bom galera muitas vezes precisamos debugar o nosso programa, e muitas vezes essa debugação é bem trabalhosa, as vezes necessitando localizar determinado endereço na memoria para conseguir colocar um breakpoint naquela parte que vamos analisar. Uma forma bastante simples de colocar um breakpoint sem precisar ficar lendo instruções do nosso código na memoria é pela interrupção 3 (int 3). O int 3 é um breakpoint da própria arquitetura x86, então tambem existe um código binário próprio para chamar o int 3. Temos que ficar ciente também que não é possível chamar o int 3 fora de uma debugação, vai crashar o programa. Uma forma da gente usar o int 3 é via asm inline chamando a instrução int com o valor 3
podemos colocar vários int 3 no nosso código, a cada trecho que a gente precisar
se a gente executar esse programa fora do debugador vai dar erro
por outro lado se ele for aberto em um debugador e executado la dentro vai parar exatamente no primeiro breakpoint
depois disso bastaria continuar a execução
o mesmo poderia ser feito em outro debugador tambem, não necessariamente precisaria ser o gdb
como também é possível fazer em outras linguagens ou IDEs, como exemplo o delphi
outra forma da gente usar ele, é colocando o byte equivalente ao int 3, sendo que esse byte é o codigo hexadecimal 0xcc
existe uma diferença entre usar a instrução "int 0x3" e colocar diretamente o byte 0xcc. Essa pequena diferença entre os dois são apenas no byte gerado, ja o resultado final é o mesmo ou seja um breakpoint no nosso codigo. Quando colocamos 0xcc vai ter apenas um byte para o breakpoint int 3, quando usamos a instrução "int 0x3" vai gerar dois bytes sendo um equivalente a instrução "int" (0xcd) e o outro equivalente ao valor 0x3 (0x3). Sendo assim também é possível conseguir essa mesma interrupção adicionando os bytes 0xcd e 0x03 no lugar do 0xcc
no windows existe a função DebugBreak que funciona de forma semelhante
também podemos usar a função IsDebuggerPresent no windows para saber se o programa está sendo debugado
já no linux uma função semelhante ao DebugBreak é o __buitin_trap
bom galera a interrupção 3 é utilizada muito para debugação dos programas ou ate mesmo na criação de um debugger, embora tambem seja bastante utilizada de forma maliciosa em malwares para criar hooks e anti-debuggers ^^
by kodo no kami
- Código:
#include <stdio.h>
int main(void){
printf("exemplo int3\n");
__asm__("int $0x3");
printf("by kodo no kami\n");
}
podemos colocar vários int 3 no nosso código, a cada trecho que a gente precisar
- Código:
#include <stdio.h>
int main(void){
printf("exemplo int3\n");
__asm__("int $0x3");
printf("by kodo no kami\n");
__asm__("int $0x3");
}
se a gente executar esse programa fora do debugador vai dar erro
por outro lado se ele for aberto em um debugador e executado la dentro vai parar exatamente no primeiro breakpoint
depois disso bastaria continuar a execução
o mesmo poderia ser feito em outro debugador tambem, não necessariamente precisaria ser o gdb
como também é possível fazer em outras linguagens ou IDEs, como exemplo o delphi
- Código:
procedure TForm1.Button1Click(Sender: TObject);
begin
asm
int $3
end;
end;
outra forma da gente usar ele, é colocando o byte equivalente ao int 3, sendo que esse byte é o codigo hexadecimal 0xcc
- Código:
#include <stdio.h>
int main(void){
printf("exemplo int3\n");
__asm__(".byte 0xcc");
printf("by kodo no kami\n");
__asm__(".byte 0xcc");
}
existe uma diferença entre usar a instrução "int 0x3" e colocar diretamente o byte 0xcc. Essa pequena diferença entre os dois são apenas no byte gerado, ja o resultado final é o mesmo ou seja um breakpoint no nosso codigo. Quando colocamos 0xcc vai ter apenas um byte para o breakpoint int 3, quando usamos a instrução "int 0x3" vai gerar dois bytes sendo um equivalente a instrução "int" (0xcd) e o outro equivalente ao valor 0x3 (0x3). Sendo assim também é possível conseguir essa mesma interrupção adicionando os bytes 0xcd e 0x03 no lugar do 0xcc
- Código:
#include <stdio.h>
int main(void){
printf("exemplo int3\n");
__asm__(".byte 0xcd,0x03");
printf("by kodo no kami\n");
__asm__(".byte 0xcd,0x03");
}
no windows existe a função DebugBreak que funciona de forma semelhante
- Código:
#include <stdio.h>
#include <windows.h>
int main(void){
printf("exemplo int3\n");
DebugBreak();
printf("by kodo no kami\n");
DebugBreak();
}
também podemos usar a função IsDebuggerPresent no windows para saber se o programa está sendo debugado
- Código:
#include <stdio.h>
#include <windows.h>
int main(void){
printf("exemplo int3\n");
if(IsDebuggerPresent()){
DebugBreak();
}
printf("by kodo no kami\n");
if(IsDebuggerPresent()){
DebugBreak();
}
}
já no linux uma função semelhante ao DebugBreak é o __buitin_trap
- Código:
#include <stdio.h>
#include <unistd.h>
int main(void){
printf("exemplo int3\n");
__builtin_trap();
printf("by kodo no kami\n");
__builtin_trap();
}
bom galera a interrupção 3 é utilizada muito para debugação dos programas ou ate mesmo na criação de um debugger, embora tambem seja bastante utilizada de forma maliciosa em malwares para criar hooks e anti-debuggers ^^
by kodo no kami