Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/external/source/byakugan/detours/creatwth.cpp
Views: 11779
//////////////////////////////////////////////////////////////////////////////1//2// Create a process with a DLL (creatwth.cpp of detours.lib)3//4// Microsoft Research Detours Package, Version 2.1.5//6// Copyright (c) Microsoft Corporation. All rights reserved.7//89#include <windows.h>10#include <stddef.h>11#if (_MSC_VER < 1299)12typedef DWORD DWORD_PTR;13#endif14#if (_MSC_VER < 1310)15#else16#include <strsafe.h>17#endif1819//#define DETOUR_DEBUG 120#define DETOURS_INTERNAL2122#include "detours.h"2324#define IMPORT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]25#define BOUND_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT]26#define CLR_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]27#define IAT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT]2829//////////////////////////////////////////////////////////////////////////////30//31#ifndef _STRSAFE_H_INCLUDED_32static inline HRESULT StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch)33{34HRESULT hr = S_OK;35size_t cchMaxPrev = cchMax;3637if (cchMax > 2147483647)38{39return ERROR_INVALID_PARAMETER;40}4142while (cchMax && (*psz != '\0'))43{44psz++;45cchMax--;46}4748if (cchMax == 0)49{50// the string is longer than cchMax51hr = ERROR_INVALID_PARAMETER;52}5354if (SUCCEEDED(hr) && pcch)55{56*pcch = cchMaxPrev - cchMax;57}5859return hr;60}616263static inline HRESULT StringCchCopyA(char* pszDest, size_t cchDest, const char* pszSrc)64{65HRESULT hr = S_OK;6667if (cchDest == 0)68{69// can not null terminate a zero-byte dest buffer70hr = ERROR_INVALID_PARAMETER;71}72else73{74while (cchDest && (*pszSrc != '\0'))75{76*pszDest++ = *pszSrc++;77cchDest--;78}7980if (cchDest == 0)81{82// we are going to truncate pszDest83pszDest--;84hr = ERROR_INVALID_PARAMETER;85}8687*pszDest= '\0';88}8990return hr;91}9293static inline HRESULT StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc)94{95HRESULT hr;96size_t cchDestCurrent;9798if (cchDest > 2147483647)99{100return ERROR_INVALID_PARAMETER;101}102103hr = StringCchLengthA(pszDest, cchDest, &cchDestCurrent);104105if (SUCCEEDED(hr))106{107hr = StringCchCopyA(pszDest + cchDestCurrent,108cchDest - cchDestCurrent,109pszSrc);110}111112return hr;113}114115#endif116117//////////////////////////////////////////////////////////////////////////////118//119static WORD detour_sum_minus(WORD wSum, WORD wMinus)120{121wSum = (WORD)(wSum - ((wSum < wMinus) ? 1 : 0));122wSum = (WORD)(wSum - wMinus);123return wSum;124}125126static WORD detour_sum_done(DWORD PartialSum)127{128// Fold final carry into a single word result and return the resultant value.129return (WORD)(((PartialSum >> 16) + PartialSum) & 0xffff);130}131132static WORD detour_sum_data(DWORD dwSum, PBYTE pbData, DWORD cbData)133{134while (cbData > 0) {135dwSum += *((PWORD&)pbData)++;136dwSum = (dwSum >> 16) + (dwSum & 0xffff);137cbData -= sizeof(WORD);138}139return detour_sum_done(dwSum);140}141142static WORD detour_sum_final(WORD wSum, PIMAGE_NT_HEADERS pinh)143{144DETOUR_TRACE((".... : %08x (value: %08x)\n", wSum, pinh->OptionalHeader.CheckSum));145146// Subtract the two checksum words in the optional header from the computed.147wSum = detour_sum_minus(wSum, ((PWORD)(&pinh->OptionalHeader.CheckSum))[0]);148wSum = detour_sum_minus(wSum, ((PWORD)(&pinh->OptionalHeader.CheckSum))[1]);149150return wSum;151}152153static WORD ChkSumRange(WORD wSum, HANDLE hProcess, PBYTE pbBeg, PBYTE pbEnd)154{155BYTE rbPage[4096];156157while (pbBeg < pbEnd) {158if (!ReadProcessMemory(hProcess, pbBeg, rbPage, sizeof(rbPage), NULL)) {159DETOUR_TRACE(("ReadProcessMemory(idh) failed: %d\n", GetLastError()));160break;161}162wSum = detour_sum_data(wSum, rbPage, sizeof(rbPage));163pbBeg += sizeof(rbPage);164}165return wSum;166}167168static WORD ComputeChkSum(HANDLE hProcess, PBYTE pbModule, PIMAGE_NT_HEADERS pinh)169{170// See LdrVerifyMappedImageMatchesChecksum.171172MEMORY_BASIC_INFORMATION mbi;173ZeroMemory(&mbi, sizeof(mbi));174WORD wSum = 0;175176for (PBYTE pbLast = pbModule;;177pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {178179if (VirtualQueryEx(hProcess, (PVOID)pbLast, &mbi, sizeof(mbi)) <= 0) {180if (GetLastError() == ERROR_INVALID_PARAMETER) {181break;182}183DETOUR_TRACE(("VirtualQueryEx(%08x) failed: %d\n",184pbLast, GetLastError()));185break;186}187188if (mbi.AllocationBase != pbModule) {189break;190}191192wSum = ChkSumRange(wSum,193hProcess,194(PBYTE)mbi.BaseAddress,195(PBYTE)mbi.BaseAddress + mbi.RegionSize);196197DETOUR_TRACE(("[%8p..%8p] : %04x\n",198(PBYTE)mbi.BaseAddress,199(PBYTE)mbi.BaseAddress + mbi.RegionSize,200wSum));201}202203return detour_sum_final(wSum, pinh);204}205206//////////////////////////////////////////////////////////////////////////////207//208// Find a region of memory in which we can create a replacement import table.209//210static PBYTE FindAndAllocateNearBase(HANDLE hProcess, PBYTE pbBase, DWORD cbAlloc)211{212MEMORY_BASIC_INFORMATION mbi;213ZeroMemory(&mbi, sizeof(mbi));214215for (PBYTE pbLast = pbBase;;216pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {217218if (VirtualQueryEx(hProcess, (PVOID)pbLast, &mbi, sizeof(mbi)) <= 0) {219if (GetLastError() == ERROR_INVALID_PARAMETER) {220break;221}222DETOUR_TRACE(("VirtualQueryEx(%08x) failed: %d\n",223pbLast, GetLastError()));224break;225}226227// Skip uncommitted regions and guard pages.228//229if ((mbi.State != MEM_FREE)) {230continue;231}232233PBYTE pbAddress = (PBYTE)(((DWORD_PTR)mbi.BaseAddress + 0xffff) & ~(DWORD_PTR)0xffff);234235DETOUR_TRACE(("Free region %p..%p\n",236mbi.BaseAddress,237(PBYTE)mbi.BaseAddress + mbi.RegionSize));238239for (; pbAddress < (PBYTE)mbi.BaseAddress + mbi.RegionSize; pbAddress += 0x10000) {240PBYTE pbAlloc = (PBYTE)VirtualAllocEx(hProcess, pbAddress, cbAlloc,241MEM_RESERVE, PAGE_READWRITE);242if (pbAlloc == NULL) {243DETOUR_TRACE(("VirtualAllocEx(%p) failed: %d\n", pbAddress, GetLastError()));244continue;245}246pbAlloc = (PBYTE)VirtualAllocEx(hProcess, pbAddress, cbAlloc,247MEM_COMMIT, PAGE_READWRITE);248if (pbAlloc == NULL) {249DETOUR_TRACE(("VirtualAllocEx(%p) failed: %d\n", pbAddress, GetLastError()));250continue;251}252DETOUR_TRACE(("[%p..%p] Allocated for import table.\n",253pbAlloc, pbAlloc + cbAlloc));254return pbAlloc;255}256}257return NULL;258}259260static inline DWORD PadToDword(DWORD dw)261{262return (dw + 3) & ~3u;263}264265static inline DWORD PadToDwordPtr(DWORD dw)266{267return (dw + 7) & ~7u;268}269270static BOOL IsExe(HANDLE hProcess, PBYTE pbModule)271{272IMAGE_DOS_HEADER idh;273ZeroMemory(&idh, sizeof(idh));274275if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {276DETOUR_TRACE(("ReadProcessMemory(idh) failed: %d\n", GetLastError()));277return FALSE;278}279280if (idh.e_magic != IMAGE_DOS_SIGNATURE) {281// DETOUR_TRACE((" No IMAGE_DOS_SIGNATURE\n"));282return FALSE;283}284285IMAGE_NT_HEADERS inh;286ZeroMemory(&inh, sizeof(inh));287288if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) {289DETOUR_TRACE(("ReadProcessMemory(inh) failed: %d\n", GetLastError()));290return FALSE;291}292293if (inh.Signature != IMAGE_NT_SIGNATURE) {294DETOUR_TRACE((" No IMAGE_NT_SIGNATURE\n"));295return FALSE;296}297298if (inh.FileHeader.Characteristics & IMAGE_FILE_DLL) {299DETOUR_TRACE((" Characteristics: %08x\n", inh.FileHeader.Characteristics));300return FALSE;301}302303return TRUE;304}305306PVOID FindExe(HANDLE hProcess)307{308MEMORY_BASIC_INFORMATION mbi;309ZeroMemory(&mbi, sizeof(mbi));310311// Find the next memory region that contains a mapped PE image.312//313for (PBYTE pbLast = (PBYTE)0x10000;;314pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {315316if (VirtualQueryEx(hProcess, (PVOID)pbLast, &mbi, sizeof(mbi)) <= 0) {317if (GetLastError() == ERROR_INVALID_PARAMETER) {318break;319}320DETOUR_TRACE(("VirtualQueryEx(%08x) failed: %d\n",321pbLast, GetLastError()));322break;323}324325// Skip uncommitted regions and guard pages.326//327if ((mbi.State != MEM_COMMIT) || (mbi.Protect & PAGE_GUARD)) {328continue;329}330331DETOUR_TRACE(("%8p..%8p [%8p]\n",332mbi.BaseAddress,333(PBYTE)mbi.BaseAddress + mbi.RegionSize,334mbi.AllocationBase));335336if (IsExe(hProcess, pbLast)) {337#if DETOUR_DEBUG338for (PBYTE pbNext = (PBYTE)mbi.BaseAddress + mbi.RegionSize;;339pbNext = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {340341if (VirtualQueryEx(hProcess, (PVOID)pbNext, &mbi, sizeof(mbi)) <= 0) {342if (GetLastError() == ERROR_INVALID_PARAMETER) {343break;344}345DETOUR_TRACE(("VirtualQueryEx(%08x) failed: %d\n",346pbNext, GetLastError()));347break;348}349350// Skip uncommitted regions and guard pages.351//352if ((mbi.State != MEM_COMMIT) || (mbi.Protect & PAGE_GUARD)) {353continue;354}355DETOUR_TRACE(("%8p..%8p [%8p]\n",356mbi.BaseAddress,357(PBYTE)mbi.BaseAddress + mbi.RegionSize,358mbi.AllocationBase));359360IsExe(hProcess, pbNext);361}362#endif363return pbLast;364}365}366return NULL;367}368369static BOOL UpdateImports(HANDLE hProcess, LPCSTR *plpDlls, DWORD nDlls)370{371BOOL fSucceeded = FALSE;372BYTE * pbNew = NULL;373DETOUR_EXE_RESTORE der;374DWORD i;375376ZeroMemory(&der, sizeof(der));377der.cb = sizeof(der);378379PBYTE pbModule = (PBYTE)FindExe(hProcess);380381IMAGE_DOS_HEADER idh;382ZeroMemory(&idh, sizeof(idh));383384if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {385DETOUR_TRACE(("ReadProcessMemory(idh) failed: %d\n", GetLastError()));386387finish:388if (pbNew != NULL) {389delete[] pbNew;390pbNew = NULL;391}392return fSucceeded;393}394CopyMemory(&der.idh, &idh, sizeof(idh));395der.pidh = (PIMAGE_DOS_HEADER)pbModule;396397if (idh.e_magic != IMAGE_DOS_SIGNATURE) {398goto finish;399}400401IMAGE_NT_HEADERS inh;402ZeroMemory(&inh, sizeof(inh));403404if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) {405DETOUR_TRACE(("ReadProcessMemory(inh) failed: %d\n", GetLastError()));406goto finish;407}408CopyMemory(&der.inh, &inh, sizeof(inh));409der.pinh = (PIMAGE_NT_HEADERS)(pbModule + idh.e_lfanew);410411if (inh.Signature != IMAGE_NT_SIGNATURE) {412goto finish;413}414415if (inh.IMPORT_DIRECTORY.VirtualAddress == 0) {416DETOUR_TRACE(("No IMAGE_DIRECTORY_ENTRY_IMPORT\n"));417goto finish;418}419420// Zero out the bound table so loader doesn't use it instead of our new table.421inh.BOUND_DIRECTORY.VirtualAddress = 0;422inh.BOUND_DIRECTORY.Size = 0;423424// Find the size of the mapped file.425DWORD dwFileSize = 0;426DWORD dwSec = idh.e_lfanew +427FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) +428inh.FileHeader.SizeOfOptionalHeader;429430for (i = 0; i < inh.FileHeader.NumberOfSections; i++) {431IMAGE_SECTION_HEADER ish;432ZeroMemory(&ish, sizeof(ish));433434if (!ReadProcessMemory(hProcess, pbModule + dwSec + sizeof(ish) * i, &ish,435sizeof(ish), NULL)) {436DETOUR_TRACE(("ReadProcessMemory(inh) failed: %d\n", GetLastError()));437goto finish;438}439440DETOUR_TRACE(("ish[%d] : va=%p sr=%d\n", i, ish.VirtualAddress, ish.SizeOfRawData));441442// If the file didn't have an IAT_DIRECTORY, we create one...443if (inh.IAT_DIRECTORY.VirtualAddress == 0 &&444inh.IMPORT_DIRECTORY.VirtualAddress >= ish.VirtualAddress &&445inh.IMPORT_DIRECTORY.VirtualAddress < ish.VirtualAddress + ish.SizeOfRawData) {446447inh.IAT_DIRECTORY.VirtualAddress = ish.VirtualAddress;448inh.IAT_DIRECTORY.Size = ish.SizeOfRawData;449}450451// Find the end of the file...452if (dwFileSize < ish.PointerToRawData + ish.SizeOfRawData) {453dwFileSize = ish.PointerToRawData + ish.SizeOfRawData;454}455}456DETOUR_TRACE(("dwFileSize = %08x\n", dwFileSize));457458// Find the current checksum.459WORD wBefore = ComputeChkSum(hProcess, pbModule, &inh);460DETOUR_TRACE(("ChkSum: %04x + %08x => %08x\n", wBefore, dwFileSize, wBefore + dwFileSize));461462DETOUR_TRACE((" Imports: %8p..%8p\n",463(DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,464(DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress +465inh.IMPORT_DIRECTORY.Size));466467DWORD obRem = sizeof(IMAGE_IMPORT_DESCRIPTOR) * nDlls;468DWORD obTab = PadToDwordPtr(obRem + inh.IMPORT_DIRECTORY.Size);469DWORD obDll = obTab + sizeof(DWORD_PTR) * 4 * nDlls;470DWORD obStr = obDll;471DWORD cbNew = obStr;472DWORD n;473for (n = 0; n < nDlls; n++) {474cbNew += PadToDword((DWORD)strlen(plpDlls[n]) + 1);475}476477pbNew = new BYTE [cbNew];478if (pbNew == NULL) {479DETOUR_TRACE(("new BYTE [cbNew] failed.\n"));480goto finish;481}482ZeroMemory(pbNew, cbNew);483484PBYTE pbBase = pbModule;485PBYTE pbNext = pbBase486+ inh.OptionalHeader.BaseOfCode487+ inh.OptionalHeader.SizeOfCode488+ inh.OptionalHeader.SizeOfInitializedData489+ inh.OptionalHeader.SizeOfUninitializedData;490if (pbBase < pbNext) {491pbBase = pbNext;492}493DETOUR_TRACE(("pbBase = %p\n", pbBase));494495PBYTE pbNewIid = FindAndAllocateNearBase(hProcess, pbBase, cbNew);496if (pbNewIid == NULL) {497DETOUR_TRACE(("FindAndAllocateNearBase failed.\n"));498goto finish;499}500501DWORD dwProtect = 0;502der.impDirProt = 0;503if (!VirtualProtectEx(hProcess,504pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,505inh.IMPORT_DIRECTORY.Size, PAGE_EXECUTE_READWRITE, &dwProtect)) {506DETOUR_TRACE(("VirtualProtextEx(import) write failed: %d\n", GetLastError()));507goto finish;508}509DETOUR_TRACE(("IMPORT_DIRECTORY perms=%x\n", dwProtect));510der.impDirProt = dwProtect;511512DWORD obBase = (DWORD)(pbNewIid - pbModule);513514if (!ReadProcessMemory(hProcess,515pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,516pbNew + obRem,517inh.IMPORT_DIRECTORY.Size, NULL)) {518DETOUR_TRACE(("ReadProcessMemory(imports) failed: %d\n", GetLastError()));519goto finish;520}521522PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)pbNew;523DWORD_PTR *pt;524525for (n = 0; n < nDlls; n++) {526HRESULT hrRet = StringCchCopyA((char*)pbNew + obStr, cbNew - obStr, plpDlls[n]);527if (FAILED(hrRet))528{529DETOUR_TRACE(("StringCchCopyA failed: %d\n", GetLastError()));530goto finish;531}532533DWORD nOffset = obTab + (sizeof(DWORD_PTR) * (4 * n));534piid[n].OriginalFirstThunk = obBase + nOffset;535pt = ((DWORD_PTR*)(pbNew + nOffset));536pt[0] = IMAGE_ORDINAL_FLAG + 1;537pt[1] = 0;538539nOffset = obTab + (sizeof(DWORD_PTR) * ((4 * n) + 2));540piid[n].FirstThunk = obBase + nOffset;541pt = ((DWORD_PTR*)(pbNew + nOffset));542pt[0] = IMAGE_ORDINAL_FLAG + 1;543pt[1] = 0;544piid[n].TimeDateStamp = 0;545piid[n].ForwarderChain = 0;546piid[n].Name = obBase + obStr;547548obStr += PadToDword((DWORD)strlen(plpDlls[n]) + 1);549}550551for (i = 0; i < nDlls + (inh.IMPORT_DIRECTORY.Size / sizeof(*piid)); i++) {552DETOUR_TRACE(("%8d. Look=%08x Time=%08x Fore=%08x Name=%08x Addr=%08x\n",553i,554piid[i].OriginalFirstThunk,555piid[i].TimeDateStamp,556piid[i].ForwarderChain,557piid[i].Name,558piid[i].FirstThunk));559if (piid[i].OriginalFirstThunk == 0 && piid[i].FirstThunk == 0) {560break;561}562}563564if (!WriteProcessMemory(hProcess, pbNewIid, pbNew, obStr, NULL)) {565DETOUR_TRACE(("WriteProcessMemory(iid) failed: %d\n", GetLastError()));566goto finish;567}568569DETOUR_TRACE(("obBase = %p..%p\n",570inh.IMPORT_DIRECTORY.VirtualAddress,571inh.IMPORT_DIRECTORY.VirtualAddress + inh.IMPORT_DIRECTORY.Size));572DETOUR_TRACE(("obBase = %p..%p\n", obBase, obBase + obStr));573574inh.IMPORT_DIRECTORY.VirtualAddress = obBase;575inh.IMPORT_DIRECTORY.Size = cbNew;576577/////////////////////////////////////////////////// Update the CLR header.578//579if (inh.CLR_DIRECTORY.VirtualAddress != 0 &&580inh.CLR_DIRECTORY.Size != 0) {581582DETOUR_CLR_HEADER clr;583PBYTE pbClr = pbModule + inh.CLR_DIRECTORY.VirtualAddress;584585if (!ReadProcessMemory(hProcess, pbClr, &clr, sizeof(clr), NULL)) {586DETOUR_TRACE(("ReadProcessMemory(clr) failed: %d\n", GetLastError()));587goto finish;588}589590der.pclrFlags = (PULONG)(pbClr + offsetof(DETOUR_CLR_HEADER, Flags));591der.clrFlags = clr.Flags;592593clr.Flags &= 0xfffffffe; // Clear the IL_ONLY flag.594595if (!VirtualProtectEx(hProcess, pbClr, sizeof(clr), PAGE_READWRITE, &dwProtect)) {596DETOUR_TRACE(("VirtualProtextEx(clr) write failed: %d\n", GetLastError()));597goto finish;598}599600if (!WriteProcessMemory(hProcess, pbClr, &clr, sizeof(clr), NULL)) {601DETOUR_TRACE(("WriteProcessMemory(clr) failed: %d\n", GetLastError()));602goto finish;603}604605if (!VirtualProtectEx(hProcess, pbClr, sizeof(clr), dwProtect, &dwProtect)) {606DETOUR_TRACE(("VirtualProtextEx(clr) restore failed: %d\n", GetLastError()));607goto finish;608}609}610611/////////////////////// Update the NT header for the import new directory.612/////////////////////////////// Update the DOS header to fix the checksum.613//614if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,615PAGE_EXECUTE_READWRITE, &dwProtect)) {616DETOUR_TRACE(("VirtualProtextEx(inh) write failed: %d\n", GetLastError()));617goto finish;618}619620idh.e_res[0] = 0;621if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {622DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError()));623goto finish;624}625626if (!WriteProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) {627DETOUR_TRACE(("WriteProcessMemory(inh) failed: %d\n", GetLastError()));628goto finish;629}630631WORD wDuring = ComputeChkSum(hProcess, pbModule, &inh);632DETOUR_TRACE(("ChkSum: %04x + %08x => %08x\n", wDuring, dwFileSize, wDuring + dwFileSize));633634idh.e_res[0] = detour_sum_minus(idh.e_res[0], detour_sum_minus(wDuring, wBefore));635636if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {637DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError()));638goto finish;639}640641if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,642dwProtect, &dwProtect)) {643DETOUR_TRACE(("VirtualProtextEx(idh) restore failed: %d\n", GetLastError()));644goto finish;645}646647WORD wAfter = ComputeChkSum(hProcess, pbModule, &inh);648DETOUR_TRACE(("ChkSum: %04x + %08x => %08x\n", wAfter, dwFileSize, wAfter + dwFileSize));649DETOUR_TRACE(("Before: %08x, After: %08x\n", wBefore + dwFileSize, wAfter + dwFileSize));650651if (wBefore != wAfter) {652DETOUR_TRACE(("Restore of checksum failed %04x != %04x.\n", wBefore, wAfter));653goto finish;654}655656if (!DetourCopyPayloadToProcess(hProcess, DETOUR_EXE_RESTORE_GUID, &der, sizeof(der))) {657DETOUR_TRACE(("DetourCopyPayloadToProcess failed: %d\n", GetLastError()));658goto finish;659}660661fSucceeded = TRUE;662goto finish;663}664665//////////////////////////////////////////////////////////////////////////////666//667BOOL WINAPI DetourCreateProcessWithDllA(LPCSTR lpApplicationName,668__in_z LPSTR lpCommandLine,669LPSECURITY_ATTRIBUTES lpProcessAttributes,670LPSECURITY_ATTRIBUTES lpThreadAttributes,671BOOL bInheritHandles,672DWORD dwCreationFlags,673LPVOID lpEnvironment,674LPCSTR lpCurrentDirectory,675LPSTARTUPINFOA lpStartupInfo,676LPPROCESS_INFORMATION lpProcessInformation,677LPCSTR lpDetouredDllFullName,678LPCSTR lpDllName,679PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA)680{681DWORD dwMyCreationFlags = (dwCreationFlags | CREATE_SUSPENDED);682PROCESS_INFORMATION pi;683684if (pfCreateProcessA == NULL) {685pfCreateProcessA = CreateProcessA;686}687688if (!pfCreateProcessA(lpApplicationName,689lpCommandLine,690lpProcessAttributes,691lpThreadAttributes,692bInheritHandles,693dwMyCreationFlags,694lpEnvironment,695lpCurrentDirectory,696lpStartupInfo,697&pi)) {698return FALSE;699}700701LPCSTR rlpDlls[2];702DWORD nDlls = 0;703if (lpDetouredDllFullName != NULL) {704rlpDlls[nDlls++] = lpDetouredDllFullName;705}706if (lpDllName != NULL) {707rlpDlls[nDlls++] = lpDllName;708}709710if (!UpdateImports(pi.hProcess, rlpDlls, nDlls)) {711return FALSE;712}713714if (lpProcessInformation) {715CopyMemory(lpProcessInformation, &pi, sizeof(pi));716}717718if (!(dwCreationFlags & CREATE_SUSPENDED)) {719ResumeThread(pi.hThread);720}721return TRUE;722}723724725BOOL WINAPI DetourCreateProcessWithDllW(LPCWSTR lpApplicationName,726__in_z LPWSTR lpCommandLine,727LPSECURITY_ATTRIBUTES lpProcessAttributes,728LPSECURITY_ATTRIBUTES lpThreadAttributes,729BOOL bInheritHandles,730DWORD dwCreationFlags,731LPVOID lpEnvironment,732LPCWSTR lpCurrentDirectory,733LPSTARTUPINFOW lpStartupInfo,734LPPROCESS_INFORMATION lpProcessInformation,735LPCSTR lpDetouredDllFullName,736LPCSTR lpDllName,737PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW)738{739DWORD dwMyCreationFlags = (dwCreationFlags | CREATE_SUSPENDED);740PROCESS_INFORMATION pi;741742if (pfCreateProcessW == NULL) {743pfCreateProcessW = CreateProcessW;744}745746if (!pfCreateProcessW(lpApplicationName,747lpCommandLine,748lpProcessAttributes,749lpThreadAttributes,750bInheritHandles,751dwMyCreationFlags,752lpEnvironment,753lpCurrentDirectory,754lpStartupInfo,755&pi)) {756return FALSE;757}758759LPCSTR rlpDlls[2];760DWORD nDlls = 0;761if (lpDetouredDllFullName != NULL) {762rlpDlls[nDlls++] = lpDetouredDllFullName;763}764if (lpDllName != NULL) {765rlpDlls[nDlls++] = lpDllName;766}767768if (!UpdateImports(pi.hProcess, rlpDlls, nDlls)) {769return FALSE;770}771772if (lpProcessInformation) {773CopyMemory(lpProcessInformation, &pi, sizeof(pi));774}775776if (!(dwCreationFlags & CREATE_SUSPENDED)) {777ResumeThread(pi.hThread);778}779return TRUE;780}781782BOOL WINAPI DetourCopyPayloadToProcess(HANDLE hProcess,783REFGUID rguid,784PVOID pData,785DWORD cbData)786{787DWORD cbTotal = (sizeof(IMAGE_DOS_HEADER) +788sizeof(IMAGE_NT_HEADERS) +789sizeof(IMAGE_SECTION_HEADER) +790sizeof(DETOUR_SECTION_HEADER) +791sizeof(DETOUR_SECTION_RECORD) +792cbData);793794PBYTE pbBase = (PBYTE)VirtualAllocEx(hProcess, NULL, cbTotal,795MEM_COMMIT, PAGE_READWRITE);796if (pbBase == NULL) {797DETOUR_TRACE(("VirtualAllocEx(%d) failed: %d\n", cbTotal, GetLastError()));798return FALSE;799}800801PBYTE pbTarget = pbBase;802IMAGE_DOS_HEADER idh;803IMAGE_NT_HEADERS inh;804IMAGE_SECTION_HEADER ish;805DETOUR_SECTION_HEADER dsh;806DETOUR_SECTION_RECORD dsr;807SIZE_T cbWrote = 0;808809ZeroMemory(&idh, sizeof(idh));810idh.e_magic = IMAGE_DOS_SIGNATURE;811idh.e_lfanew = sizeof(idh);812if (!WriteProcessMemory(hProcess, pbTarget, &idh, sizeof(idh), &cbWrote) ||813cbWrote != sizeof(idh)) {814DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError()));815return FALSE;816}817pbTarget += sizeof(idh);818819ZeroMemory(&inh, sizeof(inh));820inh.Signature = IMAGE_NT_SIGNATURE;821inh.FileHeader.SizeOfOptionalHeader = sizeof(inh.OptionalHeader);822inh.FileHeader.Characteristics = IMAGE_FILE_DLL;823inh.FileHeader.NumberOfSections = 1;824if (!WriteProcessMemory(hProcess, pbTarget, &inh, sizeof(inh), &cbWrote) ||825cbWrote != sizeof(inh)) {826return FALSE;827}828pbTarget += sizeof(inh);829830ZeroMemory(&ish, sizeof(ish));831memcpy(ish.Name, ".detour", sizeof(ish.Name));832ish.VirtualAddress = (DWORD)((pbTarget + sizeof(ish)) - pbBase);833ish.SizeOfRawData = (sizeof(DETOUR_SECTION_HEADER) +834sizeof(DETOUR_SECTION_RECORD) +835cbData);836if (!WriteProcessMemory(hProcess, pbTarget, &ish, sizeof(ish), &cbWrote) ||837cbWrote != sizeof(ish)) {838return FALSE;839}840pbTarget += sizeof(ish);841842ZeroMemory(&dsh, sizeof(dsh));843dsh.cbHeaderSize = sizeof(dsh);844dsh.nSignature = DETOUR_SECTION_HEADER_SIGNATURE;845dsh.nDataOffset = sizeof(DETOUR_SECTION_HEADER);846dsh.cbDataSize = (sizeof(DETOUR_SECTION_HEADER) +847sizeof(DETOUR_SECTION_RECORD) +848cbData);849if (!WriteProcessMemory(hProcess, pbTarget, &dsh, sizeof(dsh), &cbWrote) ||850cbWrote != sizeof(dsh)) {851return FALSE;852}853pbTarget += sizeof(dsh);854855ZeroMemory(&dsr, sizeof(dsr));856dsr.cbBytes = cbData + sizeof(DETOUR_SECTION_RECORD);857dsr.nReserved = 0;858dsr.guid = rguid;859if (!WriteProcessMemory(hProcess, pbTarget, &dsr, sizeof(dsr), &cbWrote) ||860cbWrote != sizeof(dsr)) {861return FALSE;862}863pbTarget += sizeof(dsr);864865if (!WriteProcessMemory(hProcess, pbTarget, pData, cbData, &cbWrote) ||866cbWrote != cbData) {867return FALSE;868}869pbTarget += cbData;870871DETOUR_TRACE(("Copied %d bytes into target process at %p\n",872cbTotal, pbTarget - cbTotal));873return TRUE;874}875876//877///////////////////////////////////////////////////////////////// End of File.878879880