BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
BOOL bOk = FALSE; // Assume that the function fails
HANDLE hProcess = NULL, hThread = NULL;
PWSTR pszLibFileRemote = NULL;
__try {
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Calculate the number of bytes needed for the DLL's pathname
int cch = 1 + lstrlenW(pszLibFile);
int cb = cch * sizeof(wchar_t);
// Allocate space in the remote process for the pathname
pszLibFileRemote = (PWSTR)
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL) __leave;
// Copy the DLL's pathname to the remote process' address space
if (!WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) pszLibFile, cb, NULL)) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, pszLibFileRemote, 0, NULL);
DWORD dwErr = GetLastError();
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
bOk = TRUE; // Everything executed successfully
}
__finally { // Now, we can clean everything up
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(bOk);
}
_FX void * SbieDll_InjectLow_getPage(HANDLE hProcess, void *remote_addr)
{
SIZE_T mySize;
ULONG_PTR tempAddr;
void * myTable = 0;
UCHAR *func;
ULONG myProtect;
short myBuffer[1024];
SIZE_T readSize;
BOOL myVM;
HANDLE myKernel32;
HANDLE myNtDll;
//HANDLE myTestDll;
func = (UCHAR *)((ULONG_PTR)m_LdrInitializeThunk);
myKernel32 = GetModuleHandleA("kernel32.dll");
myNtDll = GetModuleHandleA("ntdll.dll");
// myTestDll = 0;
/*
if(myTestDll) {
//for testing remove this code!
sprintf(buffer,"Dll Collision Test: address %p\n",myTestDll);
OutputDebugStringA(buffer);
myTable = VirtualAllocEx(hProcess,myTestDll,0x100, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
}
else {
*/
tempAddr = ((ULONG_PTR)myNtDll < (ULONG_PTR)myKernel32 ? (ULONG_PTR)myNtDll : (ULONG_PTR)myKernel32) - 0x10000;
myTable = VirtualAllocEx(hProcess, (void *)tempAddr, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
// }
/*
else {
//use hack if all else fails
//OutputDebugStringA("Unable to allocate page!\n");
max_attempts = 0;
}
*/
if (myTable) {
mySize = 0;
if (SbieDll_Has32BitJumpHorizon(myTable, func)) {
WriteProcessMemory(hProcess, myTable, &remote_addr, 8, &mySize);
/*
sprintf(buffer,"myPage = %p, kernel32 = %p, ntdll = %p\n",myTable,myKernel32,myNtDll);
OutputDebugStringA(buffer);
*/
if (mySize == 8) {
return myTable;
}
}
}
/*
sprintf(buffer,"Failed to find table for target address %p, func = %p\n",myTable,func);
OutputDebugStringA(buffer);
*/
readSize = 1;
tempAddr = (ULONG_PTR)func - 8;
ReadProcessMemory(hProcess, (void *)((ULONG_PTR)tempAddr), &myBuffer, 8, &readSize);
// if hot patch area
if (*((ULONG_PTR *)&myBuffer) == 0x9090909090909090 || *((ULONG_PTR *)&myBuffer) == 0xcccccccccccccccc) {
//OutputDebugStringA("Using hotpatch area\n");
myTable = (void *)tempAddr;
}
else { //not hot patch area: This is a hack
//patch area in .rdata section of ntdll
ReadProcessMemory(hProcess, (void *)((ULONG_PTR)tempAddr + 0x100000), myBuffer, sizeof(myBuffer), &readSize);
if (readSize != sizeof(myBuffer)) {
//OutputDebugStringA("Error reading Memory\n");
return NULL;
}
for (int i = 0; i < sizeof(myBuffer) && !myTable; i++) {
if (*((ULONG_PTR*)&myBuffer[i]) == 0x9090909090909090 ||
*((ULONG_PTR*)&myBuffer[i]) == 0xcccccccccccccccc) {
myTable = (void *)((ULONG_PTR)tempAddr + i);
/*
sprintf(buffer,"HACK: table found at %p, index %x\n",myTable, i);
OutputDebugStringA(buffer);
*/
}
}
if (!myTable) {
//OutputDebugStringA("Table not found\n");
return NULL;
}
} //end else not hotpatch area
myVM = VirtualProtectEx(hProcess, myTable, sizeof(void *), PAGE_READWRITE, &myProtect);
if (myVM) {
SIZE_T len2 = 0;
myVM = WriteProcessMemory(hProcess, myTable, &remote_addr, 8, &len2);
if (myVM && 8 == len2) {
myVM = VirtualProtectEx(hProcess, myTable, 8, myProtect, &myProtect);
if (myVM) {
return myTable;
}
}
}
return NULL;
}
ptrVTable->offset = VirtualAlloc((void *)tempAddr, VTABLE_SIZE, MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE);
myTable = VirtualAllocEx(hProcess, (void *)tempAddr, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
NTSTATUS status = NtAllocateVirtualMemory(hProcess, &remote_addr, i, ®ion_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, myTable, &remote_addr, 8, &mySize);
ReadProcessMemory(hProcess, (void *)((ULONG_PTR)tempAddr), &myBuffer, 8, &readSize);
m_LdrInitializeThunk = (ULONG_PTR) GetProcAddress(Dll_Ntdll, "LdrInitializeThunk");
VirtualFree(inject, 0, MEM_RELEASE);
VirtualProtect(RegionBase, RegionSize, PAGE_EXECUTE_READWRITE, &prot)
myVM = VirtualProtectEx(hProcess, myTable, sizeof(void *), PAGE_READWRITE, &myProtect);