Listing 2: isdbgex.cpp Implementation of IsDebuggerPresentEx()
// IsDbgEx.cpp // Windows platform independent implementation of // IsDebuggerPresent. /* disable unnecessary level-4 warnings */ #pragma warning(disable : 4201) //nameless struct/union #pragma warning(disable : 4214) //bit field types other than int #pragma warning(disable : 4514) //unreferenced inline function /* include files */ #define WIN32_LEAN_AND_MEAN #include <windows.h> #include "IsDbgEx.h" /* required link libraries */ #pragma comment(lib, "kernel32") /* private type definitions */ typedef BOOL (WINAPI * ISDEBUGGERPRESENTPROC)(VOID); /* private function prototypes */ BOOL IsDebuggerPresent95(VOID); //------------------------------------------------------------------ //IsDebuggerPresentEx() //------------------------------------------------------------------ BOOL IsDebuggerPresentEx(VOID) { /* CONSTANTS */ static const ISDEBUGGERPRESENTPROC fnIsDebuggerPresent = (ISDEBUGGERPRESENTPROC)GetProcAddress( GetModuleHandle(TEXT("KERNEL32")), TEXT("IsDebuggerPresent")); /* TEMPORARY VARIABLES */ BOOL fDebuggerPresent = FALSE; /* use documented API if available */ if (fnIsDebuggerPresent != NULL) { fDebuggerPresent = fnIsDebuggerPresent(); } /* otherwise use undocumented Win95 technique */ else { fDebuggerPresent = IsDebuggerPresent95(); } /* done */ return fDebuggerPresent; } //------------------------------------------------------------------ //IsDebuggerPresent95() // Returns TRUE if process is being debugged, FALSE otherwise. // Note that this should only be used under Windows 95. // Windows NT and Windows 98 should use the documented // IsDebuggerPresent() API. // See chapter 3 of 'Windows 95 System Programming Secrets' by // Matt Pietrek for details on the obfuscator and the structure // of the process database. //------------------------------------------------------------------ BOOL IsDebuggerPresent95(VOID) { #ifdef _M_IX86 /* CONSTANTS */ static const DWORD FLAG_DEBUGGERPRESENT = 0x00000001; static const UINT cbProcessDatabase = 190; static const UINT dwOffsetFlags = 8; /* TEMPORARY VARIABLES */ const DWORD dwThreadId = GetCurrentThreadId(); const DWORD dwProcessId = GetCurrentProcessId(); LPVOID pProcessDatabase = NULL; DWORD obfuscator = 0; DWORD dwFlags = 0; BOOL fIsDebuggerPresent = FALSE; /* retrieve the obfuscator */ __asm { mov ax, fs mov es, ax mov eax, 18h mov eax, es:[eax] sub eax, 10h xor eax, [dwThreadId] mov [obfuscator], eax } /* locate the process database and validate */ pProcessDatabase = (VOID *)(dwProcessId ^ obfuscator); if (!IsBadReadPtr(pProcessDatabase, cbProcessDatabase)) { /* get process flags and determine if debugger present */ dwFlags = ((DWORD *)pProcessDatabase)[dwOffsetFlags]; fIsDebuggerPresent = dwFlags & FLAG_DEBUGGERPRESENT; } /* done */ return fIsDebuggerPresent; #else //!_M_IX86 SetLastError(ERROR_NOT_IMPLEMENTED); return FALSE; #endif //!_M_IX86 } /* End of file */