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);