Download: http://www.sendspace.com/file/90o7w1

This is just a very, very simple C++ wrapper for the Windows API. It supports buttons, labels, checkboxes, and textboxes. Window events are also added, and the main.cpp given file is an example of using all the features of the wrapper.

My long term goal is to implement every Windows API object and events matching such objects.

Short term, I’m going to try to add scroll bars, and some more window events.

Side-note: It’s codename is “Cro”, as a homage to the MMA fighter, Mirko “Cro Cop” Filipović.


I was browsing the MSDN library recently in the “Intrinsics” index, and found a neat little intrinsic for fetching a pointer to the IDT. Rather than checking the IDT itself, for XP/2000, the pointer itself is something that changes in the context of a debugger.

DWORD __inline SiberianTiger::CheckIDT( )
{
	DWORD returnVal;
	DWORD_PTR *IDTP = new DWORD_PTR[4];
	DWORD IDT;
	OSVERSIONINFO osvi;

	osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
	if( GetVersionEx( &osvi ) == 0 )
	{
		#ifdef AGGRESSIVE
			return( 0 );
		#else
			return( 1 );
		#endif
	}

	if( osvi.dwMajorVersion < 6 )
	{
		#ifdef __INTRIN_H_
			__sidt( IDTP );
		#else
			__asm SIDT [IDTP]
		#endif
		IDT = ( DWORD ) IDTP;

		returnVal = ( IDT & 0x373FC8 ) == IDT;
	}
	else
	{
		returnVal = 1;
	}

	return( returnVal );
}

Note: I’ll probably expand onto this function to check the actual IDT for any breakpoints that may have been set.


C++ splash

20Jul09

http://www.sendspace.com/file/uimi9i

Using nothing but the Windows API, just replace the “Splash.bmp” file with the file of your choice, then compile. Enjoy!


Update again! No bugfixes, only two new features.

Changelog:
– Check for a potential hook on IsDebuggerPresent via setting the BeingDebugged bit in the PEB to “true”.
– Remove as much header information as possible; in some debugging situations, errors may arise based off other debugger-caused issues.

Download: http://www.sendspace.com/file/u0qeu1

___

Revision 0.412b

A friend bugged me enough to make some changes to the library, as they lacked the intrinsic library, and weren’t aiming for any of the gains from it (e.g. x64 compatibility, compiler optimizations, etc).

Changelog:
– Addition of non-intrinsic support, for backward compatibility.
– Compiler customization (Defining of WIN32_LEAN_AND_MEAN, along with inclusion of the SiberianTiger.h header file only once).
– Trap flag check wasn’t working correctly; my correction was actually added incorrectly, but, I got it, thanks to the title, “Guide to assembly language programming in Linux”, for a particular page on Google Books.
– I didn’t add the fix for the passive stack-segment flag trick in the last build; added.

Download: http://www.sendspace.com/file/j1rdrc


After work on a few other libraries, I hopped back to AD, and made some much-needed revisions.

Download: http://www.sendspace.com/file/j30u3p

Changelog:
– Each anti-debug trick added into a “new” function, with a return code of 0 if an error occurs
– Class, variable, and function renaming
– Creation of an exit code table; each exit has an identifiable name identified by a preprocessor macro in the header file.
– Repairing functions that were broken (Thanks to Venus/Galco on that note; some casting gone wrong broke NtGlobalFlags check and HeapFlags check).
– Addition of “AGGRESSIVE” mode; it’s assumed if an error occurs for any API call, then a debugger was at work. Also, a call to “BlockInput” is made in the shutdown message, intended to anger the potential cracker.
- Separation of “passive” and “aggressive” checks; passive tricks attempt to silently kill a debugger, aggressive run checks for a debugger, and die dependent on the result.
- Repair of trap-flag trick and stack register trick.
- Addition of changelogs; I think they were needed ;)


Download: http://www.sendspace.com/file/5p3leh

I’ve set up a class to handle the anti-debug portion; still works on x86(-x64) Windows Vista (SP0-SP1), Windows XP (SP0-SP3), and Windows 2000 (SP0-SP4). All you have to do is initialize the class (i.e. “antiDebug antiDebug;”), and the anti-debug code will be all taken care of ;)


Thanks to Chazwazza over at GameDeception for some much needed aid in bug fixing, and some motivation to make major changes, I’ve ported major instances of inline ASM to intrinsics, now leaving only two anti-debugger tricks which require inline ASM (And will be filtered out if the option for x64 is enabled).

When you attempt to compile in MSVS, be sure to edit the “Enable C++ Exceptions” option to have the /EHa flag (“Yes with SEH exceptions”), found under the “Configuration Operations -> C/C++ -> Code Generation” menu.

#include <windows.h>
#include <intrin.h>

int DebugBit = 0;
int countExceptions = 0;
int DebugBreakBit = 0;
HANDLE vehPtr;

DWORD_PTR *GetBeingDebugged( )
{
	DWORD_PTR *BeingDebuggedBit;
	#ifdef _M_IX86
		BeingDebuggedBit = ( DWORD_PTR * ) __readfsdword( 0x30 );
	#elif _M_X64
		BeingDebuggedBit = ( DWORD_PTR * ) __readgsqword( 0x60 );
	#endif
	return( ( DWORD_PTR * ) *BeingDebuggedBit );
}

DWORD_PTR *GetNtGlobalFlags( )
{
	DWORD_PTR *NtGlobalFlags;

	#ifdef _M_IX86
		DWORD_PTR *PEB = ( DWORD_PTR * ) __readfsdword( 0x30 ) + 0x68;
		NtGlobalFlags = ( DWORD_PTR * ) *PEB + 0x68;
	#elif _M_X64
		DWORD_PTR *PEB = ( DWORD_PTR * ) __readgsqword( 0x60 ) + 0xD0;
		NtGlobalFlags = ( DWORD_PTR * ) *PEB + 0xD0;
	#endif
	return( ( DWORD_PTR * ) NtGlobalFlags );
}

DWORD_PTR *GetHeapFlags( )
{
	DWORD *HeapFlags;
	#ifdef _M_IX86
		HeapFlags = ( DWORD_PTR * ) __readfsdword( 0x30 );
		HeapFlags = ( DWORD_PTR * ) *( &HeapFlags + 0x18 );
		HeapFlags = ( DWORD_PTR * ) *( &HeapFlags + 0x10 );
	#elif _M_X64
		HeapFlags = ( DWORD_PTR * ) __readgsqword( 0x60 );
		HeapFlags = ( DWORD_PTR * ) *( &HeapFlags + 0x30 );
		HeapFlags = ( DWORD_PTR * ) *( &HeapFlags + 0x20 );
	#endif
	return ( ( DWORD_PTR * ) HeapFlags );
}

LONG WINAPI vehCheck( PEXCEPTION_POINTERS pExecpPointers )
{
	SetUnhandledExceptionFilter( ( LPTOP_LEVEL_EXCEPTION_FILTER ) pExecpPointers->ContextRecord->Eax );
	#ifdef _M_IX86
		pExecpPointers->ContextRecord->Eip += 2;
	#elif _M_X64
		pExecpPointers->ContextRecord->Rip += 4;
	#endif
	countExceptions++;
	if( DebugBreakBit == 1 )
		return( EXCEPTION_CONTINUE_EXECUTION );
	else
		return( EXCEPTION_EXECUTE_HANDLER );
}

void pseudoExit( int exitCode )
{
	BlockInput( TRUE );
	MessageBox( 0, "Please close all active debuggers, and relaunch the application.", "Fatal Error", MB_OK );
	ExitProcess( exitCode );
}

unsigned int GetDebugRegisters( )
{
    unsigned int i = 0;
    CONTEXT ctx;
    ZeroMemory( &ctx, sizeof( CONTEXT ) );
    ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; 

    if( GetThreadContext( GetCurrentThread( ), &ctx ) == 0 )
		pseudoExit( 0x789DABCF );

    if( ctx.Dr0 != 0 )
		i++;
    if( ctx.Dr1 != 0 )
		i++;
    if( ctx.Dr2 != 0 )
		i++;
    if( ctx.Dr3 != 0 )
		i++;

    return( i );
}

LONG WINAPI suefDebugCheck( struct _EXCEPTION_POINTERS *excInfo ) {
	DebugBit = 1;
	SetUnhandledExceptionFilter( ( LPTOP_LEVEL_EXCEPTION_FILTER ) excInfo->ContextRecord->Eax );
	#ifdef _M_IX86
		excInfo->ContextRecord->Eip += 2;
	#elif _M_X64
		excInfo->ContextRecord->Rip += 4;
	#endif
	return( EXCEPTION_CONTINUE_EXECUTION );
}

void __inline antiDebug( void )
{
	DWORD beginTime = GetTickCount( );
	OSVERSIONINFO osvi;
	osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
	GetVersionEx( &osvi );

	SetUnhandledExceptionFilter( suefDebugCheck );
	DWORD_PTR *forceError = 0x00000000;
	*forceError = 0;
	if( DebugBit == 0 )
		pseudoExit( 0x99673135 );

	vehPtr = AddVectoredExceptionHandler( 1, ( PVECTORED_EXCEPTION_HANDLER ) vehCheck );

	if( osvi.dwMajorVersion >= 6 )
	{
		if( GetHeapFlags( ) > ( void * ) 0x00800000 )
			pseudoExit( 0xFFFF0000 );
	}

	if( GetHeapFlags( ) > ( void * ) 0x10000000 )
		pseudoExit( 0xFFFFFFFE );

	if( GetBeingDebugged( ) == ( void * ) 0x00010000 )
		pseudoExit( 0x04012AD0 );

	if( GetNtGlobalFlags( ) == ( void * ) 0x00000070 )
		pseudoExit( 0x0F6E1A44 );

	if( IsDebuggerPresent( ) != 0 )
		pseudoExit( 0x21473361  );

	CheckRemoteDebuggerPresent( GetCurrentProcess( ), ( PBOOL ) &DebugBit );
	if( DebugBit != 0 )
		pseudoExit( 0xC0000005 );

	#ifdef _M_IX86
		__asm
		{
			PUSH SS
			POP SS
			MOV EAX, 0
			XOR EDX, EDX
		}
	#endif

	// Windows NT 5.X or earlier features
	if( osvi.dwMajorVersion < 6 )
	{
		SetLastError( 0xC0000005 );
		OutputDebugString( "%s%s" );
		if( GetLastError( ) == 0xC0000005 )
			pseudoExit( 0x5148234F );
	}
	else
	{
		try {
			OutputDebugString( "%s%s" );
		}
		catch( ... )
		{
			DebugBit = TRUE;
		}
	}

	// Verifies if SeDebugPrivilege is given
	typedef DWORD_PTR ( NTAPI *CGPID )( );
    CGPID CsrGetProcessId = ( CGPID ) GetProcAddress( GetModuleHandle( "ntdll.dll" ), "CsrGetProcessId" );
	if( OpenProcess( PROCESS_ALL_ACCESS, FALSE, CsrGetProcessId( ) ) > 0 )
		pseudoExit( 0xFF41ECAB );
	// End experimental trick

	#ifdef _M_IX86
		try {
			__asm {
				__emit 0xF3;
				__emit 0x64;
				__emit 0xF1;
			};
		}
		catch ( ... ) {
			DebugBit = FALSE;
		}
		if( DebugBit == TRUE )
			pseudoExit( 0xAAAAAAAC );
	#endif

	if( GetDebugRegisters( ) > 0 )
		pseudoExit( 0x29342180 );

	// Requires admin access
	typedef NTSTATUS ( NTAPI *NSIT )( HANDLE, UINT, PVOID, ULONG );
	NSIT NtSetInformationThread = ( NSIT )GetProcAddress( GetModuleHandle( "ntdll.dll" ), "NtSetInformationThread" );
	NtSetInformationThread( GetCurrentProcess( ), 0x11, 0, 0 );
	// End required admin access

	try {
		CloseHandle( ( HANDLE ) -1 );
	}
	catch( ... ) {
		pseudoExit( 0x00000006 );
	}

	DebugBreakBit = 1;
	__debugbreak();
	DebugBreak( );

	if( GetTickCount( ) == beginTime )
		pseudoExit( 0xD000BE05 );

	typedef NTSTATUS ( WINAPI *NQIP )( HANDLE, LONG, PVOID, ULONG, PULONG );
	NQIP NtQueryInformationProcess = ( NQIP )GetProcAddress( GetModuleHandle( "ntdll.dll" ), "NtQueryInformationProcess" );
	int returnValue = 0;
	NtQueryInformationProcess( GetCurrentProcess( ), 0x7, &returnValue, 4, 0 );
	if( returnValue != 0 )
		pseudoExit( 0xCCCCCCCC );

	NtQueryInformationProcess( GetCurrentProcess( ), 0x1E, &returnValue, 4, 0 );
	if( returnValue != 0 )
		pseudoExit( 0xEFEFEFEF );

}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
	// Begin anti-debug..
	antiDebug( );

	if( DebugBit == 1 )
		pseudoExit( 0xFFFFFFFF );
	try {
		RemoveVectoredExceptionHandler( vehPtr );
		if( countExceptions != 3 )
			pseudoExit( 0x21522153 );
	}
	catch( ... )
	{
		pseudoExit( 0x55235151 );
	}

	// End anti-debug

	MessageBox( 0, "Debugger not found.", "Success?", MB_OK );

	return( EXIT_SUCCESS );
}

In this sample, we check if a module has a base image address as 0×00000000 more than once. The default executable will be set to that number; some modules attempt to hide by erasing their information from the _MODULEINFO structure, thus, GetModuleInformation would return 0×00000000 for the base address of such a module; in the end, it works nicely for detecting some hidden modules. I also included a quick comment with an example for loading other information gathered from the structure into an allocated buffer, for making a more advanced whitelist, not based off the easily-spoofable module-name factor.

#include <windows.h>
#include <strsafe.h>
#include <Psapi.h>

#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN

#define CODEBEGIN		0x00401000
#define CODEEND			0x004019FE
#define modAllowedSize	11
const char modAllowedArray[][255] = {
	"ADVAPI32.DLL",
	"ntdll.dll",
	"RPCRT4.dll",
	"Secur32.dll",
	"PSAPI.DLL",
	"kernel32.dll",
	"USER32.dll",
	"GDI32.dll",
	"MSVCR90.dll",
	"IMM32.DLL",
	"Killing Bad Threads.exe"
};

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
  HMODULE modArray[1024];
  int modNumber;
  int modAllowedQ = 0;
  int noBaseAddress = 0;
  char modFileName[255];
  char modInfoTemp[255];
  _MODULEINFO modInfo;

  if( EnumProcessModules( GetCurrentProcess( ), modArray, sizeof( modArray ), ( LPDWORD ) &modNumber ) )
  {
    if( modNumber > sizeof( modArray ) )
      return( -1 );

	unsigned int i = 0;
    while( i < ( modNumber / sizeof( HMODULE ) ) )
    {
      int j = 0;
	  while( j < modAllowedSize )
      {
		GetModuleFileName( modArray[i], modFileName, 255 );
		char *ModuleName = strtok( modFileName, "\\" );
		char *ModuleTempName;
		char *ModuleLastName;
		do
		{
			ModuleTempName = strtok( NULL, "\\" );
			if( ModuleTempName == NULL )
				break;
			ModuleName = ModuleTempName;
		} while( ModuleName != NULL );

        if( *modAllowedArray[j] == *ModuleName )
		{
			GetModuleInformation( GetCurrentProcess( ), GetModuleHandle( modAllowedArray[j] ), &modInfo, sizeof( modInfo ) );
			//sprintf( modInfoTemp, "%08x", modInfo.lpBaseOfDll );
			// If you plan to fingerprint modules, based off entrypoint
			// base address, or size of the image base, the above will
			// load that information into a buffer
			if( modInfo.lpBaseOfDll == 0 )
				noBaseAddress++;
			modAllowedQ++;
		}
        j++;
      }
      i++;
    }
	if( noBaseAddress != 1 )
	{
      MessageBox( 0, "Unknown module loaded to memory!", "Fatal error", MB_OK );
	  exit( -1 );
	}
    if( modAllowedQ < modAllowedSize )
	{
      MessageBox( 0, "Unknown module loaded to memory!", "Fatal error", MB_OK );
	  exit( -1 );
	}
  }

  MessageBox( 0, "Nothing evil detected.", "Success?", MB_OK );

  return( EXIT_SUCCESS );
}

I found this under an old collection files; it’s a cheat for god mode in IJJI Gunz, using AT&T inline ASM.

#include <windows.h>

BYTE gdmeCheck = 0;
BYTE tglCheck = 1;

DWORD WINAPI GetKey ( LPVOID lpParam );
DWORD WINAPI GdMde ( LPVOID lpParam );
DWORD WINAPI GetZChar ( );

BOOL APIENTRY DllMain ( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved )
{
  if( fdwReason == DLL_PROCESS_ATTACH )
  {
    CreateThread( NULL, 0, GetKey, 0, 0, NULL );
    CreateThread( NULL, 0, GdMde, 0, 0, NULL );
  }

  return( TRUE );
}

DWORD WINAPI GetKey ( LPVOID lpParam ) {
  while ( 1 ) {
   if( GetAsyncKeyState( 18 ) < 0 && GetAsyncKeyState( 71 ) < 0 )
   {
      gdmeCheck ^= 1;
      tglCheck ^= 1;
   }

   Sleep( 500 );
  }
  return( 0 );
}

DWORD WINAPI GdMde ( LPVOID lpParam ) {
 while( true ) {
   if( gdmeCheck != 0 ) {
     if( DWORD ZChar = GetZChar( ) != 0 )
       __asm__ (
        "movl %0, %%eax\n\t"
        "movl $0x461C3C00, %%ecx\n\t"
        "movl %%ecx, 0x418(%%eax)\n\t"
        "movl %%ecx, 0x41C(%%eax)\n\t"
        :"=r" (ZChar)
       );
       tglCheck = 1;
   }

   if( tglCheck != 0 )
   {
     if( DWORD ZChar = GetZChar( ) != 0 )
       __asm__ (
        "movl %0, %%eax\n\t"
        "movl $100, %%ecx\n\t"
        "movl %%ecx, 0x418(%%eax)\n\t"
        "movl %%ecx, 0x41C(%%eax)\n\t"
        :"=r" (ZChar)
       );
     tglCheck ^= 1;
   }

   Sleep( 50 );
 }
 return( 0 );
}

DWORD WINAPI GetZChar ( ) {
  DWORD ZChar = 0;
  __asm__ (
    "movl $0x49A380, %%eax\n\t"
    "movl 0x50(%%eax), %%ecx\n\t"
    "movl %%ecx, %0\n\t"
    :"=r" (ZChar)
  );
  return( ZChar );
}

Other than the HP offset, nothing’s changed, so feel free to update it ;)


I know it’s a terrible idea, but, somebody had to do it!

#include <tlhelp32.h>
#include <windows.h>

#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN

#define CODEBEGIN		0x00401000
#define CODEEND			0x004019FE
#define modAllowedSize	11
const char modAllowedArray[][255] = {
	"ADVAPI32.DLL",
	"ntdll.dll",
	"RPCRT4.dll",
	"Secur32.dll",
	"PSAPI.DLL",
	"kernel32.dll",
	"USER32.dll",
	"GDI32.dll",
	"MSVCR90.dll",
	"IMM32.DLL",
	"Killing Bad Threads.exe"
};

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
  HMODULE modArray[1024];
  int modNumber;
  int modAllowedQ = 0;
  char modFileName[255];

  if( EnumProcessModules( GetCurrentProcess( ), modArray, sizeof( modArray ), ( LPDWORD ) &modNumber ) )
  {
    if( modNumber > sizeof( modArray ) )
      return( -1 );

	unsigned int i = 0;
    while( i < ( modNumber / sizeof( HMODULE ) ) )
    {
      int j = 0;
	  while( j < modAllowedSize )
      {
		GetModuleFileName( modArray[i], modFileName, 255 );
		char *ModuleName = strtok( modFileName, "\\" );
		char *ModuleTempName;
		char *ModuleLastName;
		do
		{
			ModuleTempName = strtok( NULL, "\\" );
			if( ModuleTempName == NULL )
				break;
			ModuleName = ModuleTempName;
		} while( ModuleName != NULL );

        if( *modAllowedArray[j] == *ModuleName )
			modAllowedQ++;
        j++;
      }
      i++;
    }
    if( modAllowedQ < modAllowedSize )
	{
      MessageBox( 0, "Unknown module loaded to memory!", "Fatal error", MB_OK );
	  exit( -1 );
	}
  }

  MessageBox( 0, "Nothing evil detected.", "Success?", MB_OK );

  return( EXIT_SUCCESS );
}