DLL Injection



  • schreibt er sich LoadLibraryA eben selbst, das macht auch nich viel mehr als'n register zu laden und ne syscall instr auszuführen



  • Mein Intel kennt kein "syscall". :p



  • Ich sehe kein Problem mit Vista Port:

    int APIENTRY _tWinMain(HINSTANCE,HINSTANCE,LPTSTR,int)
    {
    	STARTUPINFOA si;
    	PROCESS_INFORMATION pi;
    
    	ZeroMemory(&si, sizeof(si));
    	si.cb = sizeof(si);
    	if (CreateProcessA(0,"cmd.exe",0,0,0,0,0,0,&si,&pi))
    	{
    		REMOTE remote;
    		HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
    
    		// find kernel32 base in cmd.exe
    		BOOL fFound  = FALSE;
    		MODULEENTRY32 me;
    		me.dwSize = sizeof(me);
    
    		int timeout = 10;
    		while (!fFound && timeout--)
    		{
    			HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pi.dwProcessId);
    			if (Module32First(hSnap, &me))
    			{
    				while (Module32Next(hSnap, &me))
    				{
    					if (!lstrcmpi(me.szModule, TEXT("kernel32.dll")))
    					{
    						fFound = TRUE;
    						break;
    					}
    				}
    			}
    			CloseHandle(hSnap);
    			if (!fFound)
    			{
    				Sleep(200);
    				hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pi.dwProcessId);
    			}
    		}
    
    		if (fFound)
    		{
    			#define offset(x) ((HMODULE)GetProcAddress(kernel32, x) - kernel32)
    			*(HMODULE*)&remote.LoadLib = me.hModule + offset("LoadLibraryA");
    			*(HMODULE*)&remote.GetProc = me.hModule + offset("GetProcAddress");
    			*(HMODULE*)&remote.FreeLib = me.hModule + offset("FreeLibrary");
    
    			lstrcpyA(remote.szUser32, "user32.dll");
    			lstrcpyA(remote.szMsgBox, "MessageBoxA");
    			lstrcpyA(remote.szMessage, "Hello from injected code!");
    
    			void *pCode = VirtualAllocEx(pi.hProcess,0,4096,MEM_COMMIT,PAGE_EXECUTE_READ);
    			void *pData = VirtualAllocEx(pi.hProcess,0,4096,MEM_COMMIT,PAGE_READWRITE);
    
    			WriteProcessMemory(pi.hProcess, pCode, MyFunction, (SIZE_T)&_tWinMain-(SIZE_T)&MyFunction, 0);
    			WriteProcessMemory(pi.hProcess, pData, &remote,sizeof(remote), 0);
    
    			HANDLE hThread = CreateRemoteThread(pi.hProcess, 0,0,(LPTHREAD_START_ROUTINE)pCode,pData,0,0);
    			WaitForSingleObject(hThread, INFINITE);
    			CloseHandle(hThread);
    
    			VirtualFreeEx(pi.hProcess,pCode,0,MEM_RELEASE);
    			VirtualFreeEx(pi.hProcess,pData,0,MEM_RELEASE);
    		}
    		CloseHandle(pi.hProcess);
    		CloseHandle(pi.hThread);
    	}
    	return 0;
    }
    


  • bei user32.dll weiß ich es nicht aber z.b. kernel32.dll oder ntdll.dll
    werden immer in jedem prozess an die selbe stelle geladen.



  • doch! schrieb:

    bei user32.dll weiß ich es nicht aber z.b. kernel32.dll oder ntdll.dll
    werden immer in jedem prozess an die selbe stelle geladen.

    Woher hast Du diese Info???
    Wenn sogar Synantec feststellt, dass "HeapAlloc" (kernel32.dll) immer an einer anderen Stelle ist, so wundert mich Deine Aussage etwas...

    Siehe:
    http://www.symantec.com/avcenter/reference/Address_Space_Layout_Randomization.pdf
    http://blogs.msdn.com/michael_howard/archive/2006/05/26/address-space-layout-randomization-in-windows-vista.aspx
    http://blogs.msdn.com/michael_howard/archive/2006/06/06/windows-vista-address-space-layout-randomization-what-is-randomized.aspx



  • Errata: ich habe mich nun registriert, und sorry für die zweite CreateToolhelp32Snapshot.

    while (!fFound && timeout--)
    {
    	HANDLE hSnap = CreateToolhelp32Snapshot()
    	if {...}
    	CloseHandle(hSnap);
    	if (!fFound) Sleep(200);
    


  • du kannst auch einfach den addressraum nach PE Dateien durchsuchen und in der IAT die adresse von LoadLibrary herausfinden



  • ich meine natürlich export directory nich iat.......



  • ich hätte noch eine Frage zu dem Link...
    ich hab den Code und die DLL genauso wie im tutorial kopiert. Die Dll ist in C:
    Die DLL wird injectet und die funktion ausgeführt. Doch nachdem sie ausgeführt wurde, crashed der zielprozess. woran liegt das? habe win xp



  • Markymark schrieb:

    crashed der zielprozess. woran liegt das?

    Du hast einen Fehler im Code.



  • nö weil ich den Code rauskopiert habe und der damals schon funktioniert hat also ist im Code kein Fehler:
    Injector:

    #include <windows.h>
    #include <cstdio>
    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()
    {
    }
    int main()
    {
       HANDLE hProc;
       LPVOID start, thread;
       DWORD funcsize, written;
       HINSTANCE hDll;
       INJECTSTRUCT is;
       DWORD id;
       hDll = LoadLibrary("KERNEL32");
       is.LoadLibrary = (fpLoadLibrary)GetProcAddress(hDll, "LoadLibraryA");
       is.GetProcAddress = (fpGetProcAddress)GetProcAddress(hDll, "GetProcAddress");
       strcpy(is.path, "C:\\DLL.dll");
       strcpy(is.func, "Funktion");
    funcsize = (DWORD)threadend-(DWORD)threadstart;
    printf("ID: ");
    scanf("%d", &id);
       hProc = OpenProcess(PROCESS_ALL_ACCESS, false, id);
       printf("Prozess Handle:       %x\n", hProc);
    start = VirtualAllocEx(hProc, 0, funcsize+sizeof(INJECTSTRUCT), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    printf("Memory:               %x\n", start);
    WriteProcessMemory(hProc, start, (LPVOID)&is, sizeof(INJECTSTRUCT), NULL);
    thread = (LPVOID)((DWORD)start+sizeof(INJECTSTRUCT));
    WriteProcessMemory(hProc, thread, (LPVOID)threadstart, funcsize, NULL);
    CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)thread, start, 0, 0);
       CloseHandle(hProc);
    	return 0;
    }
    

    DLL

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

    natürlich ist die DLL in C\\ und beides ist mit Multi Byte Compiliert.
    Wäre super wenn wer weiß woran das liegen könnte.



  • Hi,

    wie wärs mit den Prozess Debuggen in den du die DLL läds!?

    Gruß Pingu



  • Markymark schrieb:

    audacia schrieb:

    Markymark schrieb:

    crashed der zielprozess. woran liegt das?

    Du hast einen Fehler im Code.

    **
    nö weil ich den Code rauskopiert habe** und der damals schon funktioniert hat

    Genial! It compiles! Now ship it! 👍

    Markymark schrieb:

    also ist im Code kein Fehler

    Aber in den Kompilereinstellungen. Niemals vergessen: 99,95 % aller WinAPI-Funktionen sind __stdcall's.



  • Hi,

    wie wärs mit den Prozess Debuggen in den du die DLL läds!?

    Gruß Pingu



  • was muss ich den umstellen? WINAPI == __stdcall



  • Markymark schrieb:

    ...
    funcsize = (DWORD)threadend-(DWORD)threadstart;
    ..
    

    Wollt nur noch schnell anmerken daste mit diesm Konstrukt ziemlich leicht auf die Schnauze fallen kannst.
    z.B. wenn ich mit Visual C++ 2008 im Debug Modus zB. folgendes übersetzte:

    BOOL __declspec(naked) SetCursorPosA(int x, int y)
    {
       __asm
       {
          mov  edi, edi
          push ebp
          mov  ebp, esp
          jmp [DLLFunc]
       }
    }
    void blub()
    {
    	printf("hallo");
    	return;
    }
    
    int main(int argc, TCHAR** argv)
    {
    
    	unsigned char test = -1;
    
    	printf("%c",test);
    	SetCursorPosA(10,10);
    	blub();
    
    	return 0;
    }
    

    entsteht folgendes:

    /*Main function*/
    00411AA2   |.  E8 34F7FFFF       CALL FindWind.004111DB
    00411AA7   |.  83C4 08           ADD ESP,8
    00411AAA   |.  E8 36F7FFFF       CALL FindWind.004111E5
    
    ....
    
    004111D6    . /E9 D5010000       JMP FindWind.SetCursorPosA
    004111DB    $ |E9 D0010000       JMP FindWind.SetCursorPosA
    004111E0    . |E9 2F020000       JMP FindWind.printf                                                       ;  JMP to MSVCR90D.printf
    004111E5    $ |E9 D6010000       JMP FindWind.blub
    

    Gruß Pingu



  • 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


Anmelden zum Antworten