The code for the IsDebuggerPresent function has never changed - it is identical in Windows 2000, Windows XP, and even the latest Vista:
So rather than calling IsDebuggerPresent we can just as easily use the code 'inline' in our own program. The advantage of this is that it will bypass any hooks/breakpoints on IsDebuggerPresent, but keep in mind it can still be defeated quite easily (you can see that IsDebuggerPresent simply returns a flag - that flag can be patched).
Code:
77E72740 64:A1 18000000 mov eax, dword ptr fs:[18] 77E72746 8B40 30 mov eax, dword ptr ds:[eax+30] 77E72749 0FB640 02 movzx eax, byte ptr ds:[eax+2] 77E7274D C3 retn
Code:
#COMPILE EXE FUNCTION PBIsDebuggerPresent() AS LONG #REGISTER NONE ! mov eax, dword ptr fs:[&h18] ! mov eax, dword ptr ds:[eax+&h30] ! movzx eax, byte ptr ds:[eax+2] ! mov FUNCTION, eax END FUNCTION FUNCTION PBMAIN() AS LONG IF PBIsDebuggerPresent = 1 THEN MSGBOX "Debugger detected" ELSE MSGBOX "No debugger detected" END IF END FUNCTION