DLL Injection



  • wenn man die funktion als static deklariert, funktioniert das
    (visual 2008 getestet)



  • Markymark schrieb:

    was muss ich den umstellen? WINAPI == __stdcall

    Falls das Fettgedruckte eine Kompilereinstellung ist, dann wäre sie genau die richtige.

    Prinzipiell mußt du nur dafür sorgen, daß der Kompiler folgende Deklarationen

    typedef HINSTANCE (*fpLoadLibrary)   (char*);
    typedef LPVOID    (*fpGetProcAddress)(HINSTANCE, char*);
    

    als __stdcall's betrachtet und entsprechenden Assemblercode generiert. Genaueres dazu hier.

    "Per Hand" geht das so:

    typedef HINSTANCE __stdcall (*fpLoadLibrary)   (char*);
    typedef LPVOID    __stdcall (*fpGetProcAddress)(HINSTANCE, char*);
    

    🙂



  • eher so

    typedef HINSTANCE (__stdcall *fpLoadLibrary)   (char*);
    typedef LPVOID    (__stdcall *fpGetProcAddress)(HINSTANCE, char*);
    


  • vielen Dank für die Hilfe besonders an helferlein.
    Mit deinem Code funktioniert es perfekt. Mich wundert es jedoch
    da ich es früher nie so gemacht habe und es geklappt hat aber wayne.
    Warum steht im Tutorial unten dass diese Methode bei nicht vielen Prozessen klappt und man darum noch das Fortgeschrittene Tut machen soll? Bei mir geht das überall



  • und warum läuft der Code nicht mit UNICODE?
    Ich habe alle char durch TCHAR ersetzt unt strcpy durch die TCHAR routine.
    Ich kann es zwar kompilieren aber der Zielprocess crashed mit unicode.



  • helferlein schrieb:

    eher so

    Hängt vom Kompiler ab. Meiner schluckt beides. "__stdcall" ist ja kein Schlüsselwort sondern nur eine Kompilererweiterung (oder auch -verwässerung). 🙂

    Markymark schrieb:

    Warum steht im Tutorial unten dass diese Methode bei nicht vielen Prozessen klappt ...

    Hab das Tutorial zwar nicht gelesen aber das liegt nicht an der Methode sondern an WinXP sein Rechtemanagement.
    Jemand der als "User" eingeloggt ist, hat z.B. nur Zugriff auf alle Prozesse, die er selbst gestartet hat usw.

    Markymark schrieb:

    und warum läuft der Code nicht mit UNICODE?

    Weil du die "A(nsi)"-Version von LoadLibrary benutzt. Probier das mal mit LoadLibraryW.



  • geht leider auch nicht aber dann muss ich wohl mit Ansi arbeiten.
    Warum bekomme ich bei der DLL einen Linker Error, dass sie nicht ansi zeichen benutzt oder so und deshalb möglicherweiße nur auf meinem PC verwendet werden kann?

    #include <windows.h>
    
    extern "C" void __declspec(dllexport) Funktion()
    {
        Beep(1000, 1000);
    }
    
    BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
    {
       return TRUE;
    }
    

    Habs mit Multi und Unicode probiert.
    Und noch was: wie bekomme ich die Rückgabewerte der Funktion aus der Dll, bzw wie kann ich ihr Parameter aus dem Main programm übergeben?



  • Markymark schrieb:

    geht leider auch nicht aber dann muss ich wohl mit Ansi arbeiten.

    alle chars umgestellt? auch das kopieren mit strcpy?

    prinzipiel sollte das auch mit unicode gehen.

    Markymark schrieb:

    Warum bekomme ich bei der DLL einen Linker Error, dass sie nicht ansi zeichen benutzt oder so und deshalb möglicherweiße nur auf meinem PC verwendet werden kann?

    welchen fehler? poste den bitte ich kann leider nicht so gut hellsehen 😃

    Markymark schrieb:

    Und noch was: wie bekomme ich die Rückgabewerte der Funktion aus der Dll, bzw wie kann ich ihr Parameter aus dem Main programm übergeben?

    du musst einen weiteren speicherbereich in dem zielprozess VirtualAllociren,
    die parameter reinschreiben und die addresse des bereiches an die funktion
    übergeben. allerdings kannst du nicht auf daten des eigenen prozesses über
    zeiger zuggreifen also alles was du brauchst kopieren.

    die addresse kannst du einfach als parameter übergeben, also der deklaration
    in der DLL und in der main einfach ein parameter, z.b. void *, hinzufügen.

    dieser wert wiederrum wird auch in der INJECTSTRUCT gespeichert.



  • Markymark schrieb:

    Und noch was: wie bekomme ich die Rückgabewerte [...]

    Ganz einfach - GetExitCodeThread.

    DWORD __stdcall RemoteThreadProc(MYDATA *data)
    {
    	return 12345; // oder ExitThread(12345);
    }
    
    void inject()
    {
    	HANDLE hThread = CreateRemoteThread();
    
    	DWORD dwExitCode;
    	GetExitCodeThread(hThread, &dwExitCode);
    	// dwExitCode = STILL_ACTIVE, also warte noch
    	WaitForSingleObject(hThread, INFINITE);
    	GetExitCodeThread(hThread, &dwExitCode);
    	// dwExitCode ist 12345
    }
    

    Du kannst auch eine variable in MYDATA setzen um thread status (und mehr) mitteilen:

    DWORD __stdcall RemoteThreadProc(MYDATA *data)
    {
    	data->return_value = 12345;
    	return 0;
    }
    
    void inject()
    {
    	MYDATA data;
    	void *pData = VirtualAllocEx(hProcess, 0, sizeof(MYDATA), MEM_COMMIT, PAGE_READ_WRITE);
    	WriteProcessMemory(hProcess, pData, &data, sizeof(data), &cch);
    
    	HANDLE hThread = CreateRemoteThread(..., pCode, pData, ...);
    	WaitForSingleObject(hThread, INFINITE);
    	ReadProcessMemory(hProcess, pData, &data, sizeof(data), &cch);
    	// data.return_value ist 12345
    }
    


  • ich glaube es war umsonst, kann man in DLLs keine Dialoge verwenden? Denn ich wollte mein ganzes Programm in diese DLL auslagern.

    #include <windows.h>
    #include "resource.h"
    
    BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
    
    extern "C" void __declspec(dllexport) Funktion()
    {
        DialogBox(GetModuleHandle(0), MAKEINTRESOURCE(IDD_DIALOG1), 0, MainDlg);
    	MessageBox(0, "lol", "lol", 0); // geht
    }
    
    BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
    {
       return TRUE;
    }
    
    BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch(message)
    	{
    	case WM_INITDIALOG:
    		Beep(2000, 4000);
    		 return TRUE;
    
    	case WM_COMMAND:
    		 switch(LOWORD(wParam))
    		 {
    	     case IDCANCEL:
      			  EndDialog(hDlg, 0);
    			  return TRUE;
    
    		 }
    	}
    
    	return FALSE;
    }
    

    leider wird kein Dialog erzeugt oO er ist auf sichtbar gestellt usw.
    aber warum sehe ich diesen nicht?



  • Leider GetModuleHandle(0) liefert EXE BASE und nicht DLL BASE. Du brauchst die hInst von DllMain in eine globale g_hinstance Variabe speichern, und dann...

    DialogBox(g_hinstance,
    

    Aber manchmal klappt das nicht, dann must du DialogBoxIndirect benutzen (mithilfe Find/Load/LockResource).



  • natüllich klappt das, wieso soll das nich klappen lolzen



  • dankeschön, dass klappt. Und noch was anderes:
    kann ich wirklich mein ganzes Programm mit vielen Dialogen funktionen Threads usw von der DLL in den Prozess laden oder gibt es da eine begrenzung?



  • Markymark schrieb:

    gibt es da eine begrenzung?

    quatsch wieso sollte es



  • helferlein schrieb:

    welchen fehler? poste den bitte ich kann leider nicht so gut hellsehen 😃

    DLL enthält Nicht-ASCII-Zeichen. Die DLL kann möglicherweise auf einem Computer mit einer anderen ANSI-Codepage als "1252" nicht geladen werden.

    #include <windows.h>
    
    HINSTANCE hInstDLL;
    
    extern "C" void __declspec(dllexport) Funktion()
    {
        Beep(1000, 1000);
    }
    
    BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
    {
       hInstDLL = hInst;
       return TRUE;
    }
    


  • sorry aber der dll-code enthällt keine nicht ansi zeichen

    wenn du den dateinamen meinst, dann kann das probleme geben.

    wenn das unicode zeichen, was sich anscheinend gut in den 14 zeilen versteckt
    hällt, nichts mit dateinamen, funktionsnamen oder textausgabe funktionen zu tun
    hat, kannst du sowiele davon haben wie due willst. ist ja nur eine 2-Byte speichereinheit,
    die sollte der computer wohl verkraften.

    eine begrenzung in der dll sehe ich vllt ab 4GB sonst nirgentwo.

    das teil sollte ohne probleme kompilieren, vorrausgesetzt das ist der ganze code



  • wenn ich __declspec(dllexport) wegmache dann kommt der Warning nicht mehr aber ich brauche das ja



  • also ich muss einen HANDLE und einen CHAR Array übergeben.
    Ich habs mal so versucht:

    // alte
    struct INJECTSTRUCT
    {
          fpLoadLibrary LoadLibrary;
          fpGetProcAddress GetProcAddress;
          TCHAR path[255];
          TCHAR func[255];
    };
    // neue struct mit params
    struct params
    {
    	HANDLE Proc;
    	TCHAR NewAppName[200];
    };
    ----
    
    params p1; 
    p1. = // mit werten gefüllt
    p1. = // mit werten gefüllt
    ------
    
    				  funcsize = (DWORD)threadend-(DWORD)threadstart;
    				  start = VirtualAllocEx(hackProcess, 0, funcsize+sizeof(INJECTSTRUCT), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    				  WriteProcessMemory(hackProcess, start, (LPVOID)&is, sizeof(INJECTSTRUCT), NULL);
    				  thread = (LPVOID)((DWORD)start+sizeof(INJECTSTRUCT));
    				  WriteProcessMemory(hackProcess, thread, (LPVOID)threadstart, funcsize, NULL);
    				 // das hier ist neu VirtualAllocEx(hackProcess, 0, sizeof(params), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    				  // das hier ist neu WriteProcessMemory(hackProcess, 0, (LPVOID)&p1, sizeof(params), NULL);
    				  CreateRemoteThread(hackProcess, 0, 0, (LPTHREAD_START_ROUTINE)thread, start, 0, 0);
    

    Ich habe es versucht, aber ich glaube kaum, dass es richtig ist.



  • "(LPVOID)&p1" ist im "hackProcess" ungültig bzw. ist es nicht das, was es im eigenen Prozess ist. Schreib die "params" mit in die "INJECTSTRUCT".



  • ok, jetzt sieht meine INJECTSTRUCT so aus.
    und wie erhalte ich jetzt die 2 Parameter in der DLL?
    die struct auch in die DLL tun und eine variable davon
    bei readprocessmemory angeben? wie muss ich readprocessmemory ausfüllen damit es klappt weil das Proc handle für OpenProcess will ich ja übergeben OO

    struct INJECTSTRUCT
    {
          fpLoadLibrary LoadLibrary;
          fpGetProcAddress GetProcAddress;
          TCHAR path[255];
          TCHAR func[255];
    	  HANDLE Proc;
    	  TCHAR newAppName[200];
    };
    

Anmelden zum Antworten