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ć.

Advertisements

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 );
}