Das ganze sollte wie IsDebuggerPresent() ( http://msdn.microsoft.com/en-us/library/ms680345(VS.85).aspx ) funktionieren…
Der Vorteil ist, dass man keinen Import zu IsDebuggerPresent benötigt, welcher ja sehr auffällig und einfach zu entfernen ist.
Ich weiß, dass das keine sehr effiziente Anti-Reversing Methode ist, aber es kann den Reverser sicher das Leben etwas erschweren…
Die Funktionsweise ist sehr simpel: fs:[30] zeigt auf den Process Enviroment Block ( PEB http://msdn.microsoft.com/en-us/library/aa813706(VS.85).aspx ), welcher an zweiter Stelle ein BYTE namens BeingDebugged besitzt. Dieses ist normalerweise auf 0 gesetzt, wird jedoch auf 1 gesetzt, sobald sich ein User-Mode Debugger Debugging-Privilegien für den momentanen Prozess verschaffen will.
Wie oben bereits angedeutet, wird das bei Kernel-Mode Debuggern wenig Erfolg zeigen…
Sourcecode für MASM32:
.386 .MODEL flat, stdcall option casemap :none include C:\masm32\include\windows.inc include C:\masm32\include\kernel32.inc include C:\masm32\include\user32.inc includelib C:\masm32\lib\kernel32.lib includelib C:\masm32\lib\user32.lib .DATA text_0 DB "BeingDebugged = FALSE", 0 text_1 DB "BeingDebugged = TRUE", 0 caption DB "Debugger Test", 0 .CODE ASSUME fs:flat START: MOV eax, fs:[30h] MOV ah, BYTE PTR [eax + 2] TEST ah, ah JZ NoDebugger Debugger: INVOKE MessageBox, 0, ADDR text_1, ADDR caption, MB_OK OR MB_ICONWARNING JMP ExitProg NoDebugger: INVOKE MessageBox, 0, ADDR text_0, ADDR caption, MB_OK OR MB_ICONINFORMATION ExitProg: INVOKE ExitProcess, 0 END START
Sourcecode für MinGW32:
#include <stdio.h> int _IsDebuggerPresent() { asm( "movl %fs:(0x30), %eax; \n" "movl 2(%eax), %eax; \n" "andl $0xff, %eax; \n" "leave; \n" "ret; \n" ); } int main(void) { if (_IsDebuggerPresent()) { puts("BeingDebugged = TRUE"); } else { puts("BeingDebugged = FALSE"); } getc(stdin); return 0; }
Credits: BlackBerry