Problem mit dll injection [ERLEDIGT]



  • Hallo ich versuche gerade ein Programm zu schreiben, dass beliebige dlls in beliebige Prozesse injected. Das Problem ist, dass der betreffenden Prozess abstürzt nachdem die dll ihre Aufgabe erfüllt hat. Ich nehme an das es an VirtualFreeEx liegt, aus irgendeinem Grund schlägt die Funtion bei mir fehl. Bitte um Hilfe.

    PS: In der dll wird nichts besonderes gemacht, auch mit einer "leeren" dll krieg ich das Problem mit dem Absturz.

    #include <windows.h>
    #include <cstdio>
    #include <tlhelp32.h>
    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    typedef HINSTANCE (*fpLoadLibrary)(char*);
    typedef LPVOID (*fpGetProcAddress)(HINSTANCE, char*);
    typedef void (*fpFunktion)(void);
    
    struct INJECTSTRUCT
    {
          fpLoadLibrary LoadLibrary;
          fpGetProcAddress GetProcAddress;
          char path[255];
          char func[255];
    };
    
    DWORD WINAPI threadstart(LPVOID addr)
    {
    	HINSTANCE hDll;
    	fpFunktion funktion;
    	INJECTSTRUCT * is = (INJECTSTRUCT*)addr;       
    	hDll = is->LoadLibrary(is->path);
    	funktion = (fpFunktion)is->GetProcAddress(hDll, is->func);
    	funktion();
    	return 0;
    }
    void threadend()
    {
    }
    
    //...Debug_Privileg setzen
    
    void listproc()
    {
    		HANDLE hSnap, hTemp;
    	PROCESSENTRY32 pe;
    	pe.dwSize = sizeof(PROCESSENTRY32);
    
    	//EnableDebugPrivilege();
    	hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
    	if(Process32First(hSnap, &pe))
    	{
    		do
    		{
    			hTemp = OpenProcess(PROCESS_ALL_ACCESS, 0, pe.th32ProcessID);
    			if(hTemp)
    			{
    				printf("%4d\t%s\n", pe.th32ProcessID, pe.szExeFile);
    				CloseHandle(hTemp);
    			}
    		}
    		while(Process32Next(hSnap, &pe));
    	}
    }
    
    int main()
    {
    
       HANDLE hProc;
       LPVOID start, thread;
       DWORD funcsize, written;
       HINSTANCE hDll;
       INJECTSTRUCT is;
       DWORD id;
    
       EnableDebugPrivilege();
       listproc();
    
       hDll = LoadLibrary("KERNEL32");
       is.LoadLibrary = (fpLoadLibrary)GetProcAddress(hDll, "LoadLibraryA");
       is.GetProcAddress = (fpGetProcAddress)GetProcAddress(hDll, "GetProcAddress");
       strcpy(is.path, "DLL.dll");
       strcpy(is.func, "Funktion");
    
       funcsize = (DWORD)threadend-(DWORD)threadstart;
    
       printf("Process ID: ");
       scanf("%d", &id);
    
       hProc = OpenProcess(PROCESS_ALL_ACCESS, false, id);
       if(!hProc)
    	   MessageBox ( NULL, "Unable to open process", "DLL Injector", MB_OK);
    
       printf("Prozess Handle:       %x", hProc);
    
       //start = VirtualAllocEx(hProc, 0, funcsize+sizeof(INJECTSTRUCT), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
       if(!(start = VirtualAllocEx(hProc, 0, funcsize+sizeof(INJECTSTRUCT), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE)))
    	   MessageBox ( NULL, "Failed to allocate memory", "DLL Injector", MB_OK);
    
       printf("Memory:               %x\n", start);
    
       if(!(WriteProcessMemory(hProc, start, (LPVOID)&is, sizeof(INJECTSTRUCT), NULL)))
    		MessageBox ( NULL, "WriteProcessMemory(hProc, start, (LPVOID)&is, sizeof(INJECTSTRUCT), NULL) failed", "DLL Injector", MB_OK);
    
       thread = (LPVOID)((DWORD)start+sizeof(INJECTSTRUCT));
    
      if(!(WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL)))
    		MessageBox ( NULL, "WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL) failed", "DLL Injector", MB_OK);
    
       if(!(CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)thread, start, 0, NULL)))
    	   MessageBox ( NULL, "Failed to Create remote thread", "DLL Injector", MB_OK);
    
       if(!(VirtualFreeEx(hProc,NULL,funcsize+sizeof(INJECTSTRUCT),MEM_RESERVE|MEM_COMMIT)))
    
    		MessageBox ( NULL, "Failed to release allocated memory", "DLL Injector", MB_OK);
    
        CloseHandle(hProc);
    	return 0;
    }
    

    Wie gesagt, die DLL macht sogar was sie soll, aber danach stürzt der Prozess in den injected wurde ab.

    Danke schonmal.



  • Prüf bei Gelegenheit mal, was Du mit VirtualFreeEx eigentlich freigibst. 😮



  • Here you are:

    // INJECTION
    // std::string moduleFullPath = Voller Pfad zur DLL, zB. C:\\mydll.dll
    
    LPVOID remoteMemoryHandle = VirtualAllocEx(processHandle, 0, moduleFullPath.size() * sizeof(char), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(processHandle, remoteMemoryHandle, moduleFullPath.c_str(), moduleFullPath.size() * sizeof(char), 0);
    FARPROC loadLibraryAddress = GetProcAddress(GetModuleHandle("KERNEL32"), "LoadLibraryA");
    HANDLE remoteThreadHandle = CreateRemoteThread(processHandle, 0, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(loadLibraryAddress), remoteMemoryHandle, 0, 0);
    WaitForSingleObject(remoteThreadHandle, INFINITE);
    CloseHandle(remoteThreadHandle);
    VirtualFreeEx(processHandle, remoteMemoryHandle, 0, MEM_RELEASE);
    
    // EJECTION
    // HMODULE moduleHandle = Holen mit Module32First(), Module32Next() ...
    
    FARPROC freeLibraryAddress = GetProcAddress(GetModuleHandle("KERNEL32"), "FreeLibrary");
    HANDLE remoteThreadHandle = CreateRemoteThread(processHandle, 0, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(freeLibraryAddress), reinterpret_cast<void*>(moduleHandle), 0, 0);	
    WaitForSingleObject(remoteThreadHandle, INFINITE);
    CloseHandle(remoteThreadHandle);
    

  • Mod

    Man darf in dem Startprozess natürlich nicht den Speicher freigeben in dem die Argumente und der Threadcode selbst liegen, bevor der Thread diese auch nicht mehr braucht, sprich terminiert.



  • Ja, die erste Version des Programms war recht unüberlegt, bzw hauptsächlich abkopiert aus nem Tutorial. Hier mal die neue Version:

    #include <windows.h>
    #include <cstdio>
    #include <tlhelp32.h>
    #include <iostream>
    #include <conio.h>
    #include <string.h>
    
    using namespace std;
    
    typedef HINSTANCE (*fpLoadLibrary)(char*);
    typedef LPVOID (*fpGetProcAddress)(HINSTANCE, char*);
    typedef void (*fpFunktion)(void);
    
    struct INJECTSTRUCT
    {
          fpLoadLibrary LoadLibrary;
          fpGetProcAddress GetProcAddress;
          char path[255];
          char func[255];
    };
    
    DWORD WINAPI threadstart(LPVOID addr)
    {
    	HINSTANCE hDll;
    	fpFunktion funktion;
    	INJECTSTRUCT * is = (INJECTSTRUCT*)addr;       
    	hDll = is->LoadLibrary(is->path);
    	funktion = (fpFunktion)is->GetProcAddress(hDll, is->func);
    	funktion();
    	return 0;
    }
    void threadend()
    {
    }
    
    //EnableDebugPrivilege()[...]
    
    void listproc()
    {
    	HANDLE hSnap, hTemp;
    	PROCESSENTRY32 pe;
    	pe.dwSize = sizeof(PROCESSENTRY32);
    
    	EnableDebugPrivilege();
    
    	hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
    	if(Process32First(hSnap, &pe))
    	{
    		do
    		{
    			hTemp = OpenProcess(PROCESS_ALL_ACCESS, 0, pe.th32ProcessID);
    			if(hTemp)
    			{
    				printf("%4d\t%s\n", pe.th32ProcessID, pe.szExeFile);
    				CloseHandle(hTemp);
    			}
    			if(!hTemp)
    			{
    				printf("%4d\t%s NO ACCESS\n", pe.th32ProcessID, pe.szExeFile);
    				CloseHandle(hTemp);
    			}
    		}
    		while(Process32Next(hSnap, &pe));
    	}
    }
    
    int main()
    {
    
       HANDLE hProc,hThread;
       LPVOID start, thread;
       DWORD funcsize, written;
       HINSTANCE hDll;
       INJECTSTRUCT is;
       DWORD id;
    
       listproc();
    
       hDll = LoadLibrary("KERNEL32");
    
       is.LoadLibrary = (fpLoadLibrary)GetProcAddress(hDll, "LoadLibraryA");
       is.GetProcAddress = (fpGetProcAddress)GetProcAddress(hDll, "GetProcAddress");
       strcpy(is.path, "J:\\Dokumente\\Programmierung\\C++\\DLL\\DLL\\Release\\DLL.dll");
       strcpy(is.func, "Funktion");
    
       funcsize = (DWORD)threadend-(DWORD)threadstart;
    
       printf("Process ID: ");
       scanf("%d", &id);
    
       hProc = OpenProcess(PROCESS_ALL_ACCESS, false, id);
       if(!hProc)
    	   MessageBox ( NULL, "Unable to open process", "DLL Injector", MB_OK);
    
       printf("Prozess Handle:       %x", hProc);
    
       if(!(start = VirtualAllocEx(hProc, 0, funcsize+sizeof(INJECTSTRUCT), MEM_COMMIT, PAGE_READWRITE)))
    	   MessageBox ( NULL, "Failed to allocate memory", "DLL Injector", MB_OK);
       printf("Memory:               %x\n", start);
    
       if(!(WriteProcessMemory(hProc, start, (LPVOID)&is, sizeof(INJECTSTRUCT), 0)))
    		MessageBox ( NULL, "WriteProcessMemory failed", "DLL Injector", MB_OK);
    
       thread = (LPVOID)((DWORD)start+sizeof(INJECTSTRUCT));
    
      if(!(WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL)))
    		MessageBox ( NULL, "WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL) failed", "DLL Injector", MB_OK);
    
       if(!(hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)thread, start, 0, 0)))
    	   MessageBox ( NULL, "Failed to Create remote thread", "DLL Injector", MB_OK);
    
    if((WaitForSingleObject(hThread, INFINITE)) == WAIT_OBJECT_0) //Bin mir nich sicher ob man das so machen darf, aber auch wenn ich nur WaitForSingleObject(...) schreibe ist der Fehler der Gleiche.
    {
    CloseHandle(hThread);
      if(!(VirtualFreeEx(hProc,start,0,MEM_RELEASE)))
    		MessageBox ( NULL, "Failed to release allocated memory", "DLL Injector", MB_OK);
    
    CloseHandle(hProc);
    
    	return 0;
    }
    }
    

    So finde ich ergibt das eigentlich Sinn. Meine dll enthält eine message box mit der Nachricht "Message from dll". Wenn ich nun mit meinem Programm versuche die dll in Minesweeper zu injecten passiert folgendes: Als erstes kommt die Nachricht aus der dll. Klicke ich "Ok" meldet die winmine.exe "winmine.exe hat ein Problem festgestellt und muss beendet werden". Klicke ich nun auf schließen kommt "Failed to release allocated memory". Das das memory releasen nicht klappt ist ja auch klar, da der Prozess ja schon vorher abstürzt. Das Problem muss also irgendwo zwischen CreateRemoteThread und WaitForSingleObject auftreten.

    GetLastError() nach CreateRemoteThread gibt übrigens Fehlercode 18 = ERROR_NO_MORE_FILES. Laut msdn dürfte das aber aus der Funktion listproc() stammen bzw aus der Funktion Process32Next().



  • Sorry für Doppelpost aber ich hab das alles nochmal bisschen umgestaltet. Hab nun auch ne uninject funktion was aber an meinem Problem nichts ändert, da es wie gesagt schon davor auftritt.

    #include <windows.h>
    #include <cstdio>
    #include <tlhelp32.h>
    #include <iostream>
    #include <conio.h>
    #include <string.h>
    
    using namespace std;
    
    typedef HINSTANCE (*fpLoadLibrary)(char*);
    typedef LPVOID (*fpGetProcAddress)(HINSTANCE, char*);
    typedef void (*fpFunktion)(void);
    
    BOOL Inject();
    BOOL Uninject(DWORD id,HMODULE ah_ModuleHandle);
    
    DWORD  hLibModule = 0;
    DWORD id;
    
    struct INJECTSTRUCT
    {
          fpLoadLibrary LoadLibrary;
          fpGetProcAddress GetProcAddress;
          char path[255];
          char func[255];
    };
    
    DWORD WINAPI threadstart(LPVOID addr)
    {
    	HINSTANCE hDll;
    	fpFunktion funktion;
    	INJECTSTRUCT * is = (INJECTSTRUCT*)addr;       
    	hDll = is->LoadLibrary(is->path);
    	funktion = (fpFunktion)is->GetProcAddress(hDll, is->func);
    	funktion();
    	return 0;
    }
    void threadend()
    {
    }
    
    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;
    
    }
    
    void listproc()
    {
    	HANDLE hSnap, hTemp;
    	PROCESSENTRY32 pe;
    	pe.dwSize = sizeof(PROCESSENTRY32);
    
    	EnableDebugPrivilege();
    
    	hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
    	if(Process32First(hSnap, &pe))
    	{
    		do
    		{
    			hTemp = OpenProcess(PROCESS_ALL_ACCESS, 0, pe.th32ProcessID);
    			if(hTemp)
    			{
    				printf("%4d\t%s\n", pe.th32ProcessID, pe.szExeFile);
    				CloseHandle(hTemp);
    			}
    			if(!hTemp)
    			{
    				printf("%4d\t%s NO ACCESS\n", pe.th32ProcessID, pe.szExeFile);
    				CloseHandle(hTemp);
    			}
    		}
    		while(Process32Next(hSnap, &pe));
    	}
    }
    
    int main()
    {
       listproc();
       if(!(Inject()))
       {
    	   MessageBox ( NULL, "Inject failed", "DLL Injector", MB_OK);
    	   return 0;
       }
       else
    		MessageBox ( NULL, "DLL injected", "DLL Injector", MB_OK);
    
    if(!(Uninject(id,(HMODULE)hLibModule)))
    {
    	MessageBox ( NULL, "Uninject failed", "DLL Injector", MB_OK);
    	   return 0;
       }
    else
    	MessageBox ( NULL, "DLL uninjected", "DLL Injector", MB_OK);
    
    return 1;
    }
    
    BOOL Inject()
    {
       HANDLE hProc,hThread ;
       LPVOID start, thread;
       DWORD funcsize;
       HINSTANCE hDll;
       INJECTSTRUCT is;
    
        hDll = LoadLibrary("KERNEL32");
    
       is.LoadLibrary = (fpLoadLibrary)GetProcAddress(hDll, "LoadLibraryA");
       is.GetProcAddress = (fpGetProcAddress)GetProcAddress(hDll, "GetProcAddress");
       strcpy_s(is.path, "J:\\Dokumente\\Programmierung\\C++\\DLL\\DLL\\Release\\DLL.dll");
       strcpy_s(is.func, "Funktion");
    
       funcsize = (DWORD)threadend-(DWORD)threadstart;
    
       printf("\nProcess ID: ");
       scanf_s("%d", &id);
    
       hProc = OpenProcess(PROCESS_ALL_ACCESS, false, id);
       if(!hProc)
       {
    	   MessageBox ( NULL, "Unable to open process", "DLL Injector", MB_OK);
    	   return 0;
       }
    
       if(!(start = VirtualAllocEx(hProc, 0, funcsize+sizeof(INJECTSTRUCT), MEM_COMMIT, PAGE_READWRITE)))
       {
    	   MessageBox ( NULL, "Failed to allocate memory", "DLL Injector", MB_OK);
    	   return 0;
       }
    
       if(!(WriteProcessMemory(hProc, start, (LPVOID)&is, sizeof(INJECTSTRUCT), 0)))
       {
    		MessageBox ( NULL, "WriteProcessMemory failed", "DLL Injector", MB_OK);
    		return 0;
       }
    
       thread = (LPVOID)((DWORD)start+sizeof(INJECTSTRUCT));
    
      if(!(WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL)))
      {
    		MessageBox ( NULL, "WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL) failed", "DLL Injector", MB_OK);
    			return 0;
       }
    
       if(!(hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)thread, start, 0, 0)))
       {
    	   MessageBox ( NULL, "Failed to Create remote thread", "DLL Injector", MB_OK);
    	   	return 0;
       }
    
    WaitForSingleObject(hThread, INFINITE);
    
    GetExitCodeThread( hThread, &hLibModule );
    
      if(!(VirtualFreeEx(hProc,start,0,MEM_RELEASE)))
      {
    		MessageBox ( NULL, "Failed to release allocated memory", "DLL Injector", MB_OK);
    		return 0;
       }
    
    CloseHandle(hProc);
    return 1;
    }
    
    BOOL Uninject(DWORD id,HMODULE ah_ModuleHandle)
    {
        HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
        if (hProc == NULL)
            return false;
    
        bool lb_ReturnValue = false;
    
        HMODULE hLocKernel32 = GetModuleHandleW(L"KERNEL32");
        FARPROC hLocLoadLibrary = GetProcAddress(hLocKernel32, "FreeLibrary");
    
        if(ah_ModuleHandle != NULL)
        {
            HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hLocLoadLibrary, (void*)ah_ModuleHandle, 0, NULL );
    
            if( hThread != NULL )
            {
                DWORD ldw_ReturnCode;
                WaitForSingleObject( hThread, INFINITE );
                GetExitCodeThread( hThread, &ldw_ReturnCode );
                CloseHandle( hThread );
    
                lb_ReturnValue = ldw_ReturnCode != 0;
            }
        }
    
        CloseHandle(hProc);
    
        return lb_ReturnValue; 
    }
    


  • Habs hingekriegt.

    ERLEDIGT



  • Wie hast du es denn hinbekommen? (Hab das Selbe Problem)



  • Wie schön, dass ihr mein Posting ignoriert. Naja, wenn euch der Frickelweg lieber ist als 4 und 7 Zeilen...

    🙄



  • Danke Croker, jetzt gehts. (Ich hatte deinen Post glatt übersehen)

    Ist es normal, das wenn das zu infizierende Programm in einer Schleife läuft, der eingeschläußte code nur einmal ausgeführt wird?



  • Lt. Code soll er das doch.



  • Und wie muß ich das abändern, damit das jedesmal duchlaufenwird?



  • Was meinst du?
    Sobald die DLL in den Prozess gemapped wurde, wird DllMain mit "reason == DLL_PROCESS_ATTACH" aufgerufen.



  • Hi Crocker,

    ich weiß nicht so genau ob das überhaupt gehr was ich möchte (Ich bin ja schon froh das ich es jetzt hinbekommen habe. Auch den Frickelweg habe ich zum laufen gebracht 😃 )

    Also ich möchte, dass die dll so eingeladen wird, das sie im infizierten Programm immer wieder aufgerufen wird.

    Also wenn das zu infizierende Programm so aussieht.

    int main () 
    {
    	while (true)
    	{
    		Sleep(6000);
    		cout << "alles ok";
    	}
           return 0;
    }
    

    und die DLL so:

    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
    					 )
    {
    	    return TRUE;
    }
    
    void Funktion()
    {
    	cout << "infiziert";   
    }
    

    Dann passiert bisher folgendes:
    Ausgabe: alles ok alles ok alles ok infiziert alles ok alles ok alles ok...

    Das infiziert kommt genau einmal zu dem zeitpunkt zu dem ich das injection Programm aufrufe.

    Nun hätte ich aber gerne, das Folgendes passiert:
    Ausgabe: alles ok infiziert alles ok infiziert alles ok infiziert...

    Und zwar soll dies möglichst mit nur einem Aufruf des injection Programms möglich sein.
    (Wenn das überhaupt geht)



  • DllMain wird einmalig mit DLL_PROCESS_ATTACH aufgerufen wenn die DLL injiziert wird, was du darin machst ist doch dir überlassen. Allerdings darf man darin nicht alles tun (google dazu am besten mal (Ich glaube, wenn du in der DllMain eine eigene Funktion aufrufst, darfst du in dieser aber alles tun).
    Probier halt mal rum, mach ne Schleife mit cout rein oder sonstwas.

    bool __stdcall DllMain(HMODULE, unsigned long reason, void*)
    {
    	if(reason == DLL_PROCESS_ATTACH)
    	{
    		; // Rufe zB. eine Funktion auf ...
    	}
    	else if(reason == DLL_PROCESS_DETACH)
    	{
    		;
    	}
    
        return true;
    }
    


  • Danke!


Anmelden zum Antworten