From 1c099356fd2b1b4a8f5ea55eead8bc777bd01cb0 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Mon, 10 Feb 2020 03:18:23 +0800 Subject: [PATCH 01/21] =?UTF-8?q?=E5=90=88=E5=B9=B63.0=20Build=5F343?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E4=BF=AE=E6=94=B9=EF=BC=8C=E4=BD=86=E6=98=AF?= =?UTF-8?q?detours.cpp=E4=B8=ADARM=E5=8F=8AARM64=E4=B8=ADdetour=5Ffind=5Fj?= =?UTF-8?q?mp=5Fbounds=E5=87=BD=E6=95=B0=E7=9A=84=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=9B=AE=E5=89=8D=E5=B9=B6=E6=9C=AA=E5=90=88=E5=B9=B6=EF=BC=8C?= =?UTF-8?q?=E5=9B=A0=E4=B8=BA=E7=9B=AE=E5=89=8D=E6=97=A0=E5=AE=9E=E9=AA=8C?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E6=97=A0=E6=B3=95=E9=AA=8C=E8=AF=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=9A=84=E5=8F=AF=E9=9D=A0=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CREDITS.TXT | 3 +++ src/modules.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CREDITS.TXT b/CREDITS.TXT index a1226767..275b5f0a 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -3,6 +3,9 @@ The following individuals have helped identify specific bugs and improvements in Detours. The entire Detours community has benefited from their help. ============================================================================== +* Jay Krell: Identified error in DetourFindPayload that caused a + incorrect failure when pcbData is NULL. (Build_342) + * Jay Krell: Identified issue with VirtualSize == 0 files created in NT 3.1 images. (Build_339) diff --git a/src/modules.cpp b/src/modules.cpp index ade78c97..a797121c 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -803,9 +803,9 @@ PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, if (pcbData) { *pcbData = pSection->cbBytes - sizeof(*pSection); - SetLastError(NO_ERROR); - return (PBYTE)(pSection + 1); } + SetLastError(NO_ERROR); + return (PBYTE)(pSection + 1); } pbData = (PBYTE)pSection + pSection->cbBytes; From 7a6f33019f1361ded1b6f712278cccb4d0a5fc63 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Mon, 10 Feb 2020 03:28:04 +0800 Subject: [PATCH 02/21] =?UTF-8?q?=E5=8A=A0=E5=85=A5VS=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vc/Detours.sln | 31 ++++++ vc/Detours.vcxproj | 188 +++++++++++++++++++++++++++++++++++++ vc/Detours.vcxproj.filters | 182 +++++++++++++++++++++++++++++++++++ 3 files changed, 401 insertions(+) create mode 100644 vc/Detours.sln create mode 100644 vc/Detours.vcxproj create mode 100644 vc/Detours.vcxproj.filters diff --git a/vc/Detours.sln b/vc/Detours.sln new file mode 100644 index 00000000..8e894494 --- /dev/null +++ b/vc/Detours.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1000 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Detours", "Detours.vcxproj", "{37489709-8054-4903-9C49-A79846049FC9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DebugMDd|x64 = DebugMDd|x64 + DebugMDd|x86 = DebugMDd|x86 + ReleaseMD|x64 = ReleaseMD|x64 + ReleaseMD|x86 = ReleaseMD|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {37489709-8054-4903-9C49-A79846049FC9}.DebugMDd|x64.ActiveCfg = DebugMDd|x64 + {37489709-8054-4903-9C49-A79846049FC9}.DebugMDd|x64.Build.0 = DebugMDd|x64 + {37489709-8054-4903-9C49-A79846049FC9}.DebugMDd|x86.ActiveCfg = DebugMDd|Win32 + {37489709-8054-4903-9C49-A79846049FC9}.DebugMDd|x86.Build.0 = DebugMDd|Win32 + {37489709-8054-4903-9C49-A79846049FC9}.ReleaseMD|x64.ActiveCfg = ReleaseMD|x64 + {37489709-8054-4903-9C49-A79846049FC9}.ReleaseMD|x64.Build.0 = ReleaseMD|x64 + {37489709-8054-4903-9C49-A79846049FC9}.ReleaseMD|x86.ActiveCfg = ReleaseMD|Win32 + {37489709-8054-4903-9C49-A79846049FC9}.ReleaseMD|x86.Build.0 = ReleaseMD|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1E71C644-7F30-4025-B1DF-6A4F07A2EDB3} + EndGlobalSection +EndGlobal diff --git a/vc/Detours.vcxproj b/vc/Detours.vcxproj new file mode 100644 index 00000000..4c36d346 --- /dev/null +++ b/vc/Detours.vcxproj @@ -0,0 +1,188 @@ + + + + + DebugMDd + Win32 + + + ReleaseMD + Win32 + + + DebugMDd + x64 + + + ReleaseMD + x64 + + + + 15.0 + {37489709-8054-4903-9C49-A79846049FC9} + Win32Proj + Detours + 10.0.17134.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + Unicode + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + Unicode + + + + + + + + + + + + + + + + + + + + ..\lib\ + $(ProjectName)x64d + + + ..\lib\ + $(ProjectName)x64 + + + ..\lib\ + $(ProjectName)x86d + $(Platform)\$(Configuration)\ + + + ..\lib\ + $(ProjectName)x86 + $(Platform)\$(Configuration)\ + + + + Level4 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + true + ProgramDatabase + $(OutputPath)$(TargetName).pdb + + + Windows + true + + + mkdir ..\include +xcopy /I /Y /D /R /K "..\src\*.h" "..\include" + + + + + Level4 + Disabled + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + true + ProgramDatabase + + + $(OutputPath)$(TargetName).pdb + + + Windows + true + + + mkdir ..\include +xcopy /I /Y /D /R /K "..\src\*.h" "..\include" + + + + + Level4 + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + $(OutputPath)$(TargetName).pdb + + + Windows + true + true + true + + + mkdir ..\include +xcopy /I /Y /D /R /K "..\src\*.h" "..\include" + + + + + Level4 + MaxSpeed + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + + + $(OutputPath)$(TargetName).pdb + + + Windows + true + true + true + + + mkdir ..\include +xcopy /I /Y /D /R /K "..\src\*.h" "..\include" + + + + + + + + + + true + + + + + + \ No newline at end of file diff --git a/vc/Detours.vcxproj.filters b/vc/Detours.vcxproj.filters new file mode 100644 index 00000000..a7abda9b --- /dev/null +++ b/vc/Detours.vcxproj.filters @@ -0,0 +1,182 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file From 167f7f0b4114303ccac51a3d281e28471c887fe4 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Mon, 10 Feb 2020 03:30:10 +0800 Subject: [PATCH 03/21] =?UTF-8?q?git=E5=BF=BD=E7=95=A5=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 1207e230..8f61f392 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,7 @@ include/ obj.* *.ipdb *.iobj +*.tlog +*.log +*.obj +*.user From 10247b1201311914b8300b97544217c892165325 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Mon, 10 Feb 2020 04:07:38 +0800 Subject: [PATCH 04/21] =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=88=91=E4=BB=AC?= =?UTF-8?q?=E7=9B=AE=E5=89=8D=E6=9C=80=E6=96=B0=E7=9A=843.0=20Build=5F343?= =?UTF-8?q?=5Fsrc=5Fmod=E4=B8=AD=E7=9A=84=E4=BF=AE=E6=94=B9=E5=88=B0?= =?UTF-8?q?=E7=9B=AE=E5=89=8D=E5=AE=98=E6=96=B9=E6=9C=80=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/creatwth.cpp | 104 ++++++++++++++++++++++++++++++++++++++--------- src/modules.cpp | 4 +- src/uimports.cpp | 28 +++++++++++++ 3 files changed, 116 insertions(+), 20 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 300bb2c8..b6eead7d 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -408,7 +408,8 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, // inh64.Signature = inh32.Signature; inh64.FileHeader = inh32.FileHeader; - inh64.FileHeader.Machine = machine; + inh64.FileHeader.Machine = machine;//͸ֵΪinh32.FileHeader.MachineĻwin7µPEˣ + //ᱨSTATUS_INVALID_IMAGE_FORMATҪdepбԭPEͷеMachineֵinh32.FileHeader.Machineֵ inh64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64); inh64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; @@ -476,6 +477,10 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, if (!RecordExeRestore(hProcess, hModule, der)) { return FALSE; } + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //RecordExeRestore֮depб64λPEͷˣҪָderбPEͷMachineֵʹ.NETPEظCLRļ + der.inh.FileHeader.Machine = inh32.FileHeader.Machine; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Remove the import table. if (der.pclr != NULL && (der.clr.Flags & 1)) { @@ -499,6 +504,50 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, } #endif // DETOURS_64BIT +namespace Detour +{ +#ifndef PROCESSOR_ARCHITECTURE_ARM64 +#define PROCESSOR_ARCHITECTURE_ARM64 12 +#endif + BOOL Is64BitOS() + { + BOOL bRet = FALSE; + VOID(WINAPI * _GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall *)(LPSYSTEM_INFO))GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); + if (!_GetNativeSystemInfo) + { + return bRet; + } + + SYSTEM_INFO si; + _GetNativeSystemInfo(&si); + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64 || + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA64) + { + bRet = TRUE; + } + return bRet; + }; + //̾hProcessҪPROCESS_QUERY_INFORMATIONPROCESS_QUERY_LIMITED_INFORMATIONȨ + BOOL Is64BitProcess(HANDLE hProcess) + { + BOOL bRet = FALSE; + if (hProcess) + { + if (Is64BitOS()) + { + static BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, + OUT PBOOL Wow64Process) + = (BOOL(__stdcall *)(HANDLE, PBOOL))GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "IsWow64Process"); + BOOL bX86ProcessRunAt64BitOS; + if (_IsWow64Process && _IsWow64Process(hProcess, &bX86ProcessRunAt64BitOS) && bX86ProcessRunAt64BitOS == FALSE) + { + bRet = TRUE; + } + } + } + return bRet; + } +} ////////////////////////////////////////////////////////////////////////////// // BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, @@ -548,19 +597,26 @@ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, return FALSE; } - if (!bHas32BitExe) { - bIs32BitProcess = FALSE; - } - else if (!bHas64BitDll) { - bIs32BitProcess = TRUE; - } - else { - if (!IsWow64Process(hProcess, &bIs32BitProcess)) { - return FALSE; - } - } - - DETOUR_TRACE((" 32BitExe=%d 32BitProcess\n", bHas32BitExe, bIs32BitProcess)); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //ע͵Ĵ + //Ĵ벻ȷжĽǷ32λ + //if (!bHas32BitExe) { + // bIs32BitProcess = FALSE; + //} + //else if (!bHas64BitDll) { + // bIs32BitProcess = TRUE; + //} + //else { + // if (!IsWow64Process(hProcess, &bIs32BitProcess)) { + // return FALSE; + // } + //} + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //ӵĴ + bIs32BitProcess = !Detour::Is64BitProcess(hProcess); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + DETOUR_TRACE((" 32BitExe=%d 32BitProcess=%d\n", bHas32BitExe, bIs32BitProcess)); return DetourUpdateProcessWithDllEx(hProcess, hModule, @@ -594,7 +650,7 @@ BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, bIs32BitExe = TRUE; } - DETOUR_TRACE((" 32BitExe=%d 32BitProcess\n", bIs32BitExe, bIs32BitProcess)); + DETOUR_TRACE((" 32BitExe=%d 32BitProcess=%d\n", bIs32BitExe, bIs32BitProcess)); if (hModule == NULL) { SetLastError(ERROR_INVALID_OPERATION); @@ -678,6 +734,8 @@ BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, DETOUR_CLR_HEADER clr; CopyMemory(&clr, &der.clr, sizeof(clr)); clr.Flags &= 0xfffffffe; // Clear the IL_ONLY flag. + //IL_ONLY־֮ɽ̺󣬻ָIATҪָIL_ONLY־ + //IL_ONLY־޷̣Ϊ滻ԭIATΪǵDLLIAT DWORD dwProtect; if (!DetourVirtualProtectSameExecuteEx(hProcess, der.pclr, sizeof(clr), PAGE_READWRITE, &dwProtect)) { @@ -1172,8 +1230,11 @@ BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, goto Cleanup; } - hr = StringCchPrintfA(szCommand, ARRAYSIZE(szCommand), - "rundll32.exe \"%hs\",#1", &helper->rDlls[0]); + //hr = StringCchPrintfA(szCommand, ARRAYSIZE(szCommand), + // "rundll32.exe \"%hs\",#1", &helper->rDlls[0]); + //fix for chinese + hr = StringCchPrintfA(szCommand, ARRAYSIZE(szCommand), + "rundll32.exe \"%s\",#1", &helper->rDlls[0]); if (!SUCCEEDED(hr)) { goto Cleanup; } @@ -1268,8 +1329,13 @@ BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, goto Cleanup; } - hr = StringCchPrintfW(szCommand, ARRAYSIZE(szCommand), - L"rundll32.exe \"%hs\",#1", &helper->rDlls[0]); + //hr = StringCchPrintfW(szCommand, ARRAYSIZE(szCommand), + // L"rundll32.exe \"%hs\",#1", &helper->rDlls[0]); + //fix for chinese + WCHAR szDllName[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, &helper->rDlls[0], -1, szDllName, ARRAYSIZE(szDllName)); + hr = StringCchPrintfW(szCommand, ARRAYSIZE(szCommand), + L"rundll32.exe \"%s\",#1", szDllName); if (!SUCCEEDED(hr)) { goto Cleanup; } diff --git a/src/modules.cpp b/src/modules.cpp index a797121c..d2b4f158 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -858,6 +858,7 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 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. + //Ѿ֧(δ֪ĿλIL뼴ʱɵ64λ̵ı)CLRͷݻָ fUpdated32To64 = TRUE; } @@ -869,7 +870,8 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, CopyMemory(pder->pidh, &pder->idh, pder->cbidh); CopyMemory(pder->pinh, &pder->inh, pder->cbinh); - if (pder->pclr != NULL && !fUpdated32To64) { + //fUpdated32To64ΪTRUEʱҲԻָˣĿǰʵֻǻָclr.Flagsֶ + if (pder->pclr != NULL /*&& !fUpdated32To64*/) { if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr, PAGE_EXECUTE_READWRITE, &dwPermClr)) { CopyMemory(pder->pclr, &pder->clr, pder->cbclr); diff --git a/src/uimports.cpp b/src/uimports.cpp index 1e8cbd70..00c5a8af 100644 --- a/src/uimports.cpp +++ b/src/uimports.cpp @@ -101,6 +101,34 @@ static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess, } } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //ӵĴ + if (inh.IMPORT_DIRECTORY.VirtualAddress!=NULL && inh.IMPORT_DIRECTORY.Size==0) + { + //ÿǻıPEļ,ΪԭPEͷĸϢѱ,ָ,ıֻΪĴ + PIMAGE_IMPORT_DESCRIPTOR pImageImport=(PIMAGE_IMPORT_DESCRIPTOR)(pbModule+inh.IMPORT_DIRECTORY.VirtualAddress); + IMAGE_IMPORT_DESCRIPTOR ImageImport; + + if(!ReadProcessMemory(hProcess,pImageImport,&ImageImport,sizeof(ImageImport),NULL)) + { + _Analysis_assume_(FALSE); + goto finish; + } + while(ImageImport.Name) + { + inh.IMPORT_DIRECTORY.Size+=sizeof(IMAGE_IMPORT_DESCRIPTOR); + if(!ReadProcessMemory(hProcess,pImageImport,&ImageImport,sizeof(ImageImport),NULL)) + { + _Analysis_assume_(FALSE); + goto finish; + } + ++pImageImport; + } + OutputDebugString(TEXT("PEļڵ,ǵСȴΪ0,һ,") + TEXT("޸ij޷,ΪԶ޸ĵС\r\n")); + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + DETOUR_TRACE((" Imports: %p..%p\n", (DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress, (DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress + From 74bb4f17995b7658e069c1c0609b147364b574c2 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Fri, 6 Mar 2020 19:56:49 +0800 Subject: [PATCH 05/21] =?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=BB=E5=8A=A1=E5=90=8E=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=AF=A5=E8=B4=9F=E8=BD=BD=E4=BB=A5=E9=98=B2=E6=AD=A2=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=A2=AB=E5=8F=8D=E5=A4=8D=E6=89=A7=E8=A1=8C=E5=8F=8A?= =?UTF-8?q?=E9=98=B2=E6=AD=A2=E5=86=85=E5=AD=98=E6=B3=84=E9=9C=B2=20?= =?UTF-8?q?=E4=B8=BA=E4=BA=86=E8=83=BD=E5=92=8C=E8=80=81=E7=89=88=E6=9C=AC?= =?UTF-8?q?Detours=E7=BC=96=E8=AF=91=E7=9A=84=E7=A8=8B=E5=BA=8F=E4=BF=9D?= =?UTF-8?q?=E6=8C=81=E5=85=BC=E5=AE=B9=EF=BC=8C=E6=88=91=E4=BB=AC=E4=B8=BA?= =?UTF-8?q?DETOUR=5FEXE=5FRESTORE=5FGUID=E6=8D=A2=E4=B8=80=E4=B8=AAguid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/creatwth.cpp | 13 +++++++++++++ src/modules.cpp | 17 +++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 8f61f392..6e7f035d 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ obj.* *.log *.obj *.user +/bin.* diff --git a/src/creatwth.cpp b/src/creatwth.cpp index b6eead7d..05363581 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -11,6 +11,7 @@ #define DETOURS_INTERNAL #include "detours.h" #include +#include #if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH #error detours.h version mismatch @@ -1041,6 +1042,18 @@ VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, rlpDlls = NULL; } + //ִɺɾøͷռõڴ + if (s_pHelper != NULL) + { + HMODULE hModule = DetourGetContainingModule(s_pHelper); + assert(hModule != NULL); + if (hModule != NULL) + { + VirtualFree(hModule, 0, MEM_RELEASE); + hModule = NULL; + } + } + ExitProcess(Result); } diff --git a/src/modules.cpp b/src/modules.cpp index d2b4f158..0322afe6 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -12,6 +12,7 @@ // #define DETOUR_DEBUG 1 #define DETOURS_INTERNAL #include "detours.h" +#include #if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH #error detours.h version mismatch @@ -23,8 +24,8 @@ ////////////////////////////////////////////////////////////////////////////// // const GUID DETOUR_EXE_RESTORE_GUID = { - 0x2ed7a3ff, 0x3339, 0x4a8d, - { 0x80, 0x5c, 0xd4, 0x98, 0x15, 0x3f, 0xc2, 0x8f }}; + 0xbda26f34, 0xbc82, 0x4829, + { 0x9e, 0x64, 0x74, 0x2c, 0x4, 0xc8, 0x4f, 0xa0 } }; ////////////////////////////////////////////////////////////////////////////// // @@ -886,6 +887,18 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, } VirtualProtect(pder->pidh, pder->cbidh, dwPermIdh, &dwIgnore); } + + //ָɹɾøԷֹظִлָ + if (fSucceeded) + { + HMODULE hModule = DetourGetContainingModule(pder); + assert(hModule != NULL); + if (hModule != NULL) + { + VirtualFree(hModule, 0, MEM_RELEASE); + hModule = NULL; + } + } return fSucceeded; } From 0cb41bb3ceb277eee9bb737518258dc9f17d532d Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Fri, 6 Mar 2020 20:47:06 +0800 Subject: [PATCH 06/21] =?UTF-8?q?=E5=88=A0=E9=99=A4.detourd=E5=8F=AF?= =?UTF-8?q?=E8=AF=BB=E5=86=99=E6=95=B0=E6=8D=AE=E8=8A=82=E5=92=8C.detourc?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=E6=95=B0=E6=8D=AE=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/disasm.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/disasm.cpp b/src/disasm.cpp index ce666fb0..c70d57b9 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -144,8 +144,11 @@ // offsets. // -#pragma data_seg(".detourd") -#pragma const_seg(".detourc") +//ӦҪΪ˷DetoursٷijǷʹDetoursģĿǰʵ; +//Դļ涨ĵĿɶдֻݿԺϲݽȥ(.detourd->.data , .detourc->.rdata) +//ϲʹɵijС +//#pragma data_seg(".detourd") +//#pragma const_seg(".detourc") //////////////////////////////////////////////////// X86 and X64 Disassembler. // From 55755c32ff7a04f05d73064a1364a8b6e7768092 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Wed, 29 Apr 2020 10:55:56 +0800 Subject: [PATCH 07/21] =?UTF-8?q?Windows=20SDK=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ vc/Detours.vcxproj | 2 +- vc/Detours.vcxproj.filters | 30 ++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6e7f035d..bba55ace 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ obj.* *.obj *.user /bin.* +/vc/Win32/ +/vc/x64/ diff --git a/vc/Detours.vcxproj b/vc/Detours.vcxproj index 4c36d346..8746c827 100644 --- a/vc/Detours.vcxproj +++ b/vc/Detours.vcxproj @@ -23,7 +23,7 @@ {37489709-8054-4903-9C49-A79846049FC9} Win32Proj Detours - 10.0.17134.0 + 10.0.18362.0 diff --git a/vc/Detours.vcxproj.filters b/vc/Detours.vcxproj.filters index a7abda9b..206361d1 100644 --- a/vc/Detours.vcxproj.filters +++ b/vc/Detours.vcxproj.filters @@ -29,6 +29,9 @@ Header Files + + Header Files + @@ -178,5 +181,32 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + \ No newline at end of file From ff487868e3b31a51267fb1078ae66b454cf3dd75 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Wed, 1 Jul 2020 19:43:03 +0800 Subject: [PATCH 08/21] =?UTF-8?q?=E4=BB=8ESocksCapEx2=E7=9A=84Detours?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E4=B8=AD=E7=A7=BB=E6=A4=8D=E8=BF=9B?= =?UTF-8?q?detour=5Fskip=5Fall=5Fsequential=5Fjmps=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/detours.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ src/detours.h | 5 ++++ 2 files changed, 85 insertions(+) diff --git a/src/detours.cpp b/src/detours.cpp index b8f46884..1ec2b093 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -179,6 +179,46 @@ inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) return pbCode; } +//нJMPָ,ͬdetour_skip_jmp,detour_skip_jmpֻDzȫ +//http://m.newsmth.net/article/DotNET/10955?au=flier +//X86 +PBYTE detour_skip_all_sequential_jmps(PBYTE pbCode, PVOID *ppGlobals) +{ + if (pbCode == NULL) { + return NULL; + } + if (ppGlobals != NULL) { + *ppGlobals = NULL; + } + + // First, skip over the import vector if there is one. + if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [imm32] + // Looks like an import alias jump, then get the code it points to. + PBYTE pbTarget = *(UNALIGNED PBYTE *)&pbCode[2]; + + PBYTE pbNew = *(UNALIGNED PBYTE *)pbTarget; + DETOUR_TRACE(("%p->%p: skipped over import alias style jmp.\n", pbCode, pbNew)); + + return detour_skip_all_sequential_jmps(pbNew, ppGlobals); + } + // Then, skip over a patch jump + else if (pbCode[0] == 0xeb) { // jmp +imm8 + PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1]; + DETOUR_TRACE(("%p->%p: skipped over short jump.\n", pbCode, pbNew)); + + return detour_skip_all_sequential_jmps(pbNew, ppGlobals); + } + // Finally, skip over a long jump if it is the target of the patch jump. + else if (pbCode[0] == 0xe9) { // jmp +imm32 + PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; + DETOUR_TRACE(("%p->%p: skipped over long jump.\n", pbCode, pbNew)); + + return detour_skip_all_sequential_jmps(pbNew, ppGlobals); + } + + return pbCode; +} + inline void detour_find_jmp_bounds(PBYTE pbCode, PDETOUR_TRAMPOLINE *ppLower, PDETOUR_TRAMPOLINE *ppUpper) @@ -392,6 +432,46 @@ inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) return pbCode; } +//нJMPָ,ͬdetour_skip_jmp,detour_skip_jmpֻDzȫ +//http://m.newsmth.net/article/DotNET/10955?au=flier +//X64 +PBYTE detour_skip_all_sequential_jmps(PBYTE pbCode, PVOID *ppGlobals) +{ + if (pbCode == NULL) { + return NULL; + } + if (ppGlobals != NULL) { + *ppGlobals = NULL; + } + + // First, skip over the import vector if there is one. + if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] + // Looks like an import alias jump, then get the code it points to. + PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32 *)&pbCode[2]; + + PBYTE pbNew = *(UNALIGNED PBYTE *)pbTarget; + DETOUR_TRACE(("%p->%p: skipped over import alias style jmp.\n", pbCode, pbNew)); + + return detour_skip_all_sequential_jmps(pbNew, ppGlobals); + } + // Then, skip over a patch jump + else if (pbCode[0] == 0xeb) { // jmp +imm8 + PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1]; + DETOUR_TRACE(("%p->%p: skipped over short jump.\n", pbCode, pbNew)); + + return detour_skip_all_sequential_jmps(pbNew, ppGlobals); + } + // Finally, skip over a long jump if it is the target of the patch jump. + else if (pbCode[0] == 0xe9) { // jmp +imm32 + PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; + DETOUR_TRACE(("%p->%p: skipped over long jump.\n", pbCode, pbNew)); + + return detour_skip_all_sequential_jmps(pbNew, ppGlobals); + } + + return pbCode; +} + inline void detour_find_jmp_bounds(PBYTE pbCode, PDETOUR_TRAMPOLINE *ppLower, PDETOUR_TRAMPOLINE *ppUpper) diff --git a/src/detours.h b/src/detours.h index 4f6db89a..12bce4ce 100644 --- a/src/detours.h +++ b/src/detours.h @@ -546,6 +546,11 @@ BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); +/////////////////////////////////////////////////////////////////////////////// +//ӵĴ +PBYTE detour_skip_all_sequential_jmps(PBYTE pbCode, PVOID *ppGlobals); +/////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////// Code Functions. // PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, From e23122fafa1ddbb7349b5d31ec6393e9c7c3c059 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Sun, 2 Aug 2020 19:13:54 +0800 Subject: [PATCH 09/21] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E6=96=B0=E7=9A=84API?= =?UTF-8?q?=E5=87=BD=E6=95=B0DetourSetNeedClosePendingThreadHandles?= =?UTF-8?q?=E7=94=A8=E4=BA=8E=E6=8E=A7=E5=88=B6=E6=98=AF=E5=90=A6=E5=9C=A8?= =?UTF-8?q?=E5=88=A0=E9=99=A4DetourThread=E5=AF=B9=E8=B1=A1=E5=89=8D?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E7=9B=B8=E5=85=B3=E8=81=94=E7=9A=84=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E5=8F=A5=E6=9F=84;=E4=B8=8D=E5=86=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8CRT=E7=9A=84new/delete=E5=87=BD=E6=95=B0=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E5=86=85=E9=83=A8=E7=9A=84=E5=86=85=E5=AD=98=E7=AE=A1?= =?UTF-8?q?=E7=90=86.=E5=9B=A0=E6=AD=A4=E6=9B=B4=E5=A5=BD=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BA=86DetourUpdateThread=E5=87=BD=E6=95=B0?= =?UTF-8?q?;=E5=8A=A0=E5=85=A5=E6=96=B0API=E5=87=BD=E6=95=B0DetourUpdateAl?= =?UTF-8?q?lOtherThreads=E4=BB=A5=E7=94=A8=E4=BA=8E=E4=B8=AD=E9=80=94?= =?UTF-8?q?=E5=AE=89=E5=85=A8HOOK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/creatwth.cpp | 10 +- src/detours.cpp | 5375 ++++++++++++++++++------------------ src/detours.h | 110 + src/image.cpp | 55 +- src/modules.cpp | 2 +- src/uimports.cpp | 6 +- vc/Detours.vcxproj | 375 +-- vc/Detours.vcxproj.filters | 266 +- 8 files changed, 3140 insertions(+), 3059 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 05363581..37919e54 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -1014,7 +1014,7 @@ VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, goto Cleanup; } - rlpDlls = new NOTHROW LPCSTR [s_pHelper->nDlls]; + rlpDlls = DetourCreateObjectArray(s_pHelper->nDlls); cSize = s_pHelper->cb - sizeof(DETOUR_EXE_HELPER); for (DWORD n = 0; n < s_pHelper->nDlls; n++) { size_t cchDest = 0; @@ -1038,7 +1038,7 @@ VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, Cleanup: if (rlpDlls != NULL) { - delete[] rlpDlls; + DetourDestroyObjectArray(rlpDlls); rlpDlls = NULL; } @@ -1115,7 +1115,7 @@ BOOL WINAPI AllocExeHelper(_Out_ PDETOUR_EXE_HELPER *pHelper, cSize += (DWORD)cchDest + 1; } - Helper = (PDETOUR_EXE_HELPER) new NOTHROW BYTE[sizeof(DETOUR_EXE_HELPER) + cSize]; + Helper = (PDETOUR_EXE_HELPER)DetourCreateObjectArray(sizeof(DETOUR_EXE_HELPER) + cSize); if (Helper == NULL) { goto Cleanup; } @@ -1180,7 +1180,7 @@ BOOL WINAPI AllocExeHelper(_Out_ PDETOUR_EXE_HELPER *pHelper, Cleanup: if (Helper != NULL) { - delete[] (PBYTE)Helper; + DetourDestroyObjectArray((PBYTE)Helper); Helper = NULL; } return Result; @@ -1190,7 +1190,7 @@ static VOID WINAPI FreeExeHelper(PDETOUR_EXE_HELPER *pHelper) { if (*pHelper != NULL) { - delete[] (PBYTE)*pHelper; + DetourDestroyObjectArray((PBYTE)*pHelper); *pHelper = NULL; } } diff --git a/src/detours.cpp b/src/detours.cpp index 1ec2b093..66c979ec 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -1,2628 +1,2747 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Core Detours Functionality (detours.cpp of detours.lib) -// -// Microsoft Research Detours Package, Version 4.0.1 -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// - - -//#define DETOUR_DEBUG 1 -#define DETOURS_INTERNAL -#include "detours.h" - -#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH -#error detours.h version mismatch -#endif - -#define NOTHROW - -////////////////////////////////////////////////////////////////////////////// -// -struct _DETOUR_ALIGN -{ - BYTE obTarget : 3; - BYTE obTrampoline : 5; -}; - -C_ASSERT(sizeof(_DETOUR_ALIGN) == 1); - -////////////////////////////////////////////////////////////////////////////// -// -// Region reserved for system DLLs, which cannot be used for trampolines. -// -static PVOID s_pSystemRegionLowerBound = (PVOID)(ULONG_PTR)0x70000000; -static PVOID s_pSystemRegionUpperBound = (PVOID)(ULONG_PTR)0x80000000; - -////////////////////////////////////////////////////////////////////////////// -// -static bool detour_is_imported(PBYTE pbCode, PBYTE pbAddress) -{ - MEMORY_BASIC_INFORMATION mbi; - VirtualQuery((PVOID)pbCode, &mbi, sizeof(mbi)); - __try { - PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase; - if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { - return false; - } - - PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + - pDosHeader->e_lfanew); - if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { - return false; - } - - if (pbAddress >= ((PBYTE)pDosHeader + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) && - pbAddress < ((PBYTE)pDosHeader + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size)) { - return true; - } - } -#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) { - return false; - } - return false; -} - -inline ULONG_PTR detour_2gb_below(ULONG_PTR address) -{ - return (address > (ULONG_PTR)0x7ff80000) ? address - 0x7ff80000 : 0x80000; -} - -inline ULONG_PTR detour_2gb_above(ULONG_PTR address) -{ -#if defined(DETOURS_64BIT) - return (address < (ULONG_PTR)0xffffffff80000000) ? address + 0x7ff80000 : (ULONG_PTR)0xfffffffffff80000; -#else - return (address < (ULONG_PTR)0x80000000) ? address + 0x7ff80000 : (ULONG_PTR)0xfff80000; -#endif -} - -///////////////////////////////////////////////////////////////////////// X86. -// -#ifdef DETOURS_X86 - -struct _DETOUR_TRAMPOLINE -{ - BYTE rbCode[30]; // target code + jmp to pbRemain - BYTE cbCode; // size of moved target code. - BYTE cbCodeBreak; // padding to make debugging easier. - BYTE rbRestore[22]; // original target code. - BYTE cbRestore; // size of original target code. - BYTE cbRestoreBreak; // padding to make debugging easier. - _DETOUR_ALIGN rAlign[8]; // instruction alignment array. - PBYTE pbRemain; // first instruction after moved code. [free list] - PBYTE pbDetour; // first instruction of detour function. -}; - -C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 72); - -enum { - SIZE_OF_JMP = 5 -}; - -inline PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE pbJmpVal) -{ - PBYTE pbJmpSrc = pbCode + 5; - *pbCode++ = 0xE9; // jmp +imm32 - *((INT32*&)pbCode)++ = (INT32)(pbJmpVal - pbJmpSrc); - return pbCode; -} - -inline PBYTE detour_gen_jmp_indirect(PBYTE pbCode, PBYTE *ppbJmpVal) -{ - *pbCode++ = 0xff; // jmp [+imm32] - *pbCode++ = 0x25; - *((INT32*&)pbCode)++ = (INT32)((PBYTE)ppbJmpVal); - return pbCode; -} - -inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) -{ - while (pbCode < pbLimit) { - *pbCode++ = 0xcc; // brk; - } - return pbCode; -} - -inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) -{ - if (pbCode == NULL) { - return NULL; - } - if (ppGlobals != NULL) { - *ppGlobals = NULL; - } - - // First, skip over the import vector if there is one. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [imm32] - // Looks like an import alias jump, then get the code it points to. - PBYTE pbTarget = *(UNALIGNED PBYTE *)&pbCode[2]; - if (detour_is_imported(pbCode, pbTarget)) { - PBYTE pbNew = *(UNALIGNED PBYTE *)pbTarget; - DETOUR_TRACE(("%p->%p: skipped over import table.\n", pbCode, pbNew)); - pbCode = pbNew; - } - } - - // Then, skip over a patch jump - if (pbCode[0] == 0xeb) { // jmp +imm8 - PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1]; - DETOUR_TRACE(("%p->%p: skipped over short jump.\n", pbCode, pbNew)); - pbCode = pbNew; - - // First, skip over the import vector if there is one. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [imm32] - // Looks like an import alias jump, then get the code it points to. - PBYTE pbTarget = *(UNALIGNED PBYTE *)&pbCode[2]; - if (detour_is_imported(pbCode, pbTarget)) { - pbNew = *(UNALIGNED PBYTE *)pbTarget; - DETOUR_TRACE(("%p->%p: skipped over import table.\n", pbCode, pbNew)); - pbCode = pbNew; - } - } - // Finally, skip over a long jump if it is the target of the patch jump. - else if (pbCode[0] == 0xe9) { // jmp +imm32 - pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; - DETOUR_TRACE(("%p->%p: skipped over long jump.\n", pbCode, pbNew)); - pbCode = pbNew; - } - } - return pbCode; -} - -//нJMPָ,ͬdetour_skip_jmp,detour_skip_jmpֻDzȫ -//http://m.newsmth.net/article/DotNET/10955?au=flier -//X86 -PBYTE detour_skip_all_sequential_jmps(PBYTE pbCode, PVOID *ppGlobals) -{ - if (pbCode == NULL) { - return NULL; - } - if (ppGlobals != NULL) { - *ppGlobals = NULL; - } - - // First, skip over the import vector if there is one. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [imm32] - // Looks like an import alias jump, then get the code it points to. - PBYTE pbTarget = *(UNALIGNED PBYTE *)&pbCode[2]; - - PBYTE pbNew = *(UNALIGNED PBYTE *)pbTarget; - DETOUR_TRACE(("%p->%p: skipped over import alias style jmp.\n", pbCode, pbNew)); - - return detour_skip_all_sequential_jmps(pbNew, ppGlobals); - } - // Then, skip over a patch jump - else if (pbCode[0] == 0xeb) { // jmp +imm8 - PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1]; - DETOUR_TRACE(("%p->%p: skipped over short jump.\n", pbCode, pbNew)); - - return detour_skip_all_sequential_jmps(pbNew, ppGlobals); - } - // Finally, skip over a long jump if it is the target of the patch jump. - else if (pbCode[0] == 0xe9) { // jmp +imm32 - PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; - DETOUR_TRACE(("%p->%p: skipped over long jump.\n", pbCode, pbNew)); - - return detour_skip_all_sequential_jmps(pbNew, ppGlobals); - } - - return pbCode; -} - -inline void detour_find_jmp_bounds(PBYTE pbCode, - PDETOUR_TRAMPOLINE *ppLower, - PDETOUR_TRAMPOLINE *ppUpper) -{ - // We have to place trampolines within +/- 2GB of code. - ULONG_PTR lo = detour_2gb_below((ULONG_PTR)pbCode); - ULONG_PTR hi = detour_2gb_above((ULONG_PTR)pbCode); - DETOUR_TRACE(("[%p..%p..%p]\n", lo, pbCode, hi)); - - // And, within +/- 2GB of relative jmp targets. - if (pbCode[0] == 0xe9) { // jmp +imm32 - PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; - - if (pbNew < pbCode) { - hi = detour_2gb_above((ULONG_PTR)pbNew); - } - else { - lo = detour_2gb_below((ULONG_PTR)pbNew); - } - DETOUR_TRACE(("[%p..%p..%p] +imm32\n", lo, pbCode, hi)); - } - - *ppLower = (PDETOUR_TRAMPOLINE)lo; - *ppUpper = (PDETOUR_TRAMPOLINE)hi; -} - -inline BOOL detour_does_code_end_function(PBYTE pbCode) -{ - if (pbCode[0] == 0xeb || // jmp +imm8 - pbCode[0] == 0xe9 || // jmp +imm32 - pbCode[0] == 0xe0 || // jmp eax - pbCode[0] == 0xc2 || // ret +imm8 - pbCode[0] == 0xc3 || // ret - pbCode[0] == 0xcc) { // brk - return TRUE; - } - else if (pbCode[0] == 0xf3 && pbCode[1] == 0xc3) { // rep ret - return TRUE; - } - else if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] - return TRUE; - } - else if ((pbCode[0] == 0x26 || // jmp es: - pbCode[0] == 0x2e || // jmp cs: - pbCode[0] == 0x36 || // jmp ss: - pbCode[0] == 0x3e || // jmp ds: - pbCode[0] == 0x64 || // jmp fs: - pbCode[0] == 0x65) && // jmp gs: - pbCode[1] == 0xff && // jmp [+imm32] - pbCode[2] == 0x25) { - return TRUE; - } - return FALSE; -} - -inline ULONG detour_is_code_filler(PBYTE pbCode) -{ - // 1-byte through 11-byte NOPs. - if (pbCode[0] == 0x90) { - return 1; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x90) { - return 2; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x00) { - return 3; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x40 && - pbCode[3] == 0x00) { - return 4; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x44 && - pbCode[3] == 0x00 && pbCode[4] == 0x00) { - return 5; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && - pbCode[3] == 0x44 && pbCode[4] == 0x00 && pbCode[5] == 0x00) { - return 6; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x80 && - pbCode[3] == 0x00 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && - pbCode[6] == 0x00) { - return 7; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x84 && - pbCode[3] == 0x00 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && - pbCode[6] == 0x00 && pbCode[7] == 0x00) { - return 8; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && - pbCode[3] == 0x84 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && - pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00) { - return 9; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x0F && - pbCode[3] == 0x1F && pbCode[4] == 0x84 && pbCode[5] == 0x00 && - pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && - pbCode[9] == 0x00) { - return 10; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x66 && - pbCode[3] == 0x0F && pbCode[4] == 0x1F && pbCode[5] == 0x84 && - pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && - pbCode[9] == 0x00 && pbCode[10] == 0x00) { - return 11; - } - - // int 3. - if (pbCode[0] == 0xcc) { - return 1; - } - return 0; -} - -#endif // DETOURS_X86 - -///////////////////////////////////////////////////////////////////////// X64. -// -#ifdef DETOURS_X64 - -struct _DETOUR_TRAMPOLINE -{ - // An X64 instuction can be 15 bytes long. - // In practice 11 seems to be the limit. - BYTE rbCode[30]; // target code + jmp to pbRemain. - BYTE cbCode; // size of moved target code. - BYTE cbCodeBreak; // padding to make debugging easier. - BYTE rbRestore[30]; // original target code. - BYTE cbRestore; // size of original target code. - BYTE cbRestoreBreak; // padding to make debugging easier. - _DETOUR_ALIGN rAlign[8]; // instruction alignment array. - PBYTE pbRemain; // first instruction after moved code. [free list] - PBYTE pbDetour; // first instruction of detour function. - BYTE rbCodeIn[8]; // jmp [pbDetour] -}; - -C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 96); - -enum { - SIZE_OF_JMP = 5 -}; - -inline PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE pbJmpVal) -{ - PBYTE pbJmpSrc = pbCode + 5; - *pbCode++ = 0xE9; // jmp +imm32 - *((INT32*&)pbCode)++ = (INT32)(pbJmpVal - pbJmpSrc); - return pbCode; -} - -inline PBYTE detour_gen_jmp_indirect(PBYTE pbCode, PBYTE *ppbJmpVal) -{ - PBYTE pbJmpSrc = pbCode + 6; - *pbCode++ = 0xff; // jmp [+imm32] - *pbCode++ = 0x25; - *((INT32*&)pbCode)++ = (INT32)((PBYTE)ppbJmpVal - pbJmpSrc); - return pbCode; -} - -inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) -{ - while (pbCode < pbLimit) { - *pbCode++ = 0xcc; // brk; - } - return pbCode; -} - -inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) -{ - if (pbCode == NULL) { - return NULL; - } - if (ppGlobals != NULL) { - *ppGlobals = NULL; - } - - // First, skip over the import vector if there is one. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] - // Looks like an import alias jump, then get the code it points to. - PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32 *)&pbCode[2]; - if (detour_is_imported(pbCode, pbTarget)) { - PBYTE pbNew = *(UNALIGNED PBYTE *)pbTarget; - DETOUR_TRACE(("%p->%p: skipped over import table.\n", pbCode, pbNew)); - pbCode = pbNew; - } - } - - // Then, skip over a patch jump - if (pbCode[0] == 0xeb) { // jmp +imm8 - PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1]; - DETOUR_TRACE(("%p->%p: skipped over short jump.\n", pbCode, pbNew)); - pbCode = pbNew; - - // First, skip over the import vector if there is one. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] - // Looks like an import alias jump, then get the code it points to. - PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32 *)&pbCode[2]; - if (detour_is_imported(pbCode, pbTarget)) { - pbNew = *(UNALIGNED PBYTE *)pbTarget; - DETOUR_TRACE(("%p->%p: skipped over import table.\n", pbCode, pbNew)); - pbCode = pbNew; - } - } - // Finally, skip over a long jump if it is the target of the patch jump. - else if (pbCode[0] == 0xe9) { // jmp +imm32 - pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; - DETOUR_TRACE(("%p->%p: skipped over long jump.\n", pbCode, pbNew)); - pbCode = pbNew; - } - } - return pbCode; -} - -//нJMPָ,ͬdetour_skip_jmp,detour_skip_jmpֻDzȫ -//http://m.newsmth.net/article/DotNET/10955?au=flier -//X64 -PBYTE detour_skip_all_sequential_jmps(PBYTE pbCode, PVOID *ppGlobals) -{ - if (pbCode == NULL) { - return NULL; - } - if (ppGlobals != NULL) { - *ppGlobals = NULL; - } - - // First, skip over the import vector if there is one. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] - // Looks like an import alias jump, then get the code it points to. - PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32 *)&pbCode[2]; - - PBYTE pbNew = *(UNALIGNED PBYTE *)pbTarget; - DETOUR_TRACE(("%p->%p: skipped over import alias style jmp.\n", pbCode, pbNew)); - - return detour_skip_all_sequential_jmps(pbNew, ppGlobals); - } - // Then, skip over a patch jump - else if (pbCode[0] == 0xeb) { // jmp +imm8 - PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1]; - DETOUR_TRACE(("%p->%p: skipped over short jump.\n", pbCode, pbNew)); - - return detour_skip_all_sequential_jmps(pbNew, ppGlobals); - } - // Finally, skip over a long jump if it is the target of the patch jump. - else if (pbCode[0] == 0xe9) { // jmp +imm32 - PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; - DETOUR_TRACE(("%p->%p: skipped over long jump.\n", pbCode, pbNew)); - - return detour_skip_all_sequential_jmps(pbNew, ppGlobals); - } - - return pbCode; -} - -inline void detour_find_jmp_bounds(PBYTE pbCode, - PDETOUR_TRAMPOLINE *ppLower, - PDETOUR_TRAMPOLINE *ppUpper) -{ - // We have to place trampolines within +/- 2GB of code. - ULONG_PTR lo = detour_2gb_below((ULONG_PTR)pbCode); - ULONG_PTR hi = detour_2gb_above((ULONG_PTR)pbCode); - DETOUR_TRACE(("[%p..%p..%p]\n", lo, pbCode, hi)); - - // And, within +/- 2GB of relative jmp vectors. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] - PBYTE pbNew = pbCode + 6 + *(UNALIGNED INT32 *)&pbCode[2]; - - if (pbNew < pbCode) { - hi = detour_2gb_above((ULONG_PTR)pbNew); - } - else { - lo = detour_2gb_below((ULONG_PTR)pbNew); - } - DETOUR_TRACE(("[%p..%p..%p] [+imm32]\n", lo, pbCode, hi)); - } - // And, within +/- 2GB of relative jmp targets. - else if (pbCode[0] == 0xe9) { // jmp +imm32 - PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; - - if (pbNew < pbCode) { - hi = detour_2gb_above((ULONG_PTR)pbNew); - } - else { - lo = detour_2gb_below((ULONG_PTR)pbNew); - } - DETOUR_TRACE(("[%p..%p..%p] +imm32\n", lo, pbCode, hi)); - } - - *ppLower = (PDETOUR_TRAMPOLINE)lo; - *ppUpper = (PDETOUR_TRAMPOLINE)hi; -} - -inline BOOL detour_does_code_end_function(PBYTE pbCode) -{ - if (pbCode[0] == 0xeb || // jmp +imm8 - pbCode[0] == 0xe9 || // jmp +imm32 - pbCode[0] == 0xe0 || // jmp eax - pbCode[0] == 0xc2 || // ret +imm8 - pbCode[0] == 0xc3 || // ret - pbCode[0] == 0xcc) { // brk - return TRUE; - } - else if (pbCode[0] == 0xf3 && pbCode[1] == 0xc3) { // rep ret - return TRUE; - } - else if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] - return TRUE; - } - else if ((pbCode[0] == 0x26 || // jmp es: - pbCode[0] == 0x2e || // jmp cs: - pbCode[0] == 0x36 || // jmp ss: - pbCode[0] == 0x3e || // jmp ds: - pbCode[0] == 0x64 || // jmp fs: - pbCode[0] == 0x65) && // jmp gs: - pbCode[1] == 0xff && // jmp [+imm32] - pbCode[2] == 0x25) { - return TRUE; - } - return FALSE; -} - -inline ULONG detour_is_code_filler(PBYTE pbCode) -{ - // 1-byte through 11-byte NOPs. - if (pbCode[0] == 0x90) { - return 1; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x90) { - return 2; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x00) { - return 3; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x40 && - pbCode[3] == 0x00) { - return 4; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x44 && - pbCode[3] == 0x00 && pbCode[4] == 0x00) { - return 5; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && - pbCode[3] == 0x44 && pbCode[4] == 0x00 && pbCode[5] == 0x00) { - return 6; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x80 && - pbCode[3] == 0x00 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && - pbCode[6] == 0x00) { - return 7; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x84 && - pbCode[3] == 0x00 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && - pbCode[6] == 0x00 && pbCode[7] == 0x00) { - return 8; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && - pbCode[3] == 0x84 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && - pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00) { - return 9; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x0F && - pbCode[3] == 0x1F && pbCode[4] == 0x84 && pbCode[5] == 0x00 && - pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && - pbCode[9] == 0x00) { - return 10; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x66 && - pbCode[3] == 0x0F && pbCode[4] == 0x1F && pbCode[5] == 0x84 && - pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && - pbCode[9] == 0x00 && pbCode[10] == 0x00) { - return 11; - } - - // int 3. - if (pbCode[0] == 0xcc) { - return 1; - } - return 0; -} - -#endif // DETOURS_X64 - -//////////////////////////////////////////////////////////////////////// IA64. -// -#ifdef DETOURS_IA64 - -struct _DETOUR_TRAMPOLINE -{ - // On the IA64, a trampoline is used for both incoming and outgoing calls. - // - // The trampoline contains the following bundles for the outgoing call: - // movl gp=target_gp; - // - // brl target_code; - // - // The trampoline contains the following bundles for the incoming call: - // alloc r41=ar.pfs, b, 0, 8, 0 - // mov r40=rp - // - // adds r50=0, r39 - // adds r49=0, r38 - // adds r48=0, r37 ;; - // - // adds r47=0, r36 - // adds r46=0, r35 - // adds r45=0, r34 - // - // adds r44=0, r33 - // adds r43=0, r32 - // adds r42=0, gp ;; - // - // movl gp=ffffffff`ffffffff ;; - // - // brl.call.sptk.few rp=disas!TestCodes+20e0 (00000000`00404ea0) ;; - // - // adds gp=0, r42 - // mov rp=r40, +0 ;; - // mov.i ar.pfs=r41 - // - // br.ret.sptk.many rp ;; - // - // This way, we only have to relocate a single bundle. - // - // The complicated incoming trampoline is required because we have to - // create an additional stack frame so that we save and restore the gp. - // We must do this because gp is a caller-saved register, but not saved - // if the caller thinks the target is in the same DLL, which changes - // when we insert a detour. - // - DETOUR_IA64_BUNDLE bMovlTargetGp; // Bundle which sets target GP - BYTE rbCode[sizeof(DETOUR_IA64_BUNDLE)]; // moved bundle. - DETOUR_IA64_BUNDLE bBrlRemainEip; // Brl to pbRemain - // This must be adjacent to bBranchIslands. - - // Each instruction in the moved bundle could be a IP-relative chk or branch or call. - // Any such instructions are changed to point to a brl in bBranchIslands. - // This must be adjacent to bBrlRemainEip -- see "pbPool". - DETOUR_IA64_BUNDLE bBranchIslands[DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE]; - - // Target of brl inserted in target function - DETOUR_IA64_BUNDLE bAllocFrame; // alloc frame - DETOUR_IA64_BUNDLE bSave37to39; // save r37, r38, r39. - DETOUR_IA64_BUNDLE bSave34to36; // save r34, r35, r36. - DETOUR_IA64_BUNDLE bSaveGPto33; // save gp, r32, r33. - DETOUR_IA64_BUNDLE bMovlDetourGp; // set detour GP. - DETOUR_IA64_BUNDLE bCallDetour; // call detour. - DETOUR_IA64_BUNDLE bPopFrameGp; // pop frame and restore gp. - DETOUR_IA64_BUNDLE bReturn; // return to caller. - - PLABEL_DESCRIPTOR pldTrampoline; - - BYTE rbRestore[sizeof(DETOUR_IA64_BUNDLE)]; // original target bundle. - BYTE cbRestore; // size of original target code. - BYTE cbCode; // size of moved target code. - _DETOUR_ALIGN rAlign[14]; // instruction alignment array. - PBYTE pbRemain; // first instruction after moved code. [free list] - PBYTE pbDetour; // first instruction of detour function. - PPLABEL_DESCRIPTOR ppldDetour; // [pbDetour,gpDetour] - PPLABEL_DESCRIPTOR ppldTarget; // [pbTarget,gpDetour] -}; - -C_ASSERT(sizeof(DETOUR_IA64_BUNDLE) == 16); -C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 256 + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * 16); - -enum { - SIZE_OF_JMP = sizeof(DETOUR_IA64_BUNDLE) -}; - -inline PBYTE detour_skip_jmp(PBYTE pPointer, PVOID *ppGlobals) -{ - PBYTE pGlobals = NULL; - PBYTE pbCode = NULL; - - if (pPointer != NULL) { - PPLABEL_DESCRIPTOR ppld = (PPLABEL_DESCRIPTOR)pPointer; - pbCode = (PBYTE)ppld->EntryPoint; - pGlobals = (PBYTE)ppld->GlobalPointer; - } - if (ppGlobals != NULL) { - *ppGlobals = pGlobals; - } - if (pbCode == NULL) { - return NULL; - } - - DETOUR_IA64_BUNDLE *pb = (DETOUR_IA64_BUNDLE *)pbCode; - - // IA64 Local Import Jumps look like: - // addl r2=ffffffff`ffe021c0, gp ;; - // ld8 r2=[r2] - // nop.i 0 ;; - // - // ld8 r3=[r2], 8 ;; - // ld8 gp=[r2] - // mov b6=r3, +0 - // - // nop.m 0 - // nop.i 0 - // br.cond.sptk.few b6 - // - - // 002024000200100b - if ((pb[0].wide[0] & 0xfffffc000603ffff) == 0x002024000200100b && - pb[0].wide[1] == 0x0004000000203008 && - pb[1].wide[0] == 0x001014180420180a && - pb[1].wide[1] == 0x07000830c0203008 && - pb[2].wide[0] == 0x0000000100000010 && - pb[2].wide[1] == 0x0080006000000200) { - - ULONG64 offset = - ((pb[0].wide[0] & 0x0000000001fc0000) >> 18) | // imm7b - ((pb[0].wide[0] & 0x000001ff00000000) >> 25) | // imm9d - ((pb[0].wide[0] & 0x00000000f8000000) >> 11); // imm5c - if (pb[0].wide[0] & 0x0000020000000000) { // sign - offset |= 0xffffffffffe00000; - } - PBYTE pbTarget = pGlobals + offset; - DETOUR_TRACE(("%p: potential import jump, target=%p\n", pb, pbTarget)); - - if (detour_is_imported(pbCode, pbTarget) && *(PBYTE*)pbTarget != NULL) { - DETOUR_TRACE(("%p: is import jump, label=%p\n", pb, *(PBYTE *)pbTarget)); - - PPLABEL_DESCRIPTOR ppld = (PPLABEL_DESCRIPTOR)*(PBYTE *)pbTarget; - pbCode = (PBYTE)ppld->EntryPoint; - pGlobals = (PBYTE)ppld->GlobalPointer; - if (ppGlobals != NULL) { - *ppGlobals = pGlobals; - } - } - } - return pbCode; -} - - -inline void detour_find_jmp_bounds(PBYTE pbCode, - PDETOUR_TRAMPOLINE *ppLower, - PDETOUR_TRAMPOLINE *ppUpper) -{ - (void)pbCode; - *ppLower = (PDETOUR_TRAMPOLINE)(ULONG_PTR)0x0000000000080000; - *ppUpper = (PDETOUR_TRAMPOLINE)(ULONG_PTR)0xfffffffffff80000; -} - -inline BOOL detour_does_code_end_function(PBYTE pbCode) -{ - // Routine not needed on IA64. - (void)pbCode; - return FALSE; -} - -inline ULONG detour_is_code_filler(PBYTE pbCode) -{ - // Routine not needed on IA64. - (void)pbCode; - return 0; -} - -#endif // DETOURS_IA64 - -#ifdef DETOURS_ARM - -struct _DETOUR_TRAMPOLINE -{ - // A Thumb-2 instruction can be 2 or 4 bytes long. - BYTE rbCode[62]; // target code + jmp to pbRemain - BYTE cbCode; // size of moved target code. - BYTE cbCodeBreak; // padding to make debugging easier. - BYTE rbRestore[22]; // original target code. - BYTE cbRestore; // size of original target code. - BYTE cbRestoreBreak; // padding to make debugging easier. - _DETOUR_ALIGN rAlign[8]; // instruction alignment array. - PBYTE pbRemain; // first instruction after moved code. [free list] - PBYTE pbDetour; // first instruction of detour function. -}; - -C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 104); - -enum { - SIZE_OF_JMP = 8 -}; - -inline PBYTE align4(PBYTE pValue) -{ - return (PBYTE)(((ULONG)pValue) & ~(ULONG)3u); -} - -inline ULONG fetch_thumb_opcode(PBYTE pbCode) -{ - ULONG Opcode = *(UINT16 *)&pbCode[0]; - if (Opcode >= 0xe800) { - Opcode = (Opcode << 16) | *(UINT16 *)&pbCode[2]; - } - return Opcode; -} - -inline void write_thumb_opcode(PBYTE &pbCode, ULONG Opcode) -{ - if (Opcode >= 0x10000) { - *((UINT16*&)pbCode)++ = Opcode >> 16; - } - *((UINT16*&)pbCode)++ = (UINT16)Opcode; -} - -PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE *ppPool, PBYTE pbJmpVal) -{ - PBYTE pbLiteral; - if (ppPool != NULL) { - *ppPool = *ppPool - 4; - pbLiteral = *ppPool; - } - else { - pbLiteral = align4(pbCode + 6); - } - - *((PBYTE*&)pbLiteral) = DETOURS_PBYTE_TO_PFUNC(pbJmpVal); - LONG delta = pbLiteral - align4(pbCode + 4); - - write_thumb_opcode(pbCode, 0xf8dff000 | delta); // LDR PC,[PC+n] - - if (ppPool == NULL) { - if (((ULONG)pbCode & 2) != 0) { - write_thumb_opcode(pbCode, 0xdefe); // BREAK - } - pbCode += 4; - } - return pbCode; -} - -inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) -{ - while (pbCode < pbLimit) { - write_thumb_opcode(pbCode, 0xdefe); - } - return pbCode; -} - -inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) -{ - if (pbCode == NULL) { - return NULL; - } - if (ppGlobals != NULL) { - *ppGlobals = NULL; - } - - // Skip over the import jump if there is one. - pbCode = (PBYTE)DETOURS_PFUNC_TO_PBYTE(pbCode); - ULONG Opcode = fetch_thumb_opcode(pbCode); - - if ((Opcode & 0xfbf08f00) == 0xf2400c00) { // movw r12,#xxxx - ULONG Opcode2 = fetch_thumb_opcode(pbCode+4); - - if ((Opcode2 & 0xfbf08f00) == 0xf2c00c00) { // movt r12,#xxxx - ULONG Opcode3 = fetch_thumb_opcode(pbCode+8); - if (Opcode3 == 0xf8dcf000) { // ldr pc,[r12] - PBYTE pbTarget = (PBYTE)(((Opcode2 << 12) & 0xf7000000) | - ((Opcode2 << 1) & 0x08000000) | - ((Opcode2 << 16) & 0x00ff0000) | - ((Opcode >> 4) & 0x0000f700) | - ((Opcode >> 15) & 0x00000800) | - ((Opcode >> 0) & 0x000000ff)); - if (detour_is_imported(pbCode, pbTarget)) { - PBYTE pbNew = *(PBYTE *)pbTarget; - pbNew = DETOURS_PFUNC_TO_PBYTE(pbNew); - DETOUR_TRACE(("%p->%p: skipped over import table.\n", pbCode, pbNew)); - return pbNew; - } - } - } - } - return pbCode; -} - -inline void detour_find_jmp_bounds(PBYTE pbCode, - PDETOUR_TRAMPOLINE *ppLower, - PDETOUR_TRAMPOLINE *ppUpper) -{ - // We have to place trampolines within +/- 2GB of code. - ULONG_PTR lo = detour_2gb_below((ULONG_PTR)pbCode); - ULONG_PTR hi = detour_2gb_above((ULONG_PTR)pbCode); - DETOUR_TRACE(("[%p..%p..%p]\n", lo, pbCode, hi)); - - *ppLower = (PDETOUR_TRAMPOLINE)lo; - *ppUpper = (PDETOUR_TRAMPOLINE)hi; -} - - -inline BOOL detour_does_code_end_function(PBYTE pbCode) -{ - ULONG Opcode = fetch_thumb_opcode(pbCode); - if ((Opcode & 0xffffff87) == 0x4700 || // bx - (Opcode & 0xf800d000) == 0xf0009000) { // b - return TRUE; - } - if ((Opcode & 0xffff8000) == 0xe8bd8000) { // pop {...,pc} - __debugbreak(); - return TRUE; - } - if ((Opcode & 0xffffff00) == 0x0000bd00) { // pop {...,pc} - __debugbreak(); - return TRUE; - } - return FALSE; -} - -inline ULONG detour_is_code_filler(PBYTE pbCode) -{ - if (pbCode[0] == 0x00 && pbCode[1] == 0xbf) { // nop. - return 2; - } - if (pbCode[0] == 0x00 && pbCode[1] == 0x00) { // zero-filled padding. - return 2; - } - return 0; -} - -#endif // DETOURS_ARM - -#ifdef DETOURS_ARM64 - -struct _DETOUR_TRAMPOLINE -{ - // An ARM64 instruction is 4 bytes long. - // - // The overwrite is always composed of 3 instructions (12 bytes) which perform an indirect jump - // using _DETOUR_TRAMPOLINE::pbDetour as the address holding the target location. - // - // Copied instructions can expand. - // - // The scheme using MovImmediate can cause an instruction - // to grow as much as 6 times. - // That would be Bcc or Tbz with a large address space: - // 4 instructions to form immediate - // inverted tbz/bcc - // br - // - // An expansion of 4 is not uncommon -- bl/blr and small address space: - // 3 instructions to form immediate - // br or brl - // - // A theoretical maximum for rbCode is thefore 4*4*6 + 16 = 112 (another 16 for jmp to pbRemain). - // - // With literals, the maximum expansion is 5, including the literals: 4*4*5 + 16 = 96. - // - // The number is rounded up to 128. m_rbScratchDst should match this. - // - BYTE rbCode[128]; // target code + jmp to pbRemain - BYTE cbCode; // size of moved target code. - BYTE cbCodeBreak[3]; // padding to make debugging easier. - BYTE rbRestore[24]; // original target code. - BYTE cbRestore; // size of original target code. - BYTE cbRestoreBreak[3]; // padding to make debugging easier. - _DETOUR_ALIGN rAlign[8]; // instruction alignment array. - PBYTE pbRemain; // first instruction after moved code. [free list] - PBYTE pbDetour; // first instruction of detour function. -}; - -C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 184); - -enum { - SIZE_OF_JMP = 12 -}; - -inline ULONG fetch_opcode(PBYTE pbCode) -{ - return *(ULONG *)pbCode; -} - -inline void write_opcode(PBYTE &pbCode, ULONG Opcode) -{ - *(ULONG *)pbCode = Opcode; - pbCode += 4; -} - -struct ARM64_INDIRECT_JMP { - struct { - ULONG Rd : 5; - ULONG immhi : 19; - ULONG iop : 5; - ULONG immlo : 2; - ULONG op : 1; - } ardp; - - struct { - ULONG Rt : 5; - ULONG Rn : 5; - ULONG imm : 12; - ULONG opc : 2; - ULONG iop1 : 2; - ULONG V : 1; - ULONG iop2 : 3; - ULONG size : 2; - } ldr; - - ULONG br; -}; - -#pragma warning(push) -#pragma warning(disable:4201) - -union ARM64_INDIRECT_IMM { - struct { - ULONG64 pad : 12; - ULONG64 adrp_immlo : 2; - ULONG64 adrp_immhi : 19; - }; - - LONG64 value; -}; - -#pragma warning(pop) - -PBYTE detour_gen_jmp_indirect(BYTE *pbCode, ULONG64 *pbJmpVal) -{ - // adrp x17, [jmpval] - // ldr x17, [x17, jmpval] - // br x17 - - struct ARM64_INDIRECT_JMP *pIndJmp; - union ARM64_INDIRECT_IMM jmpIndAddr; - - jmpIndAddr.value = (((LONG64)pbJmpVal) & 0xFFFFFFFFFFFFF000) - - (((LONG64)pbCode) & 0xFFFFFFFFFFFFF000); - - pIndJmp = (struct ARM64_INDIRECT_JMP *)pbCode; - pbCode = (BYTE *)(pIndJmp + 1); - - pIndJmp->ardp.Rd = 17; - pIndJmp->ardp.immhi = jmpIndAddr.adrp_immhi; - pIndJmp->ardp.iop = 0x10; - pIndJmp->ardp.immlo = jmpIndAddr.adrp_immlo; - pIndJmp->ardp.op = 1; - - pIndJmp->ldr.Rt = 17; - pIndJmp->ldr.Rn = 17; - pIndJmp->ldr.imm = (((ULONG64)pbJmpVal) & 0xFFF) / 8; - pIndJmp->ldr.opc = 1; - pIndJmp->ldr.iop1 = 1; - pIndJmp->ldr.V = 0; - pIndJmp->ldr.iop2 = 7; - pIndJmp->ldr.size = 3; - - pIndJmp->br = 0xD61F0220; - - return pbCode; -} - -PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE *ppPool, PBYTE pbJmpVal) -{ - PBYTE pbLiteral; - if (ppPool != NULL) { - *ppPool = *ppPool - 8; - pbLiteral = *ppPool; - } - else { - pbLiteral = pbCode + 8; - } - - *((PBYTE*&)pbLiteral) = pbJmpVal; - LONG delta = (LONG)(pbLiteral - pbCode); - - write_opcode(pbCode, 0x58000011 | ((delta / 4) << 5)); // LDR X17,[PC+n] - write_opcode(pbCode, 0xd61f0000 | (17 << 5)); // BR X17 - - if (ppPool == NULL) { - pbCode += 8; - } - return pbCode; -} - -inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) -{ - while (pbCode < pbLimit) { - write_opcode(pbCode, 0xd4100000 | (0xf000 << 5)); - } - return pbCode; -} - -inline INT64 detour_sign_extend(UINT64 value, UINT bits) -{ - const UINT left = 64 - bits; - const INT64 m1 = -1; - const INT64 wide = (INT64)(value << left); - const INT64 sign = (wide < 0) ? (m1 << left) : 0; - return value | sign; -} - -inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) -{ - if (pbCode == NULL) { - return NULL; - } - if (ppGlobals != NULL) { - *ppGlobals = NULL; - } - - // Skip over the import jump if there is one. - pbCode = (PBYTE)pbCode; - ULONG Opcode = fetch_opcode(pbCode); - - if ((Opcode & 0x9f00001f) == 0x90000010) { // adrp x16, IAT - ULONG Opcode2 = fetch_opcode(pbCode + 4); - - if ((Opcode2 & 0xffe003ff) == 0xf9400210) { // ldr x16, [x16, IAT] - ULONG Opcode3 = fetch_opcode(pbCode + 8); - - if (Opcode3 == 0xd61f0200) { // br x16 - -/* https://static.docs.arm.com/ddi0487/bb/DDI0487B_b_armv8_arm.pdf - The ADRP instruction shifts a signed, 21-bit immediate left by 12 bits, adds it to the value of the program counter with - the bottom 12 bits cleared to zero, and then writes the result to a general-purpose register. This permits the - calculation of the address at a 4KB aligned memory region. In conjunction with an ADD (immediate) instruction, or - a Load/Store instruction with a 12-bit immediate offset, this allows for the calculation of, or access to, any address - within +/- 4GB of the current PC. - -PC-rel. addressing - This section describes the encoding of the PC-rel. addressing instruction class. The encodings in this section are - decoded from Data Processing -- Immediate on page C4-226. - Add/subtract (immediate) - This section describes the encoding of the Add/subtract (immediate) instruction class. The encodings in this section - are decoded from Data Processing -- Immediate on page C4-226. - Decode fields - Instruction page - op - 0 ADR - 1 ADRP - -C6.2.10 ADRP - Form PC-relative address to 4KB page adds an immediate value that is shifted left by 12 bits, to the PC value to - form a PC-relative address, with the bottom 12 bits masked out, and writes the result to the destination register. - ADRP , - StaticLibrary + Utility true - v141 + v142 Unicode - StaticLibrary + Utility false - v141 + v142 Unicode - StaticLibrary + Utility + true + v142 + Unicode + + + Utility + true + v142 + Unicode + + + Utility true - v141 + v142 Unicode - StaticLibrary + Utility + false + v142 + Unicode + + + Utility + false + v142 + Unicode + + + Utility false - v141 + v142 Unicode @@ -64,27 +104,28 @@ + + + + + + - - ..\lib\ - $(ProjectName)x64d - - - ..\lib\ - $(ProjectName)x64 - - - ..\lib\ - $(ProjectName)x86d - $(Platform)\$(Configuration)\ - - - ..\lib\ - $(ProjectName)x86 - $(Platform)\$(Configuration)\ - + + + + + + + + + + + + + Level4 @@ -99,10 +140,12 @@ Windows true - - mkdir ..\include -xcopy /I /Y /D /R /K "..\src\*.h" "..\include" - + + + SET DETOURS_TARGET_PROCESSOR=X86 +cd .. +nmake + @@ -121,10 +164,64 @@ xcopy /I /Y /D /R /K "..\src\*.h" "..\include" Windows true - - mkdir ..\include -xcopy /I /Y /D /R /K "..\src\*.h" "..\include" - + + + SET DETOURS_TARGET_PROCESSOR=X64 +cd .. +nmake + + + + + Level4 + Disabled + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + true + ProgramDatabase + + + + + $(OutputPath)$(TargetName).pdb + + + Windows + true + + + + SET DETOURS_TARGET_PROCESSOR=ARM +cd .. +nmake + + + + + Level4 + Disabled + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + true + ProgramDatabase + + + + + $(OutputPath)$(TargetName).pdb + + + Windows + true + + + + SET DETOURS_TARGET_PROCESSOR=ARM64 +cd .. +nmake + @@ -143,10 +240,12 @@ xcopy /I /Y /D /R /K "..\src\*.h" "..\include" true true - - mkdir ..\include -xcopy /I /Y /D /R /K "..\src\*.h" "..\include" - + + + SET DETOURS_TARGET_PROCESSOR=X86 +cd .. +nmake + @@ -167,10 +266,68 @@ xcopy /I /Y /D /R /K "..\src\*.h" "..\include" true true - - mkdir ..\include -xcopy /I /Y /D /R /K "..\src\*.h" "..\include" - + + + SET DETOURS_TARGET_PROCESSOR=X64 +cd .. +nmake + + + + + Level4 + MaxSpeed + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + + + + + $(OutputPath)$(TargetName).pdb + + + Windows + true + true + true + + + + SET DETOURS_TARGET_PROCESSOR=ARM +cd .. +nmake + + + + + Level4 + MaxSpeed + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + + + + + $(OutputPath)$(TargetName).pdb + + + Windows + true + true + true + + + + SET DETOURS_TARGET_PROCESSOR=ARM64 +cd .. +nmake + From 2bd77a03f5c1630d49096980dcc85a24bf44b380 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Thu, 27 Aug 2020 23:21:35 +0800 Subject: [PATCH 16/21] add english comments of the chinese comments by google translator, the original chinese comments are reserved, because I`m afraid, the machine translated english is not 100% accurate, and they can not represent the meaning of chinese entirely. save as UTF8 without BOM for compat with old vc. --- src/creatwth.cpp | 30 ++++++++++++++++++++---------- src/detours.cpp | 15 ++++++++++----- src/detours.h | 6 ++++-- src/disasm.cpp | 9 ++++++--- src/modules.cpp | 9 ++++++--- src/uimports.cpp | 12 ++++++++---- 6 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 37919e54..968a38a3 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -409,8 +409,10 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, // inh64.Signature = inh32.Signature; inh64.FileHeader = inh32.FileHeader; - inh64.FileHeader.Machine = machine;//͸ֵΪinh32.FileHeader.MachineĻwin7µPEˣ - //ᱨSTATUS_INVALID_IMAGE_FORMATҪdepбԭPEͷеMachineֵinh32.FileHeader.Machineֵ + inh64.FileHeader.Machine = machine;//如果这里就赋值为inh32.FileHeader.Machine的话,win7及以下的PE加载器会过不了, + //会报错STATUS_INVALID_IMAGE_FORMAT,所以需要在dep中保存原来的PE头中的Machine的值,即inh32.FileHeader.Machine的值, + //If inh32.FileHeader.Machine is assigned here, the PE loader of win7 and below will not be able to pass, + //It will report an error STATUS_INVALID_IMAGE_FORMAT, so you need to save the value of Machine in the original PE header in dep, that is, the value of inh32.FileHeader.Machine, inh64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64); inh64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; @@ -479,7 +481,8 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, return FALSE; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //RecordExeRestore֮depб64λPEͷˣҪָderбPEͷMachineֵʹ.NETPEظCLRļ + //上面的RecordExeRestore调用之后,dep中保存的是64位的PE头了,所以需要恢复der中保存的PE头的Machine的值,以使得.NET的PE解析器可以正常加载该CLR文件 + //After the above RecordExeRestore call, the 64-bit PE header is saved in dep, so it is necessary to restore the Machine value of the PE header saved in der, so that the PE parser of .NET can load the CLR file normally der.inh.FileHeader.Machine = inh32.FileHeader.Machine; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -528,7 +531,8 @@ namespace Detour } return bRet; }; - //̾hProcessҪPROCESS_QUERY_INFORMATIONPROCESS_QUERY_LIMITED_INFORMATIONȨ + //进程句柄hProcess需要有PROCESS_QUERY_INFORMATION或者PROCESS_QUERY_LIMITED_INFORMATION访问权限 + //The process handle hProcess needs to have PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access rights BOOL Is64BitProcess(HANDLE hProcess) { BOOL bRet = FALSE; @@ -599,8 +603,10 @@ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //ע͵Ĵ - //Ĵ벻ȷжĽǷ32λ + //被注释掉的代码 + //下面的代码不能正确判断启动的进程是否是32位的 + //Commented out code + //The following code cannot correctly determine whether the started process is 32-bit //if (!bHas32BitExe) { // bIs32BitProcess = FALSE; //} @@ -613,7 +619,8 @@ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, // } //} ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //ӵĴ + //添加的代码 + //Added code bIs32BitProcess = !Detour::Is64BitProcess(hProcess); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -735,8 +742,10 @@ BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, DETOUR_CLR_HEADER clr; CopyMemory(&clr, &der.clr, sizeof(clr)); clr.Flags &= 0xfffffffe; // Clear the IL_ONLY flag. - //IL_ONLY־֮ɽ̺󣬻ָIATҪָIL_ONLY־ - //IL_ONLY־޷̣Ϊ滻ԭIATΪǵDLLIAT + //上面这句清除了IL_ONLY标志,所以我们之后启动完成进程后,恢复IAT后需要恢复这个IL_ONLY标志 + //不清除IL_ONLY标志将导致无法启动进程,因为我们替换了原IAT为包含我们的DLL的名称项的新IAT + //The above sentence clears the IL_ONLY flag, so we need to restore the IL_ONLY flag after the IAT is restored after starting the process completion + //Not clearing the IL_ONLY flag will result in the inability to start the process, because we replaced the original IAT with the new IAT containing the name of our DLL DWORD dwProtect; if (!DetourVirtualProtectSameExecuteEx(hProcess, der.pclr, sizeof(clr), PAGE_READWRITE, &dwProtect)) { @@ -1042,7 +1051,8 @@ VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, rlpDlls = NULL; } - //ִɺɾøͷռõڴ + //执行完成后删除该负载以释放其所占用的内存 + //Delete the payload after execution to release the memory occupied by it if (s_pHelper != NULL) { HMODULE hModule = DetourGetContainingModule(s_pHelper); diff --git a/src/detours.cpp b/src/detours.cpp index ed253f55..e0e36070 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -179,7 +179,8 @@ inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) return pbCode; } -//нJMPָ,ͬdetour_skip_jmp,detour_skip_jmpֻDzȫ +//跳过所有接连的JMP指令,不同于detour_skip_jmp函数,detour_skip_jmp只是不完全的跳过 +//Skip all consecutive JMP instructions, unlike the detour_skip_jmp function, detour_skip_jmp is just an incomplete skip //http://m.newsmth.net/article/DotNET/10955?au=flier //X86 PBYTE detour_skip_all_sequential_jmps(PBYTE pbCode, PVOID *ppGlobals) @@ -432,7 +433,8 @@ inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) return pbCode; } -//нJMPָ,ͬdetour_skip_jmp,detour_skip_jmpֻDzȫ +//跳过所有接连的JMP指令,不同于detour_skip_jmp函数,detour_skip_jmp只是不完全的跳过 +//Skip all consecutive JMP instructions, unlike the detour_skip_jmp function, detour_skip_jmp is just an incomplete skip //http://m.newsmth.net/article/DotNET/10955?au=flier //X64 PBYTE detour_skip_all_sequential_jmps(PBYTE pbCode, PVOID *ppGlobals) @@ -2117,7 +2119,8 @@ LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread, _In_ BOOL fCloseThreadHandle return NO_ERROR; } -//޸https://github.com/apriorit/mhook/blob/master/mhook-lib/mhook.c +//代码修改自https://github.com/apriorit/mhook/blob/master/mhook-lib/mhook.c +//Code modified from https://github.com/apriorit/mhook/blob/master/mhook-lib/mhook.c //========================================================================= // ntdll definitions @@ -2383,9 +2386,11 @@ BOOL WINAPI DetourUpdateAllOtherThreads() if (error) { DETOUR_TRACE(("DetourUpdateThread failed, error=%d\n", error)); - //s_nPendingErrorú߳̿ԼԵDetourUpdateThread + //重置s_nPendingError以让后面的线程可以继续尝试调用DetourUpdateThread函数 + //Reset s_nPendingError so that subsequent threads can continue to try to call the DetourUpdateThread function assert(error == s_nPendingError); - //̨ʱDetourUpdateThreadڲSuspendThreadʱs_nPendingError == ERROR_ACCESS_DENIED + //结束控制台程序时,可能在DetourUpdateThread内部的SuspendThread调用时造成s_nPendingError == ERROR_ACCESS_DENIED + //When the console program is terminated, s_nPendingError == ERROR_ACCESS_DENIED may be caused when the SuspendThread inside DetourUpdateThread is called assert(s_nPendingError == ERROR_ACCESS_DENIED); s_nPendingError = NO_ERROR; } diff --git a/src/detours.h b/src/detours.h index 5cf81e2d..32b004b9 100644 --- a/src/detours.h +++ b/src/detours.h @@ -556,7 +556,8 @@ LONG WINAPI DetourTransactionAbort(VOID); LONG WINAPI DetourTransactionCommit(VOID); LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); -//DetourUpdateThreadƼûˣʹDetourUpdateAllOtherThreadsԽиȫHOOK +//DetourUpdateThread不再推荐被用户调用了,请使用DetourUpdateAllOtherThreads以进行更安全的HOOK +//DetourUpdateThread is no longer recommended to be called by users, please use DetourUpdateAllOtherThreads for safer HOOK LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread, _In_ BOOL fCloseThreadHandleOnDestroyDetourThreadObject /*= TRUE*/); BOOL WINAPI DetourUpdateAllOtherThreads(); @@ -578,7 +579,8 @@ PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound) PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); /////////////////////////////////////////////////////////////////////////////// -//ӵĴ +//添加的代码 +//Added code PBYTE detour_skip_all_sequential_jmps(PBYTE pbCode, PVOID *ppGlobals); /////////////////////////////////////////////////////////////////////////////// diff --git a/src/disasm.cpp b/src/disasm.cpp index c70d57b9..a7c771d9 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -144,9 +144,12 @@ // offsets. // -//ӦҪΪ˷DetoursٷijǷʹDetoursģĿǰʵ; -//Դļ涨ĵĿɶдֻݿԺϲݽȥ(.detourd->.data , .detourc->.rdata) -//ϲʹɵijС +//下面两个节应该主要是为了方便Detours官方查某个程序是否使用了Detours的,目前来看并无实际用途, +//本源文件下面定义的的可读写及只读数据可以合并到其他数据节中去(.detourd->.data , .detourc->.rdata) +//合并到其他节中能使生成的程序更小 +//The following two sections should be mainly for the convenience of Detours official check whether a certain program uses Detours, currently there is no practical use, +//The read-write and read-only data defined below this source file can be merged into other data sections (.detourd->.data, .detourc->.rdata) +//Merge into other sections to make the generated program smaller //#pragma data_seg(".detourd") //#pragma const_seg(".detourc") diff --git a/src/modules.cpp b/src/modules.cpp index 8234c169..037fd572 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -859,7 +859,8 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 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. - //Ѿ֧(δ֪ĿλIL뼴ʱɵ64λ̵ı)CLRͷݻָ + //现在我们已经支持上述这种情况(未知目标位的IL代码即时编译生成到64位进程的本机代码)的CLR头数据恢复了 + //Now we have supported the recovery of CLR header data in the above situation (IL code of unknown target bit is compiled into native code of 64-bit process by instant compilation) fUpdated32To64 = TRUE; } @@ -871,7 +872,8 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, CopyMemory(pder->pidh, &pder->idh, pder->cbidh); CopyMemory(pder->pinh, &pder->inh, pder->cbinh); - //fUpdated32To64ΪTRUEʱҲԻָˣĿǰʵֻǻָclr.Flagsֶ + //fUpdated32To64为TRUE时现在也可以恢复了,目前实际上只是恢复了clr.Flags这个字段 + //It can be restored now when fUpdated32To64 is TRUE. At present, only the clr.Flags field is restored. if (pder->pclr != NULL /*&& !fUpdated32To64*/) { if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr, PAGE_EXECUTE_READWRITE, &dwPermClr)) { @@ -888,7 +890,8 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, VirtualProtect(pder->pidh, pder->cbidh, dwPermIdh, &dwIgnore); } - //ָɹɾøԷֹظִлָ + //恢复成功后删除该负载以防止被重复执行恢复 + //Delete the payload after successful recovery to prevent repeated recovery if (fSucceeded) { HMODULE hModule = DetourGetContainingModule(pder); diff --git a/src/uimports.cpp b/src/uimports.cpp index 114215fd..dcf9caad 100644 --- a/src/uimports.cpp +++ b/src/uimports.cpp @@ -102,10 +102,12 @@ static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess, } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //ӵĴ + //添加的代码 + //Added code if (inh.IMPORT_DIRECTORY.VirtualAddress!=NULL && inh.IMPORT_DIRECTORY.Size==0) { - //ÿǻıPEļ,ΪԭPEͷĸϢѱ,ָ,ıֻΪĴ + //不用考虑会改变PE文件的问题,因为原PE头的负载信息已保存,会恢复的,这里改变只是为了下面的代码能正常工作 + //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); IMAGE_IMPORT_DESCRIPTOR ImageImport; @@ -124,8 +126,10 @@ static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess, } ++pImageImport; } - OutputDebugString(TEXT("PEļڵ,ǵСȴΪ0,һ,") - TEXT("޸ij޷,ΪԶ޸ĵС\r\n")); + //OutputDebugString(TEXT("【这个PE文件存在导入表,但是导入表大小却标记为0,这是一个错误,") + // TEXT("不修复将导致启动的程序无法正常工作,已为你自动修复了它的导入表大小!!!】\r\n")); + OutputDebugString(TEXT("[This PE file has an import table, but the import table size is marked as 0. This is an error.") + TEXT("Not repair will cause the launched program to not work normally, and its import table size has been automatically repaired for you! ! !】\r\n")); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From bd317cc1207a3968418f5ca9b4e59b745e3c3613 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Thu, 27 Aug 2020 23:38:10 +0800 Subject: [PATCH 17/21] re save as UTF8-BOM for fix build warning, but it's not compat with old vc. if you need to compat with old vc, please save as ANSI, but it will arise messy code problem. --- src/creatwth.cpp | 2 +- src/detours.cpp | 2 +- src/detours.h | 2 +- src/detver.h | 2 +- src/disasm.cpp | 2 +- src/disolarm.cpp | 2 +- src/disolarm64.cpp | 2 +- src/disolia64.cpp | 2 +- src/disolx64.cpp | 2 +- src/disolx86.cpp | 2 +- src/image.cpp | 2 +- src/modules.cpp | 2 +- src/uimports.cpp | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 968a38a3..40529a01 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -1,4 +1,4 @@ -////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// // // Create a process with a DLL (creatwth.cpp of detours.lib) // diff --git a/src/detours.cpp b/src/detours.cpp index e0e36070..d5d27f6e 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -1,4 +1,4 @@ -////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// // // Core Detours Functionality (detours.cpp of detours.lib) // diff --git a/src/detours.h b/src/detours.h index 32b004b9..44072d45 100644 --- a/src/detours.h +++ b/src/detours.h @@ -1,4 +1,4 @@ -///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// // // Core Detours Functionality (detours.h of detours.lib) // diff --git a/src/detver.h b/src/detver.h index 3d4f5448..b155bfff 100644 --- a/src/detver.h +++ b/src/detver.h @@ -1,4 +1,4 @@ -////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// // // Common version parameters. // diff --git a/src/disasm.cpp b/src/disasm.cpp index a7c771d9..6fd74580 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -1,4 +1,4 @@ -////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// // // Detours Disassembler (disasm.cpp of detours.lib) // diff --git a/src/disolarm.cpp b/src/disolarm.cpp index 57e3a2c9..8b6fe844 100644 --- a/src/disolarm.cpp +++ b/src/disolarm.cpp @@ -1,2 +1,2 @@ -#define DETOURS_ARM_OFFLINE_LIBRARY +#define DETOURS_ARM_OFFLINE_LIBRARY #include "disasm.cpp" diff --git a/src/disolarm64.cpp b/src/disolarm64.cpp index f3a6aeb8..7e271dea 100644 --- a/src/disolarm64.cpp +++ b/src/disolarm64.cpp @@ -1,2 +1,2 @@ -#define DETOURS_ARM64_OFFLINE_LIBRARY +#define DETOURS_ARM64_OFFLINE_LIBRARY #include "disasm.cpp" diff --git a/src/disolia64.cpp b/src/disolia64.cpp index 9dd2410e..48b51a44 100644 --- a/src/disolia64.cpp +++ b/src/disolia64.cpp @@ -1,2 +1,2 @@ -#define DETOURS_IA64_OFFLINE_LIBRARY +#define DETOURS_IA64_OFFLINE_LIBRARY #include "disasm.cpp" diff --git a/src/disolx64.cpp b/src/disolx64.cpp index cd05a006..993a9df1 100644 --- a/src/disolx64.cpp +++ b/src/disolx64.cpp @@ -1,2 +1,2 @@ -#define DETOURS_X64_OFFLINE_LIBRARY +#define DETOURS_X64_OFFLINE_LIBRARY #include "disasm.cpp" diff --git a/src/disolx86.cpp b/src/disolx86.cpp index 91ff7d9a..7bb3e8b9 100644 --- a/src/disolx86.cpp +++ b/src/disolx86.cpp @@ -1,2 +1,2 @@ -#define DETOURS_X86_OFFLINE_LIBRARY +#define DETOURS_X86_OFFLINE_LIBRARY #include "disasm.cpp" diff --git a/src/image.cpp b/src/image.cpp index 1ba75a5d..9500fb3e 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -1,4 +1,4 @@ -////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// // // Image manipulation functions (image.cpp of detours.lib) // diff --git a/src/modules.cpp b/src/modules.cpp index 037fd572..4911ae81 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -1,4 +1,4 @@ -////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// // // Module Enumeration Functions (modules.cpp of detours.lib) // diff --git a/src/uimports.cpp b/src/uimports.cpp index dcf9caad..02aa0615 100644 --- a/src/uimports.cpp +++ b/src/uimports.cpp @@ -1,4 +1,4 @@ -////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// // // Add DLLs to a module import table (uimports.cpp of detours.lib) // From 39871e1b28f8bd463e178e84a4b2cb77c15fecbf Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Thu, 27 Aug 2020 23:56:56 +0800 Subject: [PATCH 18/21] fix for online build --- src/uimports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uimports.cpp b/src/uimports.cpp index 02aa0615..69af0491 100644 --- a/src/uimports.cpp +++ b/src/uimports.cpp @@ -129,7 +129,7 @@ static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess, //OutputDebugString(TEXT("【这个PE文件存在导入表,但是导入表大小却标记为0,这是一个错误,") // TEXT("不修复将导致启动的程序无法正常工作,已为你自动修复了它的导入表大小!!!】\r\n")); OutputDebugString(TEXT("[This PE file has an import table, but the import table size is marked as 0. This is an error.") - TEXT("Not repair will cause the launched program to not work normally, and its import table size has been automatically repaired for you! ! !】\r\n")); + TEXT("Not repair will cause the launched program to not work normally, and its import table size has been automatically repaired for you! ! !]\r\n")); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From 146bdf2d08361055119d47017de113bdb4f43349 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Wed, 2 Sep 2020 20:53:00 +0800 Subject: [PATCH 19/21] fix for online build --- src/detours.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/detours.cpp b/src/detours.cpp index d5d27f6e..117a409e 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -2260,13 +2260,19 @@ static PZwQuerySystemInformation fnZwQuerySystemInformation = NULL; //========================================================================= static BOOL CreateProcessSnapshot(VOID** snapshotContext) { + HMODULE hModule = NULL; ULONG cbBuffer = 1024 * 1024; // 1Mb - default process information buffer size (that's enough in most cases for high-loaded systems) LPVOID pBuffer = NULL; NTSTATUS status = 0; if (!fnZwQuerySystemInformation) { - fnZwQuerySystemInformation = (PZwQuerySystemInformation)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "ZwQuerySystemInformation"); + hModule = GetModuleHandle(TEXT("ntdll.dll")); + if (!hModule) + { + return FALSE; + } + fnZwQuerySystemInformation = (PZwQuerySystemInformation)GetProcAddress(hModule, "ZwQuerySystemInformation"); if (!fnZwQuerySystemInformation) { return FALSE; From 025fe0acd4754a5e14ac330dcf3928e648f13e9a Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Wed, 2 Sep 2020 22:59:40 +0800 Subject: [PATCH 20/21] fix for online build --- src/creatwth.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 11becfad..928802bf 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -516,7 +516,12 @@ namespace Detour BOOL Is64BitOS() { BOOL bRet = FALSE; - VOID(WINAPI * _GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall *)(LPSYSTEM_INFO))GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); + HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + if (!hModule) + { + return bRet; + } + VOID(WINAPI * _GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall *)(LPSYSTEM_INFO))GetProcAddress(hModule, "GetNativeSystemInfo"); if (!_GetNativeSystemInfo) { return bRet; @@ -540,14 +545,18 @@ namespace Detour { if (Is64BitOS()) { - static BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, - OUT PBOOL Wow64Process) - = (BOOL(__stdcall *)(HANDLE, PBOOL))GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "IsWow64Process"); - BOOL bX86ProcessRunAt64BitOS; - if (_IsWow64Process && _IsWow64Process(hProcess, &bX86ProcessRunAt64BitOS) && bX86ProcessRunAt64BitOS == FALSE) - { - bRet = TRUE; - } + HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + if (hModule) + { + BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, + OUT PBOOL Wow64Process) + = (BOOL(__stdcall*)(HANDLE, PBOOL))GetProcAddress(hModule, "IsWow64Process"); + BOOL bX86ProcessRunAt64BitOS; + if (_IsWow64Process && _IsWow64Process(hProcess, &bX86ProcessRunAt64BitOS) && bX86ProcessRunAt64BitOS == FALSE) + { + bRet = TRUE; + } + } } } return bRet; From 85bf59f9fc1b9cede507ab10f12726b52a771846 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Thu, 3 Sep 2020 10:01:18 +0800 Subject: [PATCH 21/21] switch vc project file ConfigurationType to MAKEFILE, because Utility type can`t support to set clean command. but MAKEFILE can`t support to set PlatformToolset version in project properties window, so if you need to change PlatformToolset version, you must change ConfigurationType to other types temporarily or edit it in project xml file manually. --- vc/Detours.vcxproj | 135 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 112 insertions(+), 23 deletions(-) diff --git a/vc/Detours.vcxproj b/vc/Detours.vcxproj index f4479564..e159eeed 100644 --- a/vc/Detours.vcxproj +++ b/vc/Detours.vcxproj @@ -43,49 +43,49 @@ - Utility + Makefile true v142 Unicode - Utility + Makefile false v142 Unicode - Utility + Makefile true v142 Unicode - Utility + Makefile true v142 Unicode - Utility + Makefile true v142 Unicode - Utility + Makefile false v142 Unicode - Utility + Makefile false v142 Unicode - Utility + Makefile false v142 Unicode @@ -119,13 +119,102 @@ - - - - - - - + + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean + + + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean + + + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean + + + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean + + + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean + + + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean + + + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean + + + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean +nmake + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) +cd .. +nmake clean + Level4 @@ -142,7 +231,7 @@ - SET DETOURS_TARGET_PROCESSOR=X86 + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) cd .. nmake @@ -166,7 +255,7 @@ nmake - SET DETOURS_TARGET_PROCESSOR=X64 + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) cd .. nmake @@ -192,7 +281,7 @@ nmake - SET DETOURS_TARGET_PROCESSOR=ARM + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) cd .. nmake @@ -218,7 +307,7 @@ nmake - SET DETOURS_TARGET_PROCESSOR=ARM64 + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) cd .. nmake @@ -242,7 +331,7 @@ nmake - SET DETOURS_TARGET_PROCESSOR=X86 + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) cd .. nmake @@ -268,7 +357,7 @@ nmake - SET DETOURS_TARGET_PROCESSOR=X64 + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) cd .. nmake @@ -296,7 +385,7 @@ nmake - SET DETOURS_TARGET_PROCESSOR=ARM + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) cd .. nmake @@ -324,7 +413,7 @@ nmake - SET DETOURS_TARGET_PROCESSOR=ARM64 + SET DETOURS_TARGET_PROCESSOR=$(PlatformTarget) cd .. nmake