mirror of
https://github.com/emtee40/NanaZip
synced 2026-04-25 16:24:56 +02:00
Remove NanaZip.Shared.Detours.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Common version parameters.
|
|
||||||
//
|
|
||||||
// Microsoft Research Detours Package, Version 4.0.1
|
|
||||||
//
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#define _USING_V110_SDK71_ 1
|
|
||||||
#include "winver.h"
|
|
||||||
#if 0
|
|
||||||
#include <windows.h>
|
|
||||||
#include <detours.h>
|
|
||||||
#else
|
|
||||||
#ifndef DETOURS_STRINGIFY
|
|
||||||
#define DETOURS_STRINGIFY_(x) #x
|
|
||||||
#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VER_FILEFLAGSMASK 0x3fL
|
|
||||||
#define VER_FILEFLAGS 0x0L
|
|
||||||
#define VER_FILEOS 0x00040004L
|
|
||||||
#define VER_FILETYPE 0x00000002L
|
|
||||||
#define VER_FILESUBTYPE 0x00000000L
|
|
||||||
#endif
|
|
||||||
#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
|||||||
#define DETOURS_ARM_OFFLINE_LIBRARY
|
|
||||||
#include "disasm.cpp"
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#define DETOURS_ARM64_OFFLINE_LIBRARY
|
|
||||||
#include "disasm.cpp"
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#define DETOURS_IA64_OFFLINE_LIBRARY
|
|
||||||
#include "disasm.cpp"
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#define DETOURS_X64_OFFLINE_LIBRARY
|
|
||||||
#include "disasm.cpp"
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#define DETOURS_X86_OFFLINE_LIBRARY
|
|
||||||
#include "disasm.cpp"
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,932 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Module Enumeration Functions (modules.cpp of detours.lib)
|
|
||||||
//
|
|
||||||
// Microsoft Research Detours Package, Version 4.0.1
|
|
||||||
//
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
//
|
|
||||||
// Module enumeration functions.
|
|
||||||
//
|
|
||||||
|
|
||||||
// #define DETOUR_DEBUG 1
|
|
||||||
#define DETOURS_INTERNAL
|
|
||||||
#include "detours.h"
|
|
||||||
|
|
||||||
#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH
|
|
||||||
#error detours.h version mismatch
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CLR_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]
|
|
||||||
#define IAT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT]
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
const GUID DETOUR_EXE_RESTORE_GUID = {
|
|
||||||
0xbda26f34, 0xbc82, 0x4829,
|
|
||||||
{ 0x9e, 0x64, 0x74, 0x2c, 0x4, 0xc8, 0x4f, 0xa0 } };
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
PDETOUR_SYM_INFO DetourLoadImageHlp(VOID)
|
|
||||||
{
|
|
||||||
static DETOUR_SYM_INFO symInfo;
|
|
||||||
static PDETOUR_SYM_INFO pSymInfo = NULL;
|
|
||||||
static BOOL failed = false;
|
|
||||||
|
|
||||||
if (failed) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pSymInfo != NULL) {
|
|
||||||
return pSymInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroMemory(&symInfo, sizeof(symInfo));
|
|
||||||
// Create a real handle to the process.
|
|
||||||
#if 0
|
|
||||||
DuplicateHandle(GetCurrentProcess(),
|
|
||||||
GetCurrentProcess(),
|
|
||||||
GetCurrentProcess(),
|
|
||||||
&symInfo.hProcess,
|
|
||||||
0,
|
|
||||||
FALSE,
|
|
||||||
DUPLICATE_SAME_ACCESS);
|
|
||||||
#else
|
|
||||||
symInfo.hProcess = GetCurrentProcess();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
symInfo.hDbgHelp = LoadLibraryExW(L"dbghelp.dll", NULL, 0);
|
|
||||||
if (symInfo.hDbgHelp == NULL) {
|
|
||||||
abort:
|
|
||||||
failed = true;
|
|
||||||
if (symInfo.hDbgHelp != NULL) {
|
|
||||||
FreeLibrary(symInfo.hDbgHelp);
|
|
||||||
}
|
|
||||||
symInfo.pfImagehlpApiVersionEx = NULL;
|
|
||||||
symInfo.pfSymInitialize = NULL;
|
|
||||||
symInfo.pfSymSetOptions = NULL;
|
|
||||||
symInfo.pfSymGetOptions = NULL;
|
|
||||||
symInfo.pfSymLoadModule64 = NULL;
|
|
||||||
symInfo.pfSymGetModuleInfo64 = NULL;
|
|
||||||
symInfo.pfSymFromName = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
symInfo.pfImagehlpApiVersionEx
|
|
||||||
= (PF_ImagehlpApiVersionEx)GetProcAddress(symInfo.hDbgHelp,
|
|
||||||
"ImagehlpApiVersionEx");
|
|
||||||
symInfo.pfSymInitialize
|
|
||||||
= (PF_SymInitialize)GetProcAddress(symInfo.hDbgHelp, "SymInitialize");
|
|
||||||
symInfo.pfSymSetOptions
|
|
||||||
= (PF_SymSetOptions)GetProcAddress(symInfo.hDbgHelp, "SymSetOptions");
|
|
||||||
symInfo.pfSymGetOptions
|
|
||||||
= (PF_SymGetOptions)GetProcAddress(symInfo.hDbgHelp, "SymGetOptions");
|
|
||||||
symInfo.pfSymLoadModule64
|
|
||||||
= (PF_SymLoadModule64)GetProcAddress(symInfo.hDbgHelp, "SymLoadModule64");
|
|
||||||
symInfo.pfSymGetModuleInfo64
|
|
||||||
= (PF_SymGetModuleInfo64)GetProcAddress(symInfo.hDbgHelp, "SymGetModuleInfo64");
|
|
||||||
symInfo.pfSymFromName
|
|
||||||
= (PF_SymFromName)GetProcAddress(symInfo.hDbgHelp, "SymFromName");
|
|
||||||
|
|
||||||
API_VERSION av;
|
|
||||||
ZeroMemory(&av, sizeof(av));
|
|
||||||
av.MajorVersion = API_VERSION_NUMBER;
|
|
||||||
|
|
||||||
if (symInfo.pfImagehlpApiVersionEx == NULL ||
|
|
||||||
symInfo.pfSymInitialize == NULL ||
|
|
||||||
symInfo.pfSymLoadModule64 == NULL ||
|
|
||||||
symInfo.pfSymGetModuleInfo64 == NULL ||
|
|
||||||
symInfo.pfSymFromName == NULL) {
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
symInfo.pfImagehlpApiVersionEx(&av);
|
|
||||||
if (av.MajorVersion < API_VERSION_NUMBER) {
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!symInfo.pfSymInitialize(symInfo.hProcess, NULL, FALSE)) {
|
|
||||||
// We won't retry the initialize if it fails.
|
|
||||||
goto abort;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (symInfo.pfSymGetOptions != NULL && symInfo.pfSymSetOptions != NULL) {
|
|
||||||
DWORD dw = symInfo.pfSymGetOptions();
|
|
||||||
|
|
||||||
dw &= ~(SYMOPT_CASE_INSENSITIVE |
|
|
||||||
SYMOPT_UNDNAME |
|
|
||||||
SYMOPT_DEFERRED_LOADS |
|
|
||||||
0);
|
|
||||||
dw |= (
|
|
||||||
#if defined(SYMOPT_EXACT_SYMBOLS)
|
|
||||||
SYMOPT_EXACT_SYMBOLS |
|
|
||||||
#endif
|
|
||||||
#if defined(SYMOPT_NO_UNQUALIFIED_LOADS)
|
|
||||||
SYMOPT_NO_UNQUALIFIED_LOADS |
|
|
||||||
#endif
|
|
||||||
SYMOPT_DEFERRED_LOADS |
|
|
||||||
#if defined(SYMOPT_FAIL_CRITICAL_ERRORS)
|
|
||||||
SYMOPT_FAIL_CRITICAL_ERRORS |
|
|
||||||
#endif
|
|
||||||
#if defined(SYMOPT_INCLUDE_32BIT_MODULES)
|
|
||||||
SYMOPT_INCLUDE_32BIT_MODULES |
|
|
||||||
#endif
|
|
||||||
0);
|
|
||||||
symInfo.pfSymSetOptions(dw);
|
|
||||||
}
|
|
||||||
|
|
||||||
pSymInfo = &symInfo;
|
|
||||||
return pSymInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule,
|
|
||||||
_In_ LPCSTR pszFunction)
|
|
||||||
{
|
|
||||||
if (pszFunction == NULL) {
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////// First, try GetProcAddress.
|
|
||||||
//
|
|
||||||
#pragma prefast(suppress:28752, "We don't do the unicode conversion for LoadLibraryExA.")
|
|
||||||
HMODULE hModule = LoadLibraryExA(pszModule, NULL, 0);
|
|
||||||
if (hModule == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PBYTE pbCode = (PBYTE)GetProcAddress(hModule, pszFunction);
|
|
||||||
if (pbCode) {
|
|
||||||
return pbCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////// Then try ImageHelp.
|
|
||||||
//
|
|
||||||
DETOUR_TRACE(("DetourFindFunction(%hs, %hs)\n", pszModule, pszFunction));
|
|
||||||
PDETOUR_SYM_INFO pSymInfo = DetourLoadImageHlp();
|
|
||||||
if (pSymInfo == NULL) {
|
|
||||||
DETOUR_TRACE(("DetourLoadImageHlp failed: %lu\n",
|
|
||||||
GetLastError()));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pSymInfo->pfSymLoadModule64(pSymInfo->hProcess, NULL,
|
|
||||||
(PCHAR)pszModule, NULL,
|
|
||||||
(DWORD64)hModule, 0) == 0) {
|
|
||||||
if (ERROR_SUCCESS != GetLastError()) {
|
|
||||||
DETOUR_TRACE(("SymLoadModule64(%p) failed: %lu\n",
|
|
||||||
pSymInfo->hProcess, GetLastError()));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hrRet;
|
|
||||||
CHAR szFullName[512];
|
|
||||||
IMAGEHLP_MODULE64 modinfo;
|
|
||||||
ZeroMemory(&modinfo, sizeof(modinfo));
|
|
||||||
modinfo.SizeOfStruct = sizeof(modinfo);
|
|
||||||
if (!pSymInfo->pfSymGetModuleInfo64(pSymInfo->hProcess, (DWORD64)hModule, &modinfo)) {
|
|
||||||
DETOUR_TRACE(("SymGetModuleInfo64(%p, %p) failed: %lu\n",
|
|
||||||
pSymInfo->hProcess, hModule, GetLastError()));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hrRet = StringCchCopyA(szFullName, sizeof(szFullName)/sizeof(CHAR), modinfo.ModuleName);
|
|
||||||
if (FAILED(hrRet)) {
|
|
||||||
DETOUR_TRACE(("StringCchCopyA failed: %08lx\n", hrRet));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
hrRet = StringCchCatA(szFullName, sizeof(szFullName)/sizeof(CHAR), "!");
|
|
||||||
if (FAILED(hrRet)) {
|
|
||||||
DETOUR_TRACE(("StringCchCatA failed: %08lx\n", hrRet));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
hrRet = StringCchCatA(szFullName, sizeof(szFullName)/sizeof(CHAR), pszFunction);
|
|
||||||
if (FAILED(hrRet)) {
|
|
||||||
DETOUR_TRACE(("StringCchCatA failed: %08lx\n", hrRet));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CFullSymbol : SYMBOL_INFO {
|
|
||||||
CHAR szRestOfName[512];
|
|
||||||
} symbol;
|
|
||||||
ZeroMemory(&symbol, sizeof(symbol));
|
|
||||||
//symbol.ModBase = (ULONG64)hModule;
|
|
||||||
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
|
|
||||||
#ifdef DBHLPAPI
|
|
||||||
symbol.MaxNameLen = sizeof(symbol.szRestOfName)/sizeof(symbol.szRestOfName[0]);
|
|
||||||
#else
|
|
||||||
symbol.MaxNameLength = sizeof(symbol.szRestOfName)/sizeof(symbol.szRestOfName[0]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!pSymInfo->pfSymFromName(pSymInfo->hProcess, szFullName, &symbol)) {
|
|
||||||
DETOUR_TRACE(("SymFromName(%hs) failed: %lu\n", szFullName, GetLastError()));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DETOURS_IA64)
|
|
||||||
// On the IA64, we get a raw code pointer from the symbol engine
|
|
||||||
// and have to convert it to a wrapped [code pointer, global pointer].
|
|
||||||
//
|
|
||||||
PPLABEL_DESCRIPTOR pldEntry = (PPLABEL_DESCRIPTOR)DetourGetEntryPoint(hModule);
|
|
||||||
PPLABEL_DESCRIPTOR pldSymbol = new PLABEL_DESCRIPTOR;
|
|
||||||
|
|
||||||
pldSymbol->EntryPoint = symbol.Address;
|
|
||||||
pldSymbol->GlobalPointer = pldEntry->GlobalPointer;
|
|
||||||
return (PBYTE)pldSymbol;
|
|
||||||
#elif defined(DETOURS_ARM)
|
|
||||||
// On the ARM, we get a raw code pointer, which we must convert into a
|
|
||||||
// valied Thumb2 function pointer.
|
|
||||||
return DETOURS_PBYTE_TO_PFUNC(symbol.Address);
|
|
||||||
#else
|
|
||||||
return (PBYTE)symbol.Address;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////// Module Image Functions.
|
|
||||||
//
|
|
||||||
|
|
||||||
HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast)
|
|
||||||
{
|
|
||||||
PBYTE pbLast = (PBYTE)hModuleLast + MM_ALLOCATION_GRANULARITY;
|
|
||||||
|
|
||||||
MEMORY_BASIC_INFORMATION mbi;
|
|
||||||
ZeroMemory(&mbi, sizeof(mbi));
|
|
||||||
|
|
||||||
// Find the next memory region that contains a mapped PE image.
|
|
||||||
//
|
|
||||||
for (;; pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {
|
|
||||||
if (VirtualQuery(pbLast, &mbi, sizeof(mbi)) <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip uncommitted regions and guard pages.
|
|
||||||
//
|
|
||||||
if ((mbi.State != MEM_COMMIT) ||
|
|
||||||
((mbi.Protect & 0xff) == PAGE_NOACCESS) ||
|
|
||||||
(mbi.Protect & PAGE_GUARD)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
__try {
|
|
||||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbLast;
|
|
||||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
|
|
||||||
(DWORD)pDosHeader->e_lfanew > mbi.RegionSize ||
|
|
||||||
(DWORD)pDosHeader->e_lfanew < sizeof(*pDosHeader)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
|
||||||
pDosHeader->e_lfanew);
|
|
||||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
return (HMODULE)pDosHeader;
|
|
||||||
}
|
|
||||||
#pragma prefast(suppress:28940, "A bad pointer means this probably isn't a PE header.")
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
|
||||||
if (hModule == NULL) {
|
|
||||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
__try {
|
|
||||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
|
||||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
|
||||||
pDosHeader->e_lfanew);
|
|
||||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PDETOUR_CLR_HEADER pClrHeader = NULL;
|
|
||||||
if (pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
|
||||||
if (((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.VirtualAddress != 0 &&
|
|
||||||
((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.Size != 0) {
|
|
||||||
pClrHeader = (PDETOUR_CLR_HEADER)
|
|
||||||
(((PBYTE)pDosHeader)
|
|
||||||
+ ((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.VirtualAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
|
||||||
if (((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.VirtualAddress != 0 &&
|
|
||||||
((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.Size != 0) {
|
|
||||||
pClrHeader = (PDETOUR_CLR_HEADER)
|
|
||||||
(((PBYTE)pDosHeader)
|
|
||||||
+ ((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.VirtualAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pClrHeader != NULL) {
|
|
||||||
// For MSIL assemblies, we want to use the _Cor entry points.
|
|
||||||
|
|
||||||
HMODULE hClr = GetModuleHandleW(L"MSCOREE.DLL");
|
|
||||||
if (hClr == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
return (PVOID)GetProcAddress(hClr, "_CorExeMain");
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
|
|
||||||
// Pure resource DLLs have neither an entry point nor CLR information
|
|
||||||
// so handle them by returning NULL (LastError is NO_ERROR)
|
|
||||||
if (pNtHeader->OptionalHeader.AddressOfEntryPoint == 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((PBYTE)pDosHeader) +
|
|
||||||
pNtHeader->OptionalHeader.AddressOfEntryPoint;
|
|
||||||
}
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
|
||||||
if (hModule == NULL) {
|
|
||||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
__try {
|
|
||||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
|
||||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
|
||||||
pDosHeader->e_lfanew);
|
|
||||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
|
|
||||||
return (pNtHeader->OptionalHeader.SizeOfImage);
|
|
||||||
}
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr)
|
|
||||||
{
|
|
||||||
MEMORY_BASIC_INFORMATION mbi;
|
|
||||||
ZeroMemory(&mbi, sizeof(mbi));
|
|
||||||
|
|
||||||
__try {
|
|
||||||
if (VirtualQuery(pvAddr, &mbi, sizeof(mbi)) <= 0) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip uncommitted regions and guard pages.
|
|
||||||
//
|
|
||||||
if ((mbi.State != MEM_COMMIT) ||
|
|
||||||
((mbi.Protect & 0xff) == PAGE_NOACCESS) ||
|
|
||||||
(mbi.Protect & PAGE_GUARD)) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase;
|
|
||||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
|
||||||
pDosHeader->e_lfanew);
|
|
||||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
|
|
||||||
return (HMODULE)pDosHeader;
|
|
||||||
}
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline PBYTE RvaAdjust(_Pre_notnull_ PIMAGE_DOS_HEADER pDosHeader, _In_ DWORD raddr)
|
|
||||||
{
|
|
||||||
if (raddr != NULL) {
|
|
||||||
return ((PBYTE)pDosHeader) + raddr;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule,
|
|
||||||
_In_opt_ PVOID pContext,
|
|
||||||
_In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport)
|
|
||||||
{
|
|
||||||
if (pfExport == NULL) {
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
|
||||||
if (hModule == NULL) {
|
|
||||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
__try {
|
|
||||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
|
||||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
|
||||||
pDosHeader->e_lfanew);
|
|
||||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_EXPORT_DIRECTORY pExportDir
|
|
||||||
= (PIMAGE_EXPORT_DIRECTORY)
|
|
||||||
RvaAdjust(pDosHeader,
|
|
||||||
pNtHeader->OptionalHeader
|
|
||||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
|
||||||
|
|
||||||
if (pExportDir == NULL) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PBYTE pExportDirEnd = (PBYTE)pExportDir + pNtHeader->OptionalHeader
|
|
||||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
|
|
||||||
PDWORD pdwFunctions = (PDWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfFunctions);
|
|
||||||
PDWORD pdwNames = (PDWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfNames);
|
|
||||||
PWORD pwOrdinals = (PWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfNameOrdinals);
|
|
||||||
|
|
||||||
for (DWORD nFunc = 0; nFunc < pExportDir->NumberOfFunctions; nFunc++) {
|
|
||||||
PBYTE pbCode = (pdwFunctions != NULL)
|
|
||||||
? (PBYTE)RvaAdjust(pDosHeader, pdwFunctions[nFunc]) : NULL;
|
|
||||||
PCHAR pszName = NULL;
|
|
||||||
|
|
||||||
// if the pointer is in the export region, then it is a forwarder.
|
|
||||||
if (pbCode > (PBYTE)pExportDir && pbCode < pExportDirEnd) {
|
|
||||||
pbCode = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DWORD n = 0; n < pExportDir->NumberOfNames; n++) {
|
|
||||||
if (pwOrdinals[n] == nFunc) {
|
|
||||||
pszName = (pdwNames != NULL)
|
|
||||||
? (PCHAR)RvaAdjust(pDosHeader, pdwNames[n]) : NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ULONG nOrdinal = pExportDir->Base + nFunc;
|
|
||||||
|
|
||||||
if (!pfExport(pContext, nOrdinal, pszName, pbCode)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule,
|
|
||||||
_In_opt_ PVOID pContext,
|
|
||||||
_In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
|
|
||||||
_In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFunc)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
|
||||||
if (hModule == NULL) {
|
|
||||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
__try {
|
|
||||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
|
||||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
|
||||||
pDosHeader->e_lfanew);
|
|
||||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR iidp
|
|
||||||
= (PIMAGE_IMPORT_DESCRIPTOR)
|
|
||||||
RvaAdjust(pDosHeader,
|
|
||||||
pNtHeader->OptionalHeader
|
|
||||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
|
||||||
|
|
||||||
if (iidp == NULL) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; iidp->OriginalFirstThunk != 0; iidp++) {
|
|
||||||
|
|
||||||
PCSTR pszName = (PCHAR)RvaAdjust(pDosHeader, iidp->Name);
|
|
||||||
if (pszName == NULL) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_THUNK_DATA pThunks = (PIMAGE_THUNK_DATA)
|
|
||||||
RvaAdjust(pDosHeader, iidp->OriginalFirstThunk);
|
|
||||||
PVOID * pAddrs = (PVOID *)
|
|
||||||
RvaAdjust(pDosHeader, iidp->FirstThunk);
|
|
||||||
|
|
||||||
HMODULE hFile = DetourGetContainingModule(pAddrs[0]);
|
|
||||||
|
|
||||||
if (pfImportFile != NULL) {
|
|
||||||
if (!pfImportFile(pContext, hFile, pszName)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD nNames = 0;
|
|
||||||
if (pThunks) {
|
|
||||||
for (; pThunks[nNames].u1.Ordinal; nNames++) {
|
|
||||||
DWORD nOrdinal = 0;
|
|
||||||
PCSTR pszFunc = NULL;
|
|
||||||
|
|
||||||
if (IMAGE_SNAP_BY_ORDINAL(pThunks[nNames].u1.Ordinal)) {
|
|
||||||
nOrdinal = (DWORD)IMAGE_ORDINAL(pThunks[nNames].u1.Ordinal);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pszFunc = (PCSTR)RvaAdjust(pDosHeader,
|
|
||||||
(DWORD)pThunks[nNames].u1.AddressOfData + 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pfImportFunc != NULL) {
|
|
||||||
if (!pfImportFunc(pContext,
|
|
||||||
nOrdinal,
|
|
||||||
pszFunc,
|
|
||||||
&pAddrs[nNames])) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pfImportFunc != NULL) {
|
|
||||||
pfImportFunc(pContext, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pfImportFile != NULL) {
|
|
||||||
pfImportFile(pContext, NULL, NULL);
|
|
||||||
}
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Context for DetourEnumerateImportsThunk, which adapts "regular" callbacks for use with "Ex".
|
|
||||||
struct _DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT
|
|
||||||
{
|
|
||||||
PVOID pContext;
|
|
||||||
PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Callback for DetourEnumerateImportsEx that adapts DetourEnumerateImportsEx
|
|
||||||
// for use with a DetourEnumerateImports callback -- derefence the IAT and pass the value on.
|
|
||||||
|
|
||||||
static
|
|
||||||
BOOL
|
|
||||||
CALLBACK
|
|
||||||
DetourEnumerateImportsThunk(_In_ PVOID VoidContext,
|
|
||||||
_In_ DWORD nOrdinal,
|
|
||||||
_In_opt_ PCSTR pszFunc,
|
|
||||||
_In_opt_ PVOID* ppvFunc)
|
|
||||||
{
|
|
||||||
_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT const * const
|
|
||||||
pContext = (_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT*)VoidContext;
|
|
||||||
return pContext->pfImportFunc(pContext->pContext, nOrdinal, pszFunc, ppvFunc ? *ppvFunc : NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule,
|
|
||||||
_In_opt_ PVOID pContext,
|
|
||||||
_In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
|
|
||||||
_In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc)
|
|
||||||
{
|
|
||||||
if (pfImportFile == NULL || pfImportFunc == NULL) {
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT const context = { pContext, pfImportFunc };
|
|
||||||
|
|
||||||
return DetourEnumerateImportsEx(hModule,
|
|
||||||
(PVOID)&context,
|
|
||||||
pfImportFile,
|
|
||||||
&DetourEnumerateImportsThunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PDETOUR_LOADED_BINARY WINAPI GetPayloadSectionFromModule(HMODULE hModule)
|
|
||||||
{
|
|
||||||
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
|
|
||||||
if (hModule == NULL) {
|
|
||||||
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
__try {
|
|
||||||
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
|
|
||||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
|
|
||||||
pDosHeader->e_lfanew);
|
|
||||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
|
|
||||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_SECTION_HEADER pSectionHeaders
|
|
||||||
= (PIMAGE_SECTION_HEADER)((PBYTE)pNtHeader
|
|
||||||
+ sizeof(pNtHeader->Signature)
|
|
||||||
+ sizeof(pNtHeader->FileHeader)
|
|
||||||
+ pNtHeader->FileHeader.SizeOfOptionalHeader);
|
|
||||||
|
|
||||||
for (DWORD n = 0; n < pNtHeader->FileHeader.NumberOfSections; n++) {
|
|
||||||
if (strcmp((PCHAR)pSectionHeaders[n].Name, ".detour") == 0) {
|
|
||||||
if (pSectionHeaders[n].VirtualAddress == 0 ||
|
|
||||||
pSectionHeaders[n].SizeOfRawData == 0) {
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PBYTE pbData = (PBYTE)pDosHeader + pSectionHeaders[n].VirtualAddress;
|
|
||||||
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pbData;
|
|
||||||
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
|
|
||||||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pHeader->nDataOffset == 0) {
|
|
||||||
pHeader->nDataOffset = pHeader->cbHeaderSize;
|
|
||||||
}
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
return (PBYTE)pHeader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
SetLastError(ERROR_EXE_MARKED_INVALID);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule)
|
|
||||||
{
|
|
||||||
PDETOUR_LOADED_BINARY pBinary = GetPayloadSectionFromModule(hModule);
|
|
||||||
if (pBinary == NULL) {
|
|
||||||
// Error set by GetPayloadSectionFromModule.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__try {
|
|
||||||
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary;
|
|
||||||
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
|
|
||||||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
|
|
||||||
|
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
return pHeader->cbDataSize;
|
|
||||||
}
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_Writable_bytes_(*pcbData)
|
|
||||||
_Readable_bytes_(*pcbData)
|
|
||||||
_Success_(return != NULL)
|
|
||||||
PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule,
|
|
||||||
_In_ REFGUID rguid,
|
|
||||||
_Out_opt_ DWORD *pcbData)
|
|
||||||
{
|
|
||||||
PBYTE pbData = NULL;
|
|
||||||
if (pcbData) {
|
|
||||||
*pcbData = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PDETOUR_LOADED_BINARY pBinary = GetPayloadSectionFromModule(hModule);
|
|
||||||
if (pBinary == NULL) {
|
|
||||||
// Error set by GetPayloadSectionFromModule.
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
__try {
|
|
||||||
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary;
|
|
||||||
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
|
|
||||||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
|
|
||||||
|
|
||||||
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PBYTE pbBeg = ((PBYTE)pHeader) + pHeader->nDataOffset;
|
|
||||||
PBYTE pbEnd = ((PBYTE)pHeader) + pHeader->cbDataSize;
|
|
||||||
|
|
||||||
for (pbData = pbBeg; pbData < pbEnd;) {
|
|
||||||
DETOUR_SECTION_RECORD *pSection = (DETOUR_SECTION_RECORD *)pbData;
|
|
||||||
|
|
||||||
if (DetourAreSameGuid(pSection->guid, rguid)) {
|
|
||||||
if (pcbData) {
|
|
||||||
*pcbData = pSection->cbBytes - sizeof(*pSection);
|
|
||||||
}
|
|
||||||
SetLastError(NO_ERROR);
|
|
||||||
return (PBYTE)(pSection + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pbData = (PBYTE)pSection + pSection->cbBytes;
|
|
||||||
}
|
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
|
|
||||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
|
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_Writable_bytes_(*pcbData)
|
|
||||||
_Readable_bytes_(*pcbData)
|
|
||||||
_Success_(return != NULL)
|
|
||||||
PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid,
|
|
||||||
_Out_opt_ DWORD *pcbData)
|
|
||||||
{
|
|
||||||
for (HMODULE hMod = NULL; (hMod = DetourEnumerateModules(hMod)) != NULL;) {
|
|
||||||
PVOID pvData;
|
|
||||||
|
|
||||||
pvData = DetourFindPayload(hMod, rguid, pcbData);
|
|
||||||
if (pvData != NULL) {
|
|
||||||
return pvData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SetLastError(ERROR_MOD_NOT_FOUND);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI DetourFreePayload(_In_ PVOID pvData)
|
|
||||||
{
|
|
||||||
BOOL fSucceeded = FALSE;
|
|
||||||
|
|
||||||
// If you have any doubts about the following code, please refer to the comments in DetourCopyPayloadToProcess.
|
|
||||||
HMODULE hModule = DetourGetContainingModule(pvData);
|
|
||||||
DETOUR_ASSERT(hModule != NULL);
|
|
||||||
if (hModule != NULL) {
|
|
||||||
fSucceeded = VirtualFree(hModule, 0, MEM_RELEASE);
|
|
||||||
DETOUR_ASSERT(fSucceeded);
|
|
||||||
if (fSucceeded) {
|
|
||||||
hModule = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fSucceeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData,
|
|
||||||
_In_ DWORD cbData)
|
|
||||||
{
|
|
||||||
PDETOUR_EXE_RESTORE pder = (PDETOUR_EXE_RESTORE)pvData;
|
|
||||||
|
|
||||||
if (pder->cb != sizeof(*pder) || pder->cb > cbData) {
|
|
||||||
SetLastError(ERROR_BAD_EXE_FORMAT);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD dwPermIdh = ~0u;
|
|
||||||
DWORD dwPermInh = ~0u;
|
|
||||||
DWORD dwPermClr = ~0u;
|
|
||||||
DWORD dwIgnore;
|
|
||||||
BOOL fSucceeded = FALSE;
|
|
||||||
BOOL fUpdated32To64 = FALSE;
|
|
||||||
|
|
||||||
if (pder->pclr != NULL && pder->clr.Flags != ((PDETOUR_CLR_HEADER)pder->pclr)->Flags) {
|
|
||||||
// If we had to promote the 32/64-bit agnostic IL to 64-bit, we can't restore
|
|
||||||
// that.
|
|
||||||
fUpdated32To64 = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DetourVirtualProtectSameExecute(pder->pidh, pder->cbidh,
|
|
||||||
PAGE_EXECUTE_READWRITE, &dwPermIdh)) {
|
|
||||||
if (DetourVirtualProtectSameExecute(pder->pinh, pder->cbinh,
|
|
||||||
PAGE_EXECUTE_READWRITE, &dwPermInh)) {
|
|
||||||
|
|
||||||
CopyMemory(pder->pidh, &pder->idh, pder->cbidh);
|
|
||||||
CopyMemory(pder->pinh, &pder->inh, pder->cbinh);
|
|
||||||
|
|
||||||
if (pder->pclr != NULL && !fUpdated32To64) {
|
|
||||||
if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr,
|
|
||||||
PAGE_EXECUTE_READWRITE, &dwPermClr)) {
|
|
||||||
CopyMemory(pder->pclr, &pder->clr, pder->cbclr);
|
|
||||||
VirtualProtect(pder->pclr, pder->cbclr, dwPermClr, &dwIgnore);
|
|
||||||
fSucceeded = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fSucceeded = TRUE;
|
|
||||||
}
|
|
||||||
VirtualProtect(pder->pinh, pder->cbinh, dwPermInh, &dwIgnore);
|
|
||||||
}
|
|
||||||
VirtualProtect(pder->pidh, pder->cbidh, dwPermIdh, &dwIgnore);
|
|
||||||
}
|
|
||||||
// Delete the payload after successful recovery to prevent repeated restore
|
|
||||||
if (fSucceeded) {
|
|
||||||
DetourFreePayload(pder);
|
|
||||||
pder = NULL;
|
|
||||||
}
|
|
||||||
return fSucceeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI DetourRestoreAfterWith()
|
|
||||||
{
|
|
||||||
PVOID pvData;
|
|
||||||
DWORD cbData;
|
|
||||||
|
|
||||||
pvData = DetourFindPayloadEx(DETOUR_EXE_RESTORE_GUID, &cbData);
|
|
||||||
|
|
||||||
if (pvData != NULL && cbData != 0) {
|
|
||||||
return DetourRestoreAfterWithEx(pvData, cbData);
|
|
||||||
}
|
|
||||||
SetLastError(ERROR_MOD_NOT_FOUND);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// End of File
|
|
||||||
@@ -1,333 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Add DLLs to a module import table (uimports.cpp of detours.lib)
|
|
||||||
//
|
|
||||||
// Microsoft Research Detours Package, Version 4.0.1
|
|
||||||
//
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
//
|
|
||||||
// Note that this file is included into creatwth.cpp one or more times
|
|
||||||
// (once for each supported module format).
|
|
||||||
//
|
|
||||||
|
|
||||||
#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH
|
|
||||||
#error detours.h version mismatch
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// UpdateImports32 aka UpdateImports64
|
|
||||||
static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess,
|
|
||||||
HMODULE hModule,
|
|
||||||
__in_ecount(nDlls) LPCSTR *plpDlls,
|
|
||||||
DWORD nDlls)
|
|
||||||
{
|
|
||||||
BOOL fSucceeded = FALSE;
|
|
||||||
DWORD cbNew = 0;
|
|
||||||
|
|
||||||
BYTE * pbNew = NULL;
|
|
||||||
DWORD i;
|
|
||||||
SIZE_T cbRead;
|
|
||||||
DWORD n;
|
|
||||||
|
|
||||||
PBYTE pbModule = (PBYTE)hModule;
|
|
||||||
|
|
||||||
IMAGE_DOS_HEADER idh;
|
|
||||||
ZeroMemory(&idh, sizeof(idh));
|
|
||||||
if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), &cbRead)
|
|
||||||
|| cbRead < sizeof(idh)) {
|
|
||||||
|
|
||||||
DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %lu\n",
|
|
||||||
pbModule, pbModule + sizeof(idh), GetLastError()));
|
|
||||||
|
|
||||||
finish:
|
|
||||||
if (pbNew != NULL) {
|
|
||||||
delete[] pbNew;
|
|
||||||
pbNew = NULL;
|
|
||||||
}
|
|
||||||
return fSucceeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMAGE_NT_HEADERS_XX inh;
|
|
||||||
ZeroMemory(&inh, sizeof(inh));
|
|
||||||
|
|
||||||
if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), &cbRead)
|
|
||||||
|| cbRead < sizeof(inh)) {
|
|
||||||
DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %lu\n",
|
|
||||||
pbModule + idh.e_lfanew,
|
|
||||||
pbModule + idh.e_lfanew + sizeof(inh),
|
|
||||||
GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inh.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC_XX) {
|
|
||||||
DETOUR_TRACE(("Wrong size image (%04x != %04x).\n",
|
|
||||||
inh.OptionalHeader.Magic, IMAGE_NT_OPTIONAL_HDR_MAGIC_XX));
|
|
||||||
SetLastError(ERROR_INVALID_BLOCK);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zero out the bound table so loader doesn't use it instead of our new table.
|
|
||||||
inh.BOUND_DIRECTORY.VirtualAddress = 0;
|
|
||||||
inh.BOUND_DIRECTORY.Size = 0;
|
|
||||||
|
|
||||||
// Find the size of the mapped file.
|
|
||||||
DWORD dwSec = idh.e_lfanew +
|
|
||||||
FIELD_OFFSET(IMAGE_NT_HEADERS_XX, OptionalHeader) +
|
|
||||||
inh.FileHeader.SizeOfOptionalHeader;
|
|
||||||
|
|
||||||
for (i = 0; i < inh.FileHeader.NumberOfSections; i++) {
|
|
||||||
IMAGE_SECTION_HEADER ish;
|
|
||||||
ZeroMemory(&ish, sizeof(ish));
|
|
||||||
|
|
||||||
if (!ReadProcessMemory(hProcess, pbModule + dwSec + sizeof(ish) * i, &ish,
|
|
||||||
sizeof(ish), &cbRead)
|
|
||||||
|| cbRead < sizeof(ish)) {
|
|
||||||
|
|
||||||
DETOUR_TRACE(("ReadProcessMemory(ish@%p..%p) failed: %lu\n",
|
|
||||||
pbModule + dwSec + sizeof(ish) * i,
|
|
||||||
pbModule + dwSec + sizeof(ish) * (i + 1),
|
|
||||||
GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
DETOUR_TRACE(("ish[%lu] : va=%08lx sr=%lu\n", i, ish.VirtualAddress, ish.SizeOfRawData));
|
|
||||||
|
|
||||||
// If the linker didn't suggest an IAT in the data directories, the
|
|
||||||
// loader will look for the section of the import directory to be used
|
|
||||||
// for this instead. Since we put out new IMPORT_DIRECTORY outside any
|
|
||||||
// section boundary, the loader will not find it. So we provide one
|
|
||||||
// explicitly to avoid the search.
|
|
||||||
//
|
|
||||||
if (inh.IAT_DIRECTORY.VirtualAddress == 0 &&
|
|
||||||
inh.IMPORT_DIRECTORY.VirtualAddress >= ish.VirtualAddress &&
|
|
||||||
inh.IMPORT_DIRECTORY.VirtualAddress < ish.VirtualAddress + ish.SizeOfRawData) {
|
|
||||||
|
|
||||||
inh.IAT_DIRECTORY.VirtualAddress = ish.VirtualAddress;
|
|
||||||
inh.IAT_DIRECTORY.Size = ish.SizeOfRawData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inh.IMPORT_DIRECTORY.VirtualAddress != 0 && inh.IMPORT_DIRECTORY.Size == 0) {
|
|
||||||
|
|
||||||
// Don't worry about changing the PE file,
|
|
||||||
// because the load information of the original PE header has been saved and will be restored.
|
|
||||||
// The change here is just for the following code to work normally
|
|
||||||
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR pImageImport = (PIMAGE_IMPORT_DESCRIPTOR)(pbModule + inh.IMPORT_DIRECTORY.VirtualAddress);
|
|
||||||
|
|
||||||
do {
|
|
||||||
IMAGE_IMPORT_DESCRIPTOR ImageImport;
|
|
||||||
if (!ReadProcessMemory(hProcess, pImageImport, &ImageImport, sizeof(ImageImport), NULL)) {
|
|
||||||
DETOUR_TRACE(("ReadProcessMemory failed: %lu\n", GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
inh.IMPORT_DIRECTORY.Size += sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
|
||||||
if (!ImageImport.Name) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++pImageImport;
|
|
||||||
} while (TRUE);
|
|
||||||
|
|
||||||
DWORD dwLastError = GetLastError();
|
|
||||||
OutputDebugString(TEXT("[This PE file has an import table, but the import table size is marked as 0. This is an error.")
|
|
||||||
TEXT("If it is not repaired, the launched program will not work properly, Detours has automatically repaired its import table size for you! ! !]\r\n"));
|
|
||||||
if (GetLastError() != dwLastError) {
|
|
||||||
SetLastError(dwLastError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DETOUR_TRACE((" Imports: %p..%p\n",
|
|
||||||
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,
|
|
||||||
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress +
|
|
||||||
inh.IMPORT_DIRECTORY.Size));
|
|
||||||
|
|
||||||
// Calculate new import directory size. Note that since inh is from another
|
|
||||||
// process, inh could have been corrupted. We need to protect against
|
|
||||||
// integer overflow in allocation calculations.
|
|
||||||
DWORD nOldDlls = inh.IMPORT_DIRECTORY.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
|
||||||
DWORD obRem;
|
|
||||||
if (DWordMult(sizeof(IMAGE_IMPORT_DESCRIPTOR), nDlls, &obRem) != S_OK) {
|
|
||||||
DETOUR_TRACE(("too many new DLLs.\n"));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
DWORD obOld;
|
|
||||||
if (DWordAdd(obRem, sizeof(IMAGE_IMPORT_DESCRIPTOR) * nOldDlls, &obOld) != S_OK) {
|
|
||||||
DETOUR_TRACE(("DLL entries overflow.\n"));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
DWORD obTab = PadToDwordPtr(obOld);
|
|
||||||
// Check for integer overflow.
|
|
||||||
if (obTab < obOld) {
|
|
||||||
DETOUR_TRACE(("DLL entries padding overflow.\n"));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
DWORD stSize;
|
|
||||||
if (DWordMult(sizeof(DWORD_XX) * 4, nDlls, &stSize) != S_OK) {
|
|
||||||
DETOUR_TRACE(("String table overflow.\n"));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
DWORD obDll;
|
|
||||||
if (DWordAdd(obTab, stSize, &obDll) != S_OK) {
|
|
||||||
DETOUR_TRACE(("Import table size overflow\n"));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
DWORD obStr = obDll;
|
|
||||||
cbNew = obStr;
|
|
||||||
for (n = 0; n < nDlls; n++) {
|
|
||||||
if (DWordAdd(cbNew, PadToDword((DWORD)strlen(plpDlls[n]) + 1), &cbNew) != S_OK) {
|
|
||||||
DETOUR_TRACE(("Overflow adding string table entry\n"));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pbNew = new BYTE [cbNew];
|
|
||||||
if (pbNew == NULL) {
|
|
||||||
DETOUR_TRACE(("new BYTE [cbNew] failed.\n"));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
ZeroMemory(pbNew, cbNew);
|
|
||||||
|
|
||||||
PBYTE pbBase = pbModule;
|
|
||||||
PBYTE pbNext = pbBase
|
|
||||||
+ inh.OptionalHeader.BaseOfCode
|
|
||||||
+ inh.OptionalHeader.SizeOfCode
|
|
||||||
+ inh.OptionalHeader.SizeOfInitializedData
|
|
||||||
+ inh.OptionalHeader.SizeOfUninitializedData;
|
|
||||||
if (pbBase < pbNext) {
|
|
||||||
pbBase = pbNext;
|
|
||||||
}
|
|
||||||
DETOUR_TRACE(("pbBase = %p\n", pbBase));
|
|
||||||
|
|
||||||
PBYTE pbNewIid = FindAndAllocateNearBase(hProcess, pbModule, pbBase, cbNew);
|
|
||||||
if (pbNewIid == NULL) {
|
|
||||||
DETOUR_TRACE(("FindAndAllocateNearBase failed.\n"));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)pbNew;
|
|
||||||
IMAGE_THUNK_DATAXX *pt = NULL;
|
|
||||||
|
|
||||||
DWORD obBase = (DWORD)(pbNewIid - pbModule);
|
|
||||||
DWORD dwProtect = 0;
|
|
||||||
|
|
||||||
if (inh.IMPORT_DIRECTORY.VirtualAddress != 0) {
|
|
||||||
// Read the old import directory if it exists.
|
|
||||||
DETOUR_TRACE(("IMPORT_DIRECTORY perms=%lx\n", dwProtect));
|
|
||||||
|
|
||||||
if (!ReadProcessMemory(hProcess,
|
|
||||||
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,
|
|
||||||
&piid[nDlls],
|
|
||||||
nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR), &cbRead)
|
|
||||||
|| cbRead < nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR)) {
|
|
||||||
|
|
||||||
DETOUR_TRACE(("ReadProcessMemory(imports) failed: %lu\n", GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (n = 0; n < nDlls; n++) {
|
|
||||||
HRESULT hrRet = StringCchCopyA((char*)pbNew + obStr, cbNew - obStr, plpDlls[n]);
|
|
||||||
if (FAILED(hrRet)) {
|
|
||||||
DETOUR_TRACE(("StringCchCopyA failed: %08lx\n", hrRet));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
// After copying the string, we patch up the size "??" bits if any.
|
|
||||||
hrRet = ReplaceOptionalSizeA((char*)pbNew + obStr,
|
|
||||||
cbNew - obStr,
|
|
||||||
DETOURS_STRINGIFY(DETOURS_BITS_XX));
|
|
||||||
if (FAILED(hrRet)) {
|
|
||||||
DETOUR_TRACE(("ReplaceOptionalSizeA failed: %08lx\n", hrRet));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD nOffset = obTab + (sizeof(IMAGE_THUNK_DATAXX) * (4 * n));
|
|
||||||
piid[n].OriginalFirstThunk = obBase + nOffset;
|
|
||||||
|
|
||||||
// We need 2 thunks for the import table and 2 thunks for the IAT.
|
|
||||||
// One for an ordinal import and one to mark the end of the list.
|
|
||||||
pt = ((IMAGE_THUNK_DATAXX*)(pbNew + nOffset));
|
|
||||||
pt[0].u1.Ordinal = IMAGE_ORDINAL_FLAG_XX + 1;
|
|
||||||
pt[1].u1.Ordinal = 0;
|
|
||||||
|
|
||||||
nOffset = obTab + (sizeof(IMAGE_THUNK_DATAXX) * ((4 * n) + 2));
|
|
||||||
piid[n].FirstThunk = obBase + nOffset;
|
|
||||||
pt = ((IMAGE_THUNK_DATAXX*)(pbNew + nOffset));
|
|
||||||
pt[0].u1.Ordinal = IMAGE_ORDINAL_FLAG_XX + 1;
|
|
||||||
pt[1].u1.Ordinal = 0;
|
|
||||||
piid[n].TimeDateStamp = 0;
|
|
||||||
piid[n].ForwarderChain = 0;
|
|
||||||
piid[n].Name = obBase + obStr;
|
|
||||||
|
|
||||||
obStr += PadToDword((DWORD)strlen(plpDlls[n]) + 1);
|
|
||||||
}
|
|
||||||
_Analysis_assume_(obStr <= cbNew);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (i = 0; i < nDlls + nOldDlls; i++) {
|
|
||||||
DETOUR_TRACE(("%8d. Look=%08x Time=%08x Fore=%08x Name=%08x Addr=%08x\n",
|
|
||||||
i,
|
|
||||||
piid[i].OriginalFirstThunk,
|
|
||||||
piid[i].TimeDateStamp,
|
|
||||||
piid[i].ForwarderChain,
|
|
||||||
piid[i].Name,
|
|
||||||
piid[i].FirstThunk));
|
|
||||||
if (piid[i].OriginalFirstThunk == 0 && piid[i].FirstThunk == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!WriteProcessMemory(hProcess, pbNewIid, pbNew, obStr, NULL)) {
|
|
||||||
DETOUR_TRACE(("WriteProcessMemory(iid) failed: %lu\n", GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
DETOUR_TRACE(("obBaseBef = %08lx..%08lx\n",
|
|
||||||
inh.IMPORT_DIRECTORY.VirtualAddress,
|
|
||||||
inh.IMPORT_DIRECTORY.VirtualAddress + inh.IMPORT_DIRECTORY.Size));
|
|
||||||
DETOUR_TRACE(("obBaseAft = %08lx..%08lx\n", obBase, obBase + obStr));
|
|
||||||
|
|
||||||
// In this case the file didn't have an import directory in first place,
|
|
||||||
// so we couldn't fix the missing IAT above. We still need to explicitly
|
|
||||||
// provide an IAT to prevent to loader from looking for one.
|
|
||||||
//
|
|
||||||
if (inh.IAT_DIRECTORY.VirtualAddress == 0) {
|
|
||||||
inh.IAT_DIRECTORY.VirtualAddress = obBase;
|
|
||||||
inh.IAT_DIRECTORY.Size = cbNew;
|
|
||||||
}
|
|
||||||
|
|
||||||
inh.IMPORT_DIRECTORY.VirtualAddress = obBase;
|
|
||||||
inh.IMPORT_DIRECTORY.Size = cbNew;
|
|
||||||
|
|
||||||
/////////////////////// Update the NT header for the new import directory.
|
|
||||||
//
|
|
||||||
if (!DetourVirtualProtectSameExecuteEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,
|
|
||||||
PAGE_EXECUTE_READWRITE, &dwProtect)) {
|
|
||||||
DETOUR_TRACE(("VirtualProtectEx(inh) write failed: %lu\n", GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
inh.OptionalHeader.CheckSum = 0;
|
|
||||||
|
|
||||||
if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {
|
|
||||||
DETOUR_TRACE(("WriteProcessMemory(idh) failed: %lu\n", GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
DETOUR_TRACE(("WriteProcessMemory(idh:%p..%p)\n", pbModule, pbModule + sizeof(idh)));
|
|
||||||
|
|
||||||
if (!WriteProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) {
|
|
||||||
DETOUR_TRACE(("WriteProcessMemory(inh) failed: %lu\n", GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
DETOUR_TRACE(("WriteProcessMemory(inh:%p..%p)\n",
|
|
||||||
pbModule + idh.e_lfanew,
|
|
||||||
pbModule + idh.e_lfanew + sizeof(inh)));
|
|
||||||
|
|
||||||
if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,
|
|
||||||
dwProtect, &dwProtect)) {
|
|
||||||
DETOUR_TRACE(("VirtualProtectEx(idh) restore failed: %lu\n", GetLastError()));
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
fSucceeded = TRUE;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
PROJECT: NanaZip
|
|
||||||
FILE: NanaZip.Shared.Detours.props
|
|
||||||
PURPOSE: MSBuild Properties for NanaZip.Shared.Detours
|
|
||||||
|
|
||||||
LICENSE: The MIT License
|
|
||||||
|
|
||||||
MAINTAINER: MouriNaruto (Kenji.Mouri@outlook.com)
|
|
||||||
-->
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup>
|
|
||||||
<IncludePath>$(MSBuildThisFileDirectory)Detours\;$(IncludePath)</IncludePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(OutDir)NanaZip.Shared.Detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="$(MSBuildThisFileDirectory)NanaZip.Shared.Detours.vcxproj">
|
|
||||||
<Project>{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}</ProjectGuid>
|
|
||||||
<RootNamespace>NanaZip.Shared.Detours</RootNamespace>
|
|
||||||
<MileProjectType>StaticLibrary</MileProjectType>
|
|
||||||
<MileProjectEnableVCLTLSupport>true</MileProjectEnableVCLTLSupport>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="..\Mile.Project.Windows\Mile.Project.Platform.x86.props" />
|
|
||||||
<Import Project="..\Mile.Project.Windows\Mile.Project.Platform.x64.props" />
|
|
||||||
<Import Project="..\Mile.Project.Windows\Mile.Project.Platform.ARM64.props" />
|
|
||||||
<Import Project="..\Mile.Project.Windows\Mile.Project.Cpp.Default.props" />
|
|
||||||
<Import Project="..\Mile.Project.Windows\Mile.Project.Cpp.props" />
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<EnableEnhancedInstructionSet Condition="'$(Platform)'=='Win32'">NoExtensions</EnableEnhancedInstructionSet>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="Detours\creatwth.cpp" />
|
|
||||||
<ClCompile Include="Detours\detours.cpp" />
|
|
||||||
<ClCompile Include="Detours\disasm.cpp" />
|
|
||||||
<ClCompile Include="Detours\disolarm.cpp" />
|
|
||||||
<ClCompile Include="Detours\disolarm64.cpp" />
|
|
||||||
<ClCompile Include="Detours\disolia64.cpp" />
|
|
||||||
<ClCompile Include="Detours\disolx64.cpp" />
|
|
||||||
<ClCompile Include="Detours\disolx86.cpp" />
|
|
||||||
<ClCompile Include="Detours\image.cpp" />
|
|
||||||
<ClCompile Include="Detours\modules.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="Detours\detours.h" />
|
|
||||||
<ClInclude Include="Detours\detver.h" />
|
|
||||||
<ClInclude Include="Detours\uimports.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="NanaZip.Shared.Detours.props" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="..\Mile.Project.Windows\Mile.Project.Cpp.targets" />
|
|
||||||
</Project>
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Detours">
|
|
||||||
<UniqueIdentifier>{c9ddac52-8c89-4995-87a5-8a9af1db06f5}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="Detours\creatwth.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\detours.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\disasm.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\disolarm.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\disolarm64.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\disolia64.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\disolx64.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\disolx86.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\image.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Detours\modules.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="Detours\detours.h">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Detours\detver.h">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Detours\uimports.cpp">
|
|
||||||
<Filter>Detours</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="NanaZip.Shared.Detours.props" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
15
NanaZip.sln
15
NanaZip.sln
@@ -47,8 +47,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Classic", "Classic", "{6666
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaZip.Codecs", "NanaZip.Codecs\NanaZip.Codecs.vcxproj", "{89B81A5B-FF0D-4193-9CB1-738692775DD2}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaZip.Codecs", "NanaZip.Codecs\NanaZip.Codecs.vcxproj", "{89B81A5B-FF0D-4193-9CB1-738692775DD2}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaZip.Shared.Detours", "NanaZip.Shared\NanaZip.Shared.Detours.vcxproj", "{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM64 = Debug|ARM64
|
Debug|ARM64 = Debug|ARM64
|
||||||
@@ -241,18 +239,6 @@ Global
|
|||||||
{89B81A5B-FF0D-4193-9CB1-738692775DD2}.Release|x64.Build.0 = Release|x64
|
{89B81A5B-FF0D-4193-9CB1-738692775DD2}.Release|x64.Build.0 = Release|x64
|
||||||
{89B81A5B-FF0D-4193-9CB1-738692775DD2}.Release|x86.ActiveCfg = Release|Win32
|
{89B81A5B-FF0D-4193-9CB1-738692775DD2}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{89B81A5B-FF0D-4193-9CB1-738692775DD2}.Release|x86.Build.0 = Release|Win32
|
{89B81A5B-FF0D-4193-9CB1-738692775DD2}.Release|x86.Build.0 = Release|Win32
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Debug|ARM64.Build.0 = Debug|ARM64
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Release|ARM64.ActiveCfg = Release|ARM64
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Release|ARM64.Build.0 = Release|ARM64
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Release|x64.Build.0 = Release|x64
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8}.Release|x86.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -276,7 +262,6 @@ Global
|
|||||||
{F4511F91-B0EB-41B4-99D6-AEB48169132B} = {B954CA12-11FE-45D8-A4D2-562560E1CD4D}
|
{F4511F91-B0EB-41B4-99D6-AEB48169132B} = {B954CA12-11FE-45D8-A4D2-562560E1CD4D}
|
||||||
{6666CFC3-1986-469A-9266-0FD8C2674DF6} = {FB9122A4-25AA-405E-9EE1-886274614847}
|
{6666CFC3-1986-469A-9266-0FD8C2674DF6} = {FB9122A4-25AA-405E-9EE1-886274614847}
|
||||||
{89B81A5B-FF0D-4193-9CB1-738692775DD2} = {94A1E11C-B722-4BAE-9B12-1495F5EF3CC9}
|
{89B81A5B-FF0D-4193-9CB1-738692775DD2} = {94A1E11C-B722-4BAE-9B12-1495F5EF3CC9}
|
||||||
{8303FDA0-1A77-4BA9-B228-CF8CA08042E8} = {51AA7444-A07F-429B-89C4-DFF4A6F10C99}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {DE2C16C4-5306-4103-9C2A-749DC32B5CA6}
|
SolutionGuid = {DE2C16C4-5306-4103-9C2A-749DC32B5CA6}
|
||||||
|
|||||||
Reference in New Issue
Block a user