Mega Code Archive

 
Categories / Delphi / System
 

Dllinjection

{ This covers DLL injection using EliCZ's RT.DLL library. It is a 2.5kb ASM DLL that emulates NT functions for 9x. His homepage is http://elicz.cjb.net/. You will need to get his library from there and some day I hope he will be a nice guy and release the code so we can use it in open source applications. :) Now on to business... DLLs are modules that can be loaded by a process to do work on their behalf. They are not actual processes so all kinds of neat things can be hidden in them to stay off the proccess list. Also by injecting a DLL into a process you get all the privledges of that process! DLLs are loaded staticly by use of an Import Address Table or they can be loaded dynamically using the KERNEL32 function LoadLibraryA or for unicode, LoadLibraryW. The trick to injecting a DLL into another process is having it call one of the LoadLibrary functions with the path to your DLL. This can be done by first, allocating a memory region inside the foreign process by use of xVirtualAllocEx. Then, using WriteProcessMemory, to write the parameter for LoadLibrary. Finally, we use xCreateRemoteThread to call LoadLibrary inside the foreign process. So, let's get started... xVirtualAllocEx is used to allocate memory in a foreign process and returns a pointer to the newly allocated region of memory if it succeeds or 0 if it fails. If it fails you can use GetLastError to get extended error information. xVirtualAllocEx( hProcess: dword; //the process in which we want to allocate memory lpAddress: Pointer; //starting address for the memory dwSize: dword; //size of the memory region flAllocationType: dword; //type of allocation flProtect: dword //access rights ): Pointer; Description of parameters: hProcess: should be a process handle that we have opened using OpenProcess. lpAddress: we use nil to have the function choose a location for us dwSize: the amount of data you will be writing flAllocationType: MEM_COMMIT is used to reserve and commit our memory flProtect: PAGE_READWRITE is used for only reading/writing to this memory. The pointer that is returned is then used with WriteProcessMemory to copy our DLL path into this newly allocated memory. WriteProcessMemory( hProcess: dword; //process we want to write to const lpBaseAddress: Pointer; //address of memory we want to write to lpBuffer: Pointer; //pointer to data we are writing nSize: dword; //size of data to write var lpNumberOfBytesWritten: dword //used to return the actual amout written ): BOOL; Description of parameters: hProcess: the handle of the previously opened process we allocated memory in lpBaseAddress: this is where we pass the pointer to the allocated memory lpBuffer: this should be a pointer to the actual DLL name we are injecting nSize: size of memory region lpNumberOfBytesWritten: this will be filled with the actual ammount written This will either return True or False depending on whether not the data was written. If it fails you can use GetLastError to get extended error information. Now we can call xCreateRemoteThread. This function creates a new thread inside of a foreign process using the address to a function that will be called with the creation of this new thread. We use this to start a new thread inside of our target process. We give it the address of LoadLibrary and with our allocated memory containing the DLL path. xCreateRemoteThread( hProcess: dword; //process in which to create the thread lpThreadAttributes: Pointer; //security attributes of the newly created thread dwStackSize: dword; //default stack size of the thread lpStartAddress: Pointer; //base address of the function to call lpParameter: Pointer; //paramaters for the function dwCreationFlags: dword; //flags for the creation, could be used to create suspended thread var lpThreadId: dword //this will be filled with the TID for this thread ): THandle; Description of parameters: hProcess: same as the previous two lpThreadAttributes: use nil to create a regular thread dwStackSize: use 0 to use the default lpStartAddress: here we will pass the location to LoadLibrary so it will be called lpParameter: this should be the pointer to the memory containing our DLL path lpThreadId: the TID for our thread, we don't need it in this case At this point the foreign process as called LoadLibrary with our DLL path and the DLL should be attached to the process. Now all that is left to do is wait for the thread to finish and then clean up. To clean up we need to free the previously allocated memory. We do this using xVirtualFreeEx. xVirtualFreeEx( hProcess: dword; //process in which to free memory lpAddress: Pointer; //start address of the memory dwSize: dword //amount of the region to free dwFreeType: dword //type of freeing to be done ): Pointer; Description of parameters: hProcess: same as the rest lpAddress: pointer to the memory containing our DLL path dwSize: must be set to 0 dwFreeType: we use MEM_RELEASE to both release and decommit the memory Ok now we are all done. Whew! Good luck. } program Project1; uses Windows; var PID, BytesWritten, Process, Thread, ThreadId: dword; Paramaters: pointer; DLL: pchar; function xCreateRemoteThread(hProcess: dword; lpThreadAttributes: Pointer; dwStackSize: dword; lpStartAddress: Pointer; lpParameter: Pointer; dwCreationFlags: dword; lpThreadId: dword): dword; stdcall; external 'RT.dll'; function xVirtualAllocEx(hProcess: dword; lpAddress: Pointer; dwSize: dword; flAllocationType: dword; flProtect: dword): Pointer; stdcall; external 'RT.dll'; function xVirtualFreeEx(hProcess: dword; lpAddress: Pointer; dwSize: dword; dwFreeType: dword): boolean; stdcall; external 'RT.dll'; begin DLL := 'c:\Inject\Library.dll'; //full path! PID := 1784; //process id! Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID); Paramaters := xVirtualAllocEx(Process, nil, 4096, MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(Process, Paramaters, Pointer(DLL), 4096, BytesWritten); Thread := xCreateRemoteThread(Process, nil, 0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'LoadLibraryA'), Paramaters, 0, ThreadId); WaitForSingleObject(Thread, INFINITE); xVirtualFreeEx(Process, Paramaters, 0, MEM_RELEASE); CloseHandle(Thread); CloseHandle(Process); end.