CreateRemoteThread Problem (DLL INJECTION)!

Hi also hier ist erstmal mein CODE
Code:
/***********************************************************************************

	Author	: Tobias Stein
	Data	: 6th March '08
	Project	: WinApi hook 
	Remarks : ---

	All Rights Reserved! (c)Copyright by Tobias Stein!

***********************************************************************************/

//--- Includes ---------------------------------------------------------------------

#include "stdafx.h"
	using namespace std;

//--- Usertypes --------------------------------------------------------------------

typedef HINSTANCE (*fpLoadLibrary)( char* );
typedef FARPROC (*fpGetProcAddress)( HINSTANCE, char* );
typedef void (*fpMyFunction)( void );

typedef struct {

	fpLoadLibrary LoadLib;
	fpGetProcAddress GetProcAdd;
	char szDLLName[ 128 ];

} INJECTDATA;

//--- Globals ----------------------------------------------------------------------

//--- Prototypes -------------------------------------------------------------------

DWORD GetPID( const char *szWindowName );
DWORD WINAPI ThreadProc( LPVOID vParam );
void ThreadEnd( );
bool InjectDLL( DWORD dwProcessID );
bool EnableDebugPrivilege( );

//--- Main -------------------------------------------------------------------------

int main( int argc, char* argv[ ] ) {

	DWORD dwPID = 0;

	// ***** Set console name *****
	SetConsoleTitle( "WinApi Hook" );

	// ***** Get PID *****
	cout << "\n - Try to get process ID ..." << endl;
	dwPID = GetPID( "WinApi Victim" );
	if( dwPID == 0 ) {

		cout << "   FAILED!" << endl;
		Sleep( 1500 );
		return 0;
	}
	cout << "   Process ID: " << dwPID << endl;

	if( !( InjectDLL( dwPID ) ) ) {

		cout << "   FAILED!" << endl;
		Sleep( 1500 );
		return 0;
	}

	getchar( );
	return 0;
}

//--- Definitions ------------------------------------------------------------------

// ***** This function get the PID from window name *****
DWORD GetPID( const char *szWindowName ) {

	HWND hWindow = 0;
	DWORD dwPID = 0;

	hWindow = FindWindow( 0, szWindowName );
	if( !hWindow ) 
		return 0;

	GetWindowThreadProcessId( hWindow, &dwPID );

	return dwPID;
}

// ***** Thread procedure *****
DWORD WINAPI ThreadProc( LPVOID vParam ) {

	INJECTDATA *iData = (INJECTDATA*)vParam;

	HINSTANCE hDLL = iData->LoadLib( iData->szDLLName );
	return 0;
}
// ***** End of thread function *****
void ThreadEnd( ) { }

// ***** DLL inject routine *****
bool InjectDLL( DWORD dwProcessID ) {

	DWORD rw;

	// ***** Get all access *****
	EnableDebugPrivilege( );

	// ***** Get process handle *****
	cout << "\n - Try to recieve the process handle ..." << endl;

	HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, 0, dwProcessID );
	if( !hProcess ) {

		CloseHandle( hProcess );
		return false;
	}
	cout << "   Process handle: " << hex << hProcess << endl;

	// ***** Get Thread function size *****
	cout << "\n - Determine structur & thread function size ..." << endl;

	DWORD dwThreadSize = (DWORD)ThreadEnd - (DWORD)ThreadProc;
	cout << "   Inject structur size: " << dec << sizeof( INJECTDATA ) << " Bytes" << endl;
	cout << "   Thread function size: " << dec << dwThreadSize << " Bytes" << endl;

	// ***** Allocate some memory for INJECTDATA *****
	cout << "\n - Try to allocate memory for INJECTDATA structur (" << sizeof( INJECTDATA ) << ") ..." << endl;

	LPVOID pMemData = VirtualAllocEx( hProcess, 0, sizeof( INJECTDATA ), MEM_COMMIT, PAGE_EXECUTE_READWRITE );
	if( pMemData == 0 ) {

		CloseHandle( hProcess );
		return false;
	}
	cout << "   Allocated memory: 0x" << hex << (DWORD)pMemData << " - 0x" << ( (DWORD)pMemData + sizeof( INJECTDATA ) ) << endl;

	// ***** Create INJECTDATA struct and wirte to allocate memory *****
	INJECTDATA iData;
	memset( &iData, 0, sizeof( INJECTDATA ) );
	iData.LoadLib = (fpLoadLibrary)GetProcAddress( GetModuleHandle( "Kernel32.dll" ), "LoadLibraryA" );
	iData.GetProcAdd = (fpGetProcAddress)GetProcAddress( GetModuleHandle( "Kernel32.dll" ), "GetProcAddress" );
	strcpy( iData.szDLLName, "WinApiHookDLL.dll" );

	cout << "\n - Write IINJECTDATA struct to allocated memory (" << dec << (DWORD)pMemData << ") ..." << endl;

	rw = 0;
	if( ( WriteProcessMemory( hProcess, (LPVOID)pMemData, &iData, sizeof( INJECTDATA ), &rw ) ) == 0 ) {

		CloseHandle( hProcess );
		return false;
	}
	cout << "   Done!" << endl;

	// ***** Allocate some memory for thread func *****
	cout << "\n - Try to allocate memory for thread function (" << dwThreadSize << ") ..." << endl;

	LPVOID pMemThread = VirtualAllocEx( hProcess, 0, dwThreadSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
	if( pMemThread == 0 ) {

		CloseHandle( hProcess );
		return false;
	}
	cout << "   Allocated memory: 0x" << hex << (DWORD)pMemThread << " - 0x" << ( (DWORD)pMemThread + dwThreadSize ) << endl;

	// ***** Write thread function to allocated memory *****
	cout << "\n - Write Thread function to allocated memory (" << dec << (DWORD)pMemThread << ") ..." << endl;

	rw = 0;
	if( ( WriteProcessMemory( hProcess, (LPVOID)pMemThread, ThreadProc, dwThreadSize, &rw ) ) == 0 ) {

		CloseHandle( hProcess );
		return false;
	}
	cout << "   Done!" << endl;

	// ***** Now start remote thread *****
	cout << "\n - Start remote thread ..." << endl;
	HANDLE hThread = CreateRemoteThread( hProcess, 0, 0, (LPTHREAD_START_ROUTINE)pMemThread, pMemData, 0, 0 );
	if( !hThread ) {

		CloseHandle( hThread );
		CloseHandle( hProcess );
		return false;
	}
	
	WaitForSingleObject( hThread, INFINITE );

	int iSuccess = 0;
	GetExitCodeThread( hThread, (LPDWORD)iSuccess );
	if( iSuccess == 0 ) {

		CloseHandle( hThread );
		CloseHandle( hProcess );
		return false;
	}
	cout << "   Thread was successfully started!" << endl;

	// ***** Free allocated memory *****
	cout << " - Try to free allocated memory ..." << endl;

	if( ( VirtualFreeEx( hProcess, pMemData, 0, MEM_RELEASE ) ) == 0 ) {

		CloseHandle( hThread );
		CloseHandle( hProcess );
		return false;
	}

	if( ( VirtualFreeEx( hProcess, pMemThread, 0, MEM_RELEASE ) ) == 0 ) {

		CloseHandle( hThread );
		CloseHandle( hProcess );
		return false;
	}
	cout << "   Free memory done!" << endl;

	// ***** READY *****
	CloseHandle( hThread );
	CloseHandle( hProcess );
	return true;
}

// ***** Get more access *****
bool EnableDebugPrivilege( ) {

	TOKEN_PRIVILEGES priv;
	HANDLE hThis, hToken;
	LUID luid;

	hThis = GetCurrentProcess();

	OpenProcessToken(hThis, TOKEN_ADJUST_PRIVILEGES, &hToken);
 
	LookupPrivilegeValue(0, "seDebugPrivilege", &luid);

	priv.PrivilegeCount = 1;
	priv.Privileges[0].Luid = luid;
	priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	AdjustTokenPrivileges(hToken, false, &priv, 0, 0, 0); 
	CloseHandle(hToken);
	CloseHandle(hThis);
	return true;
}
//--- EXIT -------------------------------------------------------------------------

Ich habe eine WinApi32 Anwendung die als Opfer dienen soll, doch wenn ich diesen Code ausführe bekomme ich gleich zwei Probleme:

(1)In der Opfer.exe
"Unhandled exception at 0x00930010 in WinApiVictim.exe: 0xC0000096: Privileged instruction."

(2)In der hooker.exe
"Unhandled exception at 0x7c8229cb in WinApiHook.exe: 0xC0000005: Access violation writing location 0x00000000."

Der Debugger springt in der hooker.exe immer nach GetExitCodeThread() raus.
Ich hab echt keine Ahnung was ich da noch machen muss ist doch eigentlich fuer alles gesorgt oder?

Gruß Tobi.
 
Was du da machst, ist keine reine DLL-Injection mehr, eher Code-Injection ;)
Bei CreateRemoteThread kannst du eine Funktion mit einem Parameter aufrufen, dh es ist unnoetig ein ganzes Struct/Funktion in den Zielprozess zu schreiben. Es reicht aus, wenn du den _Pfad_ zur DLL in den Prozess schreibst und LoadLibrary (die Kernel32 hat jeder Prozess geladen) per CreateRemoteThread aufrufst, also
Code:
CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LL, (LPVOID)radr, 0, 0);
LL=Adresse von LoadLibraryA
radr=Speicheradr im Zielprozess, wo der Pfad zur DLL hingeschrieben wurde

Ein interessanter Ansatz ist auch, WriteProcessMemory komplett zu vermeiden (mitlerweile uninteressant, da moderne AVs CreateRemoteThread auch auf ihre Blacklist gesetzt haben). Das laesst sich dadurch realisieren, dass man seine DLL aehnlich einer nennt, die schon geladen wurde. Zb. kannst du dein Modul ernel32.dll nennen, kopierst dein Modul dann in system32 und rufst CreateRemoteThread wie oben auf, nur das radr in dem Fall die Adresse+1 ist, an der Kernel32.dll steht.

Fueg einfach mal nach dem GetExitCodeThread() ein GetLastError() und guck wo das Problem ist. Ansonsten kannste die paar Byte auch im Prozess stehen lassen, ob die nun dort drin stehen oder in China ein Sack Reis umfaellt...

hier mal n kleiner Loader von mir...

Code:
#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[])
{
   int pid;
   const char *dll="C:\\bla...";
   HANDLE hProc;
   FARPROC pLL;
   LPVOID radr;
   DWORD br;
   
   printf("give proc id: ");  scanf_s("%d", &pid);
   if((pLL=GetProcAddress(LoadLibrary("kernel32.dll"), "LoadLibraryA"))==NULL)
      return(0);
   if((hProc=OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid))==NULL)
      return(0);
   if((radr=VirtualAllocEx(hProc, NULL, strlen(dll), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE))==0)
       return(0);
   if(WriteProcessMemory(hProc, radr, (LPVOID)dll, strlen(dll), &br)==0)
      return(0);
   if(NULL==CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)pLL, radr, 0, 0))
      return(0);
   printf("done..\n");
   return(0);
}
Ok zugegeben recht statisch, reicht aber fuer die taegl. Arbeit, vllt hilft es dir ja irgendwie weiter.
 
Joa war vieleicht ne schlechte Überschrift, aba es soll später auch ne code injection werden, allerdings ist der code in der dll. Hm ok koennte man sicher deine variante nehmen, die hatte ich übrigens auch schon und die klappt, nur will ich es auch mit nen Thread schaffen, doch irgendwie klappt das nicht.

Es würde mich echt freuen wenn ihr mir da helfen koenntet.
 
lese ich das richtig, dass in der Opferexe (pMemData Bereich) nur das hier steht:
Code:
fpLoadLibrary LoadLib;
	fpGetProcAddress GetProcAdd;
	char szDLLName[ 128 ];
sprich: LoadLibraryA-Adresse
getProc Adresse und DLL Pfad.
76xxxxxx
76xxxxxx
meinPfad

Anschließend wird darauf CreateRemoteThread losgelassen, d.h es wird versucht, da irgendwas auszuführen (die CPU soll gefälligst alleine erkennen, dass hier ein Call zu dieser Adresse gemeint ist ;) ) ?
 
@CDW: Fast, vorher schreibt er allerdings noch eine Funktion in den Speicher (170) und ruft diese mit einem Pointer auf das Struct auf. Dies sieht allerdings irgendwie komisch aus.

Veruschs mal so:

Code:
typedef HMODULE  (WINAPI *LL)(LPCTSTR)

struct d
{
	LL pLoadLibrary;
	char path[BUF];
        DWORD adr;
};

static void loaddll(struct d *infos)
{
    infos->adr=infos->LL(infos->path);
}

Du darfst bei einer Codeinjection keine Variablen verwenden, die du nicht mit dem struct mitbringst, denn normalerweise stehen die Variablen ja auch nicht in der Codesektion, wenn du unbedingt Variablen benutzen musst,dann gib diese im Struct mit (s. Bsp oben). Und am Ende kann der Code doch auch nirgens hin returnen, von daher ist ein void angebracht.
 
@CDW: Fast, vorher schreibt er allerdings noch eine Funktion in den Speicher (170) und ruft diese mit einem Pointer auf das Struct auf. Dies sieht allerdings irgendwie komisch aus.
Ok, das ergibt dann Sinn. Ich würde dann am Anfang der ThreadFunction
sowas
Code:
_asm{
		db 0ebh,0feh
	};
schreiben (oder while(true); ) . Dann bleibt das bei der ersten Anweisung "hängen" und lässt sich bequem mit dem Debugger attachen und anschließen beobachten, was da beim laden schiefgeht.
 
öhm jo?
Könntest du mir mein den snippet in mein code schreiben damit ich weiss was da jetzt nun wo genau gefixed werden muss?

Danke
 
So funktionierts:

Code:
#include <stdio.h>
#include <windows.h>

#define BUF 512

typedef HMODULE (WINAPI *LL)(LPCTSTR);

typedef struct
{
   LL pLoadLibrary;
   char path[BUF];
}bla;

static void loaddll(bla *infos)
{  
   (DWORD)infos->pLoadLibrary(infos->path);
}
void blaa(void) { }

int main(int argc, char *argv[])
{
   int pid;
   const char *dll="test.dll";
   HANDLE hProc;
   FARPROC pLL, procll;
   LPVOID func, param;
   DWORD br;
   bla ueberg, *remote;
   
   
   printf("give proc id: ");  scanf("%d", &pid);
   if((hProc=OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid))==NULL)
      return(0);
   
   ueberg.pLoadLibrary=(LL)GetProcAddress(LoadLibrary("kernel32.dll"), "LoadLibraryA");
   strcpy(ueberg.path, dll);
   
   if((param=VirtualAllocEx(hProc, NULL, sizeof(ueberg), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE))==0)
      return(0);
   
   if((func=VirtualAllocEx(hProc, NULL, (DWORD)((DWORD)blaa-(DWORD)loaddll), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE))==0)
      return(0);
      
   if(WriteProcessMemory(hProc, func, (LPVOID)loaddll, (DWORD)((DWORD)blaa-(DWORD)loaddll), &br)==0)
      return(0);
      
   if(WriteProcessMemory(hProc, param, (LPVOID)&ueberg, sizeof(ueberg), &br)==0)
      return(0);
      
   if(NULL==CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)func, param, 0, 0))
      return(0);
      
   printf("done..\n");
   return(0);
}
 
Zurück
Oben