System Delphi

{
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.