Stopping execution outside the code segment..

08Jul09

An idea I had to prevent threads from being launched outside the code segment (e.g. Via 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:

#include <strsafe.h>
#include <tlhelp32.h>
#include <windows.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 );
}

Credits to:
http://blogs.msdn.com/oldnewthing/archive/2006/02/23/537856.aspx – Enumerating threads of all active processes

http://forum.sysinternals.com/printer_friendly_posts.asp?TID=5127 – Getting the start address of a thread via accessing the TIB using NtQuerySystemInformation.

Thoughts?

Advertisements


No Responses Yet to “Stopping execution outside the code segment..”

  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: