An idea I had that would inevitably kill current methods of DLL injection would be to kill all threads found to have a start address outside the code segment.
To battle against such an idea, you would have to either:
a) Spoof the TIB.
b) Launch a thread from within the code segment, which would involve modification of the code segment (Wouldn't work if checks on the code segment were done during runtime).
A very poorly formatted program I've been working on that makes use of the PEB's BeingDebugged bit and an anti-debug technique involving a software interrupt with Microsoft's proprietary __try/__except extensions:
Credits to:Code:#include <windows.h> #include <strsafe.h> #include <tlhelp32.h> #define WIN32_LEAN_AND_MEAN #define VC_EXTRALEAN #define CODEBEGIN 0x00401000 #define CODEEND 0x00401A5E char BeingDebugged( ) { char BeingDebuggedBit; __asm { MOV EAX,DWORD PTR FS:[0x30] XOR EAX, 0x2 SUB EBX, EBX XOR BL, [EAX] MOV BeingDebuggedBit, BL }; return( BeingDebuggedBit ); } DWORD WINAPI GetThreadStartAddress( HANDLE hThread ) { NTSTATUS ntStatus; HANDLE hDupHandle; DWORD dwStartAddress; typedef NTSTATUS ( WINAPI *NQIT )( HANDLE, LONG, PVOID, ULONG, PULONG ); NQIT NtQueryInformationThread = ( NQIT )GetProcAddress( GetModuleHandle( "ntdll.dll" ), "NtQueryInformationThread" ); HANDLE hCurrentProcess = GetCurrentProcess( ); if( !DuplicateHandle( hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0 ) ) { return( ERROR_ACCESS_DENIED ); } ntStatus = NtQueryInformationThread( hDupHandle, 9, &dwStartAddress, sizeof( DWORD ), NULL ); CloseHandle( hDupHandle ); return( dwStartAddress ); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { bool noDebugger = FALSE; __try { __asm INT 0x2D } __except( true ) { noDebugger = TRUE; } if( noDebugger == FALSE ) return( EXIT_FAILURE ); if( ( int ) BeingDebugged( ) == TRUE ) return( EXIT_FAILURE ); HANDLE h = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); if( h != INVALID_HANDLE_VALUE ) { THREADENTRY32 te; te.dwSize = sizeof(te); if( Thread32First( h, &te ) ) { do { if ( te.dwSize >= FIELD_OFFSET(THREADENTRY*** th32OwnerProcessID) + sizeof(te.th32OwnerProcessID) && GetCurrentProcessId( ) == te.th32OwnerProcessID ) { DWORD dwStartAddress; HANDLE lclThread = OpenThread( THREAD_GET_CONTEXT, FALSE, te.th32ThreadID ); dwStartAddress = GetThreadStartAddress( lclThread ); if( dwStartAddress < CODEBEGIN || dwStartAddress > CODEEND ) TerminateThread( lclThread, EXIT_SUCCESS ); CloseHandle( lclThread ); } te.dwSize = sizeof( te ); } while( Thread32Next( h, &te ) ); } } CloseHandle( h ); MessageBox( 0, "Debugger not found.", "Success?", MB_OK ); return( EXIT_SUCCESS ); }
http://blogs.msdn.com/oldnewthing/ar...23/537856.aspx - Enumerating threads of all active processes
http://forum.sysinternals.com/printe...s.asp?TID=5127 - Getting the start address of a thread via accessing the TIB using NtQuerySystemInformation.
Thoughts?



Reply With Quote


