Repository: JemmyLoveJenny/HookSigntool Branch: master Commit: 11c7a536f08f Files: 13 Total size: 64.0 KB Directory structure: gitextract_rx4wp0bm/ ├── .gitignore ├── HookSigntool.sln ├── HookSigntool.vcxproj ├── HookSigntool.vcxproj.filters ├── HookSigntool.vcxproj.user ├── README.md ├── include/ │ ├── detours.h │ ├── detver.h │ └── syelog.h ├── lib/ │ ├── detours.lib │ └── syelog.lib ├── main.cpp └── mssign32.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .vs/ .vscode/ Release/ ================================================ FILE: HookSigntool.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29306.81 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HookSigntool", "HookSigntool.vcxproj", "{E3ACE1E9-7437-4DA6-8B12-1A9A1870AF33}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {E3ACE1E9-7437-4DA6-8B12-1A9A1870AF33}.Release|x86.ActiveCfg = Release|Win32 {E3ACE1E9-7437-4DA6-8B12-1A9A1870AF33}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8E08657D-FDF4-4C23-87B8-23026AD83104} EndGlobalSection EndGlobal ================================================ FILE: HookSigntool.vcxproj ================================================ Release Win32 15.0 {E3ACE1E9-7437-4DA6-8B12-1A9A1870AF33} HookSigntool 10.0 DynamicLibrary false v142 true MultiByte include;$(VC_IncludePath);$(WindowsSDK_IncludePath); lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 Level3 MaxSpeed true true true true true true ================================================ FILE: HookSigntool.vcxproj.filters ================================================  {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 {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 源文件 头文件 头文件 头文件 头文件 ================================================ FILE: HookSigntool.vcxproj.user ================================================  ================================================ FILE: README.md ================================================ # HookSigntool ## 简介 本项目编译结果为`HookSigntool.dll`,用于亚洲诚信数字签名工具(或其他类似的签名工具,如天威诚信代码签名证书助手,沃通代码签名工具,环玺信息数字签名工具等等)它的作用如下: 1. Hook数字签名工具对证书有效期的判断,无需修改系统的时间,即可用过期的证书进行数字签名。 2. 增加自建的时间戳服务器,配合过期证书使用,伪造证书有效期内的时间戳签名,使得整个签名能被验证。(此功能需要修改数字签名工具本身) ## 原理 编译出的`HookSigntool.dll`通过微软的Detours库Hook了签名工具的函数调用以达到目的 总共Hook了6个函数: 1. [crypt32.dll!CertVerifyTimeValidity](https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certverifytimevalidity) 返回值改为0,让签名工具误以为所有证书都在有效期内,以便在不修改系统时间的情况下用过期证书签名。 2. [mssign32!SignerSign](https://docs.microsoft.com/en-us/windows/win32/seccrypto/signersign) 传入参数 pwszHttpTimeStamp 修改为自建时间戳地址(自建时间戳接受地址中设定的时间,用以伪造签名) 3. [mssign32!SignerTimeStamp](https://docs.microsoft.com/en-us/windows/win32/seccrypto/signertimestamp) 同上 4. [mssign32!SignerTimeStampEx2](https://docs.microsoft.com/zh-cn/windows/win32/seccrypto/signertimestampex2) 同上 5. [mssign32!SignerTimeStampEx3](https://docs.microsoft.com/zh-cn/windows/win32/seccrypto/signertimestampex3) 同上 (此函数在 Windows 7 上不存在) 6. [kernel32.dll!GetLocalTime](https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlocaltime) 返回值根据配置文件修改,对于程序功能无影响。 ## 用法 这个`dll`有两种设置方法,一种是`ini`文件,另一种是命令行参数 ### 时间表示方法 本程序所用的时间表示方法为SimpleDateFormat,即格式为 `yyyy-MM-dd'T'HH:mm:ss` 的UTC时间 北京时间是UTC+8,所以时间需要减掉8小时才能变成UTC时间 举几个例子: 北京时间 `2011-04-01 08:00:00`,表示为 `2011-04-01T00:00:00` 北京时间 `2019-03-10 10:25:34`,表示为 `2019-03-10T02:25:34` ### ini文件 程序默认使用同目录下的`hook.ini`,当然,也可以通过命令行参数`-config`指定其他`ini`文件 ``` ;[Timestamp]Section中设置SignerTimeStamp的参数 ;本处设置的是时间戳签名伪造的默认时间(SimpleDateFormat) ;可以通过命令行 -ts 参数传递替换的Timestamp [Timestamp] Timestamp=2011-04-01T00:00:00 ;[Time]Section中设置GetLocalTime的返回值 ;本处设置的时间不判断证书有效期,也不是时间戳时间,仅仅影响证书管理界面的证书颜色(到期天数) ;如需设置,请请删除注释分号 [Time] ;Year=2011 ;Month=4 ;Day=1 ;Hour=0 ;Minute=0 ;Second=0 ``` ### 命令行参数 向数字签名工具的`exe`文件传递启动参数(如亚洲诚信数字签名工具,则是对`DSigntool.exe`传递参数) #### -config 指定一个如上描述的`ini`文件的位置(相对路径或绝对路径),比如: ``` DSigntool.exe -config hook.ini DSigntool.exe -config ../another.ini DSigntool.exe -config D:\Signtool\config.ini ``` #### -ts 指定时间戳需要伪造的签名时间,用SimpleDateFormat表示 `-ts`传递的时间优先级高于`ini`文件中配置的时间,因此`-ts`和`-config`参数同时存在时,程序使用`-ts`的时间 ``` DSigntool.exe -ts 2011-04-01T00:00:00 DSigntool.exe -ts 2019-03-10T02:25:34 ``` ### 快捷方式 由于有命令行参数启动这种方式,所以可以通过lnk快捷方式启动数字签名工具,来达到修改时间戳日期的功能。 编辑指向数字签名工具的lnk快捷方式,在目标后面加上`-ts`参数即可。例如: ``` 目标 "C:\Program Files (x86)\DSignTool\DSignTool.exe" -ts 2015-04-01T00:00:00 起始位置 "C:\Program Files (x86)\DSignTool" ``` 通过这个lnk启动的数字签名工具就被设定了时间戳日期。 也可以根据需要制作多个不同的快捷方式,设定不同的时间。 ## 编译 编译环境:Visual Studio 2019 (生成工具v142) 依赖库:[Detours](https://github.com/Microsoft/Detours)库 编译步骤: 1. 下载微软Detours库 https://www.microsoft.com/en-us/download/details.aspx?id=52586 并解压缩 2. 开始菜单中打开`x86 Native Tools Command Prompt for VS 2019`,进入解压缩的Detours目录,运行`nmake`,编译出x86的lib (x64无需编译) 3. 将Detours目录下`include`,`lib.X86`目录下的文件复制到 `C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\{Version}`目录的`include`,`lib\x86`子目录中,完成Detours的安装 4. 打开项目文件`HookSigntool.sln`解决方案配置为Release,直接编译即可。 ## 修改数字签名工具 想要数字签名工具加载`HookSigntool.dll`则需要用LordPE等工具修改这个`exe`的导入表,向导入表添加`HookSigntool.dll!attach` ### 绕过证书有效期验证 这个比较容易,只要签名工具加载了本`dll`,无需任何操作即可成功。 ### 添加自定义时间戳 需要将软件内置的时间戳地址替换为特殊标记(包括`http://`部分整个替换) 一般是用十六进制编辑器直接找到字符串进行替换,原字符串的多余长度用 0x00 填充 SHA1的时间戳地址整个替换为 `{CustomTimestampMarker-SHA1}` SHA256的时间戳地址整个替换为 `{CustomTimestampMarker-SHA256}` 这个标记与时间戳协议无关,无论是Authenticode还是RFC3161都相同 dll会特异性识别这个标记,自动将它修改为时间戳地址 ## 关于时间戳服务器 时间戳服务器是我自己编写搭建的,域名是 `timestamp.pki.jemmylovejenny.tk` 根证书由我自己签发,时间戳有两条证书链,分别为SHA1和SHA256 以当前时间签名时,服务器地址是`http://timestamp.pki.jemmylovejenny.tk/SHA1/`和`http://timestamp.pki.jemmylovejenny.tk/SHA256/` 伪造任意时间的时间戳签名时,服务器地址在以上基础上加上SimpleDateFormat表示的时间,例如: ``` http://timestamp.pki.jemmylovejenny.tk/SHA1/2011-04-01T00:00:00 http://timestamp.pki.jemmylovejenny.tk/SHA256/2019-03-10T02:25:34 ``` Authenticode和RFC3161协议的地址都是相同的,服务器会根据请求的不同自动识别并处理。 域名中的`timestamp`可以简写为`tsa`,即`tsa.pki.jemmylovejenny.tk` ### 配合微软signtool使用 首先将程序签好名(不带时间戳),假设有N个签名 那么对于第一个签名打时间戳:`signtool timestamp /t "" ` 对于之后的任意个签名打时间戳:`signtool timestamp /tp /tr "" ` 其中`URL`为时间戳服务器地址,`index`从1开始递增,例如: ``` signtool timestamp /t "http://tsa.pki.jemmylovejenny.tk/SHA1/2011-04-01T00:00:00" test.exe signtool timestamp /tp 1 /tr "http://tsa.pki.jemmylovejenny.tk/SHA256/2011-04-01T00:00:00" test.exe ``` ## 关于驱动签名 根据微软的最新签名策略 https://docs.microsoft.com/en-us/windows-hardware/drivers/install/kernel-mode-code-signing-policy--windows-vista-and-later- 任何有`Microsoft Code Verification Root`交叉签名,且颁发日期在2015-07-29以前的代码签名证书,配合伪造的时间戳签名,可以生成一个在任意Windows版本下都有效的驱动签名。 因此,采用泄露的证书,信任自建时间戳根证书,就可以在WinXP~Win10(SecureBoot Enabled)任意版本成功加载驱动。 ## 关于我的自建PKI 我的自建PKI根证书为`JemmyLoveJenny EV Root CA`,我使用的所有自签名证书都由它颁发。 本程序使用的自建时间戳服务器的证书也不例外,因此想要时间戳受信,需要手动信任这个根证书。 更多信息请访问`https://pki.jemmylovejenny.tk/` ================================================ FILE: include/detours.h ================================================ ///////////////////////////////////////////////////////////////////////////// // // Core Detours Functionality (detours.h of detours.lib) // // Microsoft Research Detours Package, Version 3.0 Build_343. // // Copyright (c) Microsoft Corporation. All rights reserved. // #pragma once #ifndef _DETOURS_H_ #define _DETOURS_H_ #define DETOURS_VERSION 30001 // 3.00.01 ////////////////////////////////////////////////////////////////////////////// // #undef DETOURS_X64 #undef DETOURS_X86 #undef DETOURS_IA64 #undef DETOURS_ARM #undef DETOURS_ARM64 #undef DETOURS_BITS #undef DETOURS_32BIT #undef DETOURS_64BIT #if defined(_X86_) #define DETOURS_X86 #define DETOURS_OPTION_BITS 64 #elif defined(_AMD64_) #define DETOURS_X64 #define DETOURS_OPTION_BITS 32 #elif defined(_IA64_) #define DETOURS_IA64 #define DETOURS_OPTION_BITS 32 #elif defined(_ARM_) #define DETOURS_ARM #elif defined(_ARM64_) #define DETOURS_ARM64 #else #error Unknown architecture (x86, amd64, ia64, arm, arm64) #endif #ifdef _WIN64 #undef DETOURS_32BIT #define DETOURS_64BIT 1 #define DETOURS_BITS 64 // If all 64bit kernels can run one and only one 32bit architecture. //#define DETOURS_OPTION_BITS 32 #else #define DETOURS_32BIT 1 #undef DETOURS_64BIT #define DETOURS_BITS 32 // If all 64bit kernels can run one and only one 32bit architecture. //#define DETOURS_OPTION_BITS 32 #endif #define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS) ////////////////////////////////////////////////////////////////////////////// // #if (_MSC_VER < 1299) typedef LONG LONG_PTR; typedef ULONG ULONG_PTR; #endif ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. // // These definitions are include so that Detours will build even if the // compiler doesn't have full SAL 2.0 support. // #ifndef DETOURS_DONT_REMOVE_SAL_20 #ifdef DETOURS_TEST_REMOVE_SAL_20 #undef _Analysis_assume_ #undef _Benign_race_begin_ #undef _Benign_race_end_ #undef _Field_range_ #undef _Field_size_ #undef _In_ #undef _In_bytecount_ #undef _In_count_ #undef _In_opt_ #undef _In_opt_bytecount_ #undef _In_opt_count_ #undef _In_opt_z_ #undef _In_range_ #undef _In_reads_ #undef _In_reads_bytes_ #undef _In_reads_opt_ #undef _In_reads_opt_bytes_ #undef _In_reads_or_z_ #undef _In_z_ #undef _Inout_ #undef _Inout_opt_ #undef _Inout_z_count_ #undef _Out_ #undef _Out_opt_ #undef _Out_writes_ #undef _Outptr_result_maybenull_ #undef _Readable_bytes_ #undef _Success_ #undef _Writable_bytes_ #undef _Pre_notnull_ #endif #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) #define _Outptr_result_maybenull_ _Deref_out_opt_z_ #endif #if defined(_In_count_) && !defined(_In_reads_) #define _In_reads_(x) _In_count_(x) #endif #if defined(_In_opt_count_) && !defined(_In_reads_opt_) #define _In_reads_opt_(x) _In_opt_count_(x) #endif #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) #endif #if defined(_In_bytecount_) && !defined(_In_reads_bytes_) #define _In_reads_bytes_(x) _In_bytecount_(x) #endif #ifndef _In_ #define _In_ #endif #ifndef _In_bytecount_ #define _In_bytecount_(x) #endif #ifndef _In_count_ #define _In_count_(x) #endif #ifndef _In_opt_ #define _In_opt_ #endif #ifndef _In_opt_bytecount_ #define _In_opt_bytecount_(x) #endif #ifndef _In_opt_count_ #define _In_opt_count_(x) #endif #ifndef _In_opt_z_ #define _In_opt_z_ #endif #ifndef _In_range_ #define _In_range_(x,y) #endif #ifndef _In_reads_ #define _In_reads_(x) #endif #ifndef _In_reads_bytes_ #define _In_reads_bytes_(x) #endif #ifndef _In_reads_opt_ #define _In_reads_opt_(x) #endif #ifndef _In_reads_opt_bytes_ #define _In_reads_opt_bytes_(x) #endif #ifndef _In_reads_or_z_ #define _In_reads_or_z_ #endif #ifndef _In_z_ #define _In_z_ #endif #ifndef _Inout_ #define _Inout_ #endif #ifndef _Inout_opt_ #define _Inout_opt_ #endif #ifndef _Inout_z_count_ #define _Inout_z_count_(x) #endif #ifndef _Out_ #define _Out_ #endif #ifndef _Out_opt_ #define _Out_opt_ #endif #ifndef _Out_writes_ #define _Out_writes_(x) #endif #ifndef _Outptr_result_maybenull_ #define _Outptr_result_maybenull_ #endif #ifndef _Writable_bytes_ #define _Writable_bytes_(x) #endif #ifndef _Readable_bytes_ #define _Readable_bytes_(x) #endif #ifndef _Success_ #define _Success_(x) #endif #ifndef _Pre_notnull_ #define _Pre_notnull_ #endif #ifdef DETOURS_INTERNAL #pragma warning(disable:4615) // unknown warning type (suppress with older compilers) #ifndef _Benign_race_begin_ #define _Benign_race_begin_ #endif #ifndef _Benign_race_end_ #define _Benign_race_end_ #endif #ifndef _Field_size_ #define _Field_size_(x) #endif #ifndef _Field_range_ #define _Field_range_(x,y) #endif #ifndef _Analysis_assume_ #define _Analysis_assume_(x) #endif #endif // DETOURS_INTERNAL #endif // DETOURS_DONT_REMOVE_SAL_20 ////////////////////////////////////////////////////////////////////////////// // #ifndef GUID_DEFINED #define GUID_DEFINED typedef struct _GUID { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[ 8 ]; } GUID; #ifdef INITGUID #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ const GUID name \ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } #else #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ const GUID name #endif // INITGUID #endif // !GUID_DEFINED #if defined(__cplusplus) #ifndef _REFGUID_DEFINED #define _REFGUID_DEFINED #define REFGUID const GUID & #endif // !_REFGUID_DEFINED #else // !__cplusplus #ifndef _REFGUID_DEFINED #define _REFGUID_DEFINED #define REFGUID const GUID * const #endif // !_REFGUID_DEFINED #endif // !__cplusplus #ifndef ARRAYSIZE #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) #endif // ////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus extern "C" { #endif // __cplusplus /////////////////////////////////////////////////// Instruction Target Macros. // #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" extern const GUID DETOUR_EXE_RESTORE_GUID; extern const GUID DETOUR_EXE_HELPER_GUID; #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; /////////////////////////////////////////////////////////// Binary Structures. // #pragma pack(push, 8) typedef struct _DETOUR_SECTION_HEADER { DWORD cbHeaderSize; DWORD nSignature; DWORD nDataOffset; DWORD cbDataSize; DWORD nOriginalImportVirtualAddress; DWORD nOriginalImportSize; DWORD nOriginalBoundImportVirtualAddress; DWORD nOriginalBoundImportSize; DWORD nOriginalIatVirtualAddress; DWORD nOriginalIatSize; DWORD nOriginalSizeOfImage; DWORD cbPrePE; DWORD nOriginalClrFlags; DWORD reserved1; DWORD reserved2; DWORD reserved3; // Followed by cbPrePE bytes of data. } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; typedef struct _DETOUR_SECTION_RECORD { DWORD cbBytes; DWORD nReserved; GUID guid; } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; typedef struct _DETOUR_CLR_HEADER { // Header versioning ULONG cb; USHORT MajorRuntimeVersion; USHORT MinorRuntimeVersion; // Symbol table and startup information IMAGE_DATA_DIRECTORY MetaData; ULONG Flags; // Followed by the rest of the IMAGE_COR20_HEADER } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; typedef struct _DETOUR_EXE_RESTORE { DWORD cb; DWORD cbidh; DWORD cbinh; DWORD cbclr; PBYTE pidh; PBYTE pinh; PBYTE pclr; IMAGE_DOS_HEADER idh; union { IMAGE_NT_HEADERS inh; IMAGE_NT_HEADERS32 inh32; IMAGE_NT_HEADERS64 inh64; BYTE raw[sizeof(IMAGE_NT_HEADERS64) + sizeof(IMAGE_SECTION_HEADER) * 32]; }; DETOUR_CLR_HEADER clr; } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; typedef struct _DETOUR_EXE_HELPER { DWORD cb; DWORD pid; DWORD nDlls; CHAR rDlls[4]; } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; #pragma pack(pop) #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ { \ sizeof(DETOUR_SECTION_HEADER),\ DETOUR_SECTION_HEADER_SIGNATURE,\ sizeof(DETOUR_SECTION_HEADER),\ (cbSectionSize),\ \ 0,\ 0,\ 0,\ 0,\ \ 0,\ 0,\ 0,\ 0,\ } /////////////////////////////////////////////////////////////// Helper Macros. // #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) #define DETOURS_STRINGIFY_(x) #x ///////////////////////////////////////////////////////////// Binary Typedefs. // typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( _In_opt_ PVOID pContext, _In_opt_ LPCSTR pszFile, _Outptr_result_maybenull_ LPCSTR *ppszOutFile); typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( _In_opt_ PVOID pContext, _In_ LPCSTR pszOrigFile, _In_ LPCSTR pszFile, _Outptr_result_maybenull_ LPCSTR *ppszOutFile); typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( _In_opt_ PVOID pContext, _In_ ULONG nOrigOrdinal, _In_ ULONG nOrdinal, _Out_ ULONG *pnOutOrdinal, _In_opt_ LPCSTR pszOrigSymbol, _In_opt_ LPCSTR pszSymbol, _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( _In_opt_ PVOID pContext); typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, _In_ ULONG nOrdinal, _In_opt_ LPCSTR pszName, _In_opt_ PVOID pCode); typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, _In_opt_ HMODULE hModule, _In_opt_ LPCSTR pszFile); typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, _In_ DWORD nOrdinal, _In_opt_ LPCSTR pszFunc, _In_opt_ PVOID pvFunc); // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, _In_ DWORD nOrdinal, _In_opt_ LPCSTR pszFunc, _In_opt_ PVOID* ppvFunc); typedef VOID * PDETOUR_BINARY; typedef VOID * PDETOUR_LOADED_BINARY; //////////////////////////////////////////////////////////// Transaction APIs. // LONG WINAPI DetourTransactionBegin(VOID); LONG WINAPI DetourTransactionAbort(VOID); LONG WINAPI DetourTransactionCommit(VOID); LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, _In_ PVOID pDetour); LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, _In_ PVOID pDetour, _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, _Out_opt_ PVOID *ppRealTarget, _Out_opt_ PVOID *ppRealDetour); LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, _In_ PVOID pDetour); BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); ////////////////////////////////////////////////////////////// Code Functions. // PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, _In_ LPCSTR pszFunction); PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, _Out_opt_ PVOID *ppGlobals); PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, _Inout_opt_ PVOID *ppDstPool, _In_ PVOID pSrc, _Out_opt_ PVOID *ppTarget, _Out_opt_ LONG *plExtra); BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, _In_ BOOL fLimitReferencesToModule); ///////////////////////////////////////////////////// Loaded Binary Functions. // HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, _In_opt_ PVOID pContext, _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); 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); 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 pfImportFuncEx); _Writable_bytes_(*pcbData) _Readable_bytes_(*pcbData) _Success_(return != NULL) PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, _In_ REFGUID rguid, _Out_ DWORD *pcbData); _Writable_bytes_(*pcbData) _Readable_bytes_(*pcbData) _Success_(return != NULL) PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, _Out_ DWORD * pcbData); DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); ///////////////////////////////////////////////// Persistent Binary Functions. // PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); _Writable_bytes_(*pcbData) _Readable_bytes_(*pcbData) _Success_(return != NULL) PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, _Out_opt_ GUID *pGuid, _Out_ DWORD *pcbData, _Inout_ DWORD *pnIterator); _Writable_bytes_(*pcbData) _Readable_bytes_(*pcbData) _Success_(return != NULL) PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid, _Out_ DWORD *pcbData); PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid, _In_reads_opt_(cbData) PVOID pData, _In_ DWORD cbData); BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, _In_opt_ PVOID pContext, _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); /////////////////////////////////////////////////// Create Process & Load Dll. // typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( _In_opt_ LPCSTR lpApplicationName, _Inout_opt_ LPSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCSTR lpCurrentDirectory, _In_ LPSTARTUPINFOA lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation); typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( _In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation); BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, _Inout_opt_ LPSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCSTR lpCurrentDirectory, _In_ LPSTARTUPINFOA lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation, _In_ LPCSTR lpDllName, _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation, _In_ LPCSTR lpDllName, _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); #ifdef UNICODE #define DetourCreateProcessWithDll DetourCreateProcessWithDllW #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW #else #define DetourCreateProcessWithDll DetourCreateProcessWithDllA #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA #endif // !UNICODE BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, _Inout_opt_ LPSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCSTR lpCurrentDirectory, _In_ LPSTARTUPINFOA lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation, _In_ LPCSTR lpDllName, _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation, _In_ LPCSTR lpDllName, _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); #ifdef UNICODE #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW #else #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA #endif // !UNICODE BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, _Inout_opt_ LPSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCSTR lpCurrentDirectory, _In_ LPSTARTUPINFOA lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation, _In_ DWORD nDlls, _In_reads_(nDlls) LPCSTR *rlpDlls, _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation, _In_ DWORD nDlls, _In_reads_(nDlls) LPCSTR *rlpDlls, _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); #ifdef UNICODE #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW #else #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA #endif // !UNICODE BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, _In_ LPCSTR lpDllName, _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, _In_ LPCSTR lpDllName, _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); #ifdef UNICODE #define DetourProcessViaHelper DetourProcessViaHelperW #else #define DetourProcessViaHelper DetourProcessViaHelperA #endif // !UNICODE BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, _In_ DWORD nDlls, _In_reads_(nDlls) LPCSTR *rlpDlls, _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, _In_ DWORD nDlls, _In_reads_(nDlls) LPCSTR *rlpDlls, _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); #ifdef UNICODE #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW #else #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA #endif // !UNICODE BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, _In_reads_(nDlls) LPCSTR *rlpDlls, _In_ DWORD nDlls); BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, _In_ HMODULE hImage, _In_ BOOL bIs32Bit, _In_reads_(nDlls) LPCSTR *rlpDlls, _In_ DWORD nDlls); BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, _In_ REFGUID rguid, _In_reads_bytes_(cbData) PVOID pvData, _In_ DWORD cbData); BOOL WINAPI DetourRestoreAfterWith(VOID); BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, _In_ DWORD cbData); BOOL WINAPI DetourIsHelperProcess(VOID); VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, _In_ HINSTANCE, _In_ LPSTR, _In_ INT); // ////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus } #endif // __cplusplus //////////////////////////////////////////////// Detours Internal Definitions. // #ifdef __cplusplus #ifdef DETOURS_INTERNAL #define NOTHROW // #define NOTHROW (nothrow) ////////////////////////////////////////////////////////////////////////////// // #if (_MSC_VER < 1299) #include typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; typedef IMAGEHLP_SYMBOL SYMBOL_INFO; typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; static inline LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) { return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); } #else #pragma warning(push) #pragma warning(disable:4091) // empty typedef #include #pragma warning(pop) #endif #ifdef IMAGEAPI // defined by DBGHELP.H typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, _In_opt_ LPCSTR UserSearchPath, _In_ BOOL fInvadeProcess); typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, _In_opt_ HANDLE hFile, _In_ LPSTR ImageName, _In_opt_ LPSTR ModuleName, _In_ DWORD64 BaseOfDll, _In_opt_ DWORD SizeOfDll); typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, _In_ DWORD64 qwAddr, _Out_ PIMAGEHLP_MODULE64 ModuleInfo); typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, _In_ LPSTR Name, _Out_ PSYMBOL_INFO Symbol); typedef struct _DETOUR_SYM_INFO { HANDLE hProcess; HMODULE hDbgHelp; PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; PF_SymInitialize pfSymInitialize; PF_SymSetOptions pfSymSetOptions; PF_SymGetOptions pfSymGetOptions; PF_SymLoadModule64 pfSymLoadModule64; PF_SymGetModuleInfo64 pfSymGetModuleInfo64; PF_SymFromName pfSymFromName; } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); #endif // IMAGEAPI #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) #endif #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 #ifndef DETOUR_TRACE #if DETOUR_DEBUG #define DETOUR_TRACE(x) printf x #define DETOUR_BREAK() __debugbreak() #include #include #else #define DETOUR_TRACE(x) #define DETOUR_BREAK() #endif #endif #if 1 || defined(DETOURS_IA64) // // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. // #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) #define DETOUR_IA64_TEMPLATE_OFFSET (0) #define DETOUR_IA64_TEMPLATE_SIZE (5) #define DETOUR_IA64_INSTRUCTION_SIZE (41) #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); __declspec(align(16)) struct DETOUR_IA64_BUNDLE { public: union { BYTE data[16]; UINT64 wide[2]; }; enum { A_UNIT = 1u, I_UNIT = 2u, M_UNIT = 3u, B_UNIT = 4u, F_UNIT = 5u, L_UNIT = 6u, X_UNIT = 7u, }; struct DETOUR_IA64_METADATA { ULONG nTemplate : 8; // Instruction template. ULONG nUnit0 : 4; // Unit for slot 0 ULONG nUnit1 : 4; // Unit for slot 1 ULONG nUnit2 : 4; // Unit for slot 2 }; protected: static const DETOUR_IA64_METADATA s_rceCopyTable[33]; UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, _In_ BYTE slot, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. // 00 // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] BYTE GetTemplate() const; // Get 4 bit opcodes. BYTE GetInst0() const; BYTE GetInst1() const; BYTE GetInst2() const; BYTE GetUnit(BYTE slot) const; BYTE GetUnit0() const; BYTE GetUnit1() const; BYTE GetUnit2() const; // Get 37 bit data. UINT64 GetData0() const; UINT64 GetData1() const; UINT64 GetData2() const; // Get/set the full 41 bit instructions. UINT64 GetInstruction(BYTE slot) const; UINT64 GetInstruction0() const; UINT64 GetInstruction1() const; UINT64 GetInstruction2() const; void SetInstruction(BYTE slot, UINT64 instruction); void SetInstruction0(UINT64 instruction); void SetInstruction1(UINT64 instruction); void SetInstruction2(UINT64 instruction); // Get/set bitfields. static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); // Get specific read-only fields. static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode static UINT64 GetX(UINT64 instruction); // 1bit opcode extension static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension // Get/set specific fields. static UINT64 GetImm7a(UINT64 instruction); static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); static UINT64 GetImm13c(UINT64 instruction); static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); static UINT64 GetSignBit(UINT64 instruction); static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); static UINT64 GetImm20a(UINT64 instruction); static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); static UINT64 GetImm20b(UINT64 instruction); static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); static UINT64 SignExtend(UINT64 Value, UINT64 Offset); BOOL IsMovlGp() const; VOID SetInst(BYTE Slot, BYTE nInst); VOID SetInst0(BYTE nInst); VOID SetInst1(BYTE nInst); VOID SetInst2(BYTE nInst); VOID SetData(BYTE Slot, UINT64 nData); VOID SetData0(UINT64 nData); VOID SetData1(UINT64 nData); VOID SetData2(UINT64 nData); BOOL SetNop(BYTE Slot); BOOL SetNop0(); BOOL SetNop1(); BOOL SetNop2(); public: BOOL IsBrl() const; VOID SetBrl(); VOID SetBrl(UINT64 target); UINT64 GetBrlTarget() const; VOID SetBrlTarget(UINT64 target); VOID SetBrlImm(UINT64 imm); UINT64 GetBrlImm() const; UINT64 GetMovlGp() const; VOID SetMovlGp(UINT64 gp); VOID SetStop(); UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; }; #endif // DETOURS_IA64 #ifdef DETOURS_ARM #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) #endif // DETOURS_ARM ////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus extern "C" { #endif // __cplusplus #define DETOUR_OFFLINE_LIBRARY(x) \ PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ _Inout_opt_ PVOID *ppDstPool, \ _In_ PVOID pSrc, \ _Out_opt_ PVOID *ppTarget, \ _Out_opt_ LONG *plExtra); \ \ BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ _In_ BOOL fLimitReferencesToModule); \ DETOUR_OFFLINE_LIBRARY(X86) DETOUR_OFFLINE_LIBRARY(X64) DETOUR_OFFLINE_LIBRARY(ARM) DETOUR_OFFLINE_LIBRARY(ARM64) DETOUR_OFFLINE_LIBRARY(IA64) #undef DETOUR_OFFLINE_LIBRARY ////////////////////////////////////////////////////////////////////////////// // // Helpers for manipulating page protection. // _Success_(return != FALSE) BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, _In_ PVOID pAddress, _In_ SIZE_T nSize, _In_ DWORD dwNewProtect, _Out_ PDWORD pdwOldProtect); _Success_(return != FALSE) BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, _In_ SIZE_T nSize, _In_ DWORD dwNewProtect, _Out_ PDWORD pdwOldProtect); #ifdef __cplusplus } #endif // __cplusplus ////////////////////////////////////////////////////////////////////////////// #define MM_ALLOCATION_GRANULARITY 0x10000 ////////////////////////////////////////////////////////////////////////////// #endif // DETOURS_INTERNAL #endif // __cplusplus #endif // _DETOURS_H_ // //////////////////////////////////////////////////////////////// End of File. ================================================ FILE: include/detver.h ================================================ ////////////////////////////////////////////////////////////////////////////// // // Common version parameters. // // Microsoft Research Detours Package, Version 3.0 Build_343. // // Copyright (c) Microsoft Corporation. All rights reserved. // #define _USING_V110_SDK71_ 1 #include "winver.h" #if 0 #include #include #else #ifndef DETOURS_STRINGIFY #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) #define DETOURS_STRINGIFY_(x) #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 DETOUR_STRINGIFY(DETOURS_BITS) ================================================ FILE: include/syelog.h ================================================ ////////////////////////////////////////////////////////////////////////////// // // Detours Test Program (syelog.h of syelog.lib) // // Microsoft Research Detours Package, Version 3.0. // // Copyright (c) Microsoft Corporation. All rights reserved. // #pragma once #ifndef _SYELOGD_H_ #define _SYELOGD_H_ #include #pragma pack(push, 1) #pragma warning(push) #pragma warning(disable: 4200) ////////////////////////////////////////////////////////////////////////////// // // #define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" #define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" #ifdef UNICODE #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW #else #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA #endif ////////////////////////////////////////////////////////////////////////////// // #define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) typedef struct _SYELOG_MESSAGE { USHORT nBytes; BYTE nFacility; BYTE nSeverity; DWORD nProcessId; FILETIME ftOccurance; BOOL fTerminate; CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; } SYELOG_MESSAGE, *PSYELOG_MESSAGE; // Facility Codes. // #define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel #define SYELOG_FACILITY_SECURITY 0x20 // OS Security #define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal #define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon #define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application #define SYELOG_FACILITY_USER 0x60 // User self-generated. #define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. #define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. #define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. #define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. #define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. #define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. #define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. #define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. #define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. #define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. // Severity Codes. // #define SYELOG_SEVERITY_FATAL 0x00 // System is dead. #define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. #define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. #define SYELOG_SEVERITY_ERROR 0x30 // Error #define SYELOG_SEVERITY_WARNING 0x40 // Warning #define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. #define SYELOG_SEVERITY_INFORMATION 0x60 // Informational #define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed #define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded #define SYELOG_SEVERITY_DEBUG 0x70 // Debugging // Logging Functions. // VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); VOID SyelogClose(BOOL fTerminate); #pragma warning(pop) #pragma pack(pop) #endif // _SYELOGD_H_ // ///////////////////////////////////////////////////////////////// End of File. ================================================ FILE: main.cpp ================================================ #pragma comment(lib, "detours.lib") #define _CRT_SECURE_NO_WARNINGS #include #include #include #include "mssign32.h" HMODULE hModCrypt32 = NULL, hModMssign32 = NULL, hModKernel32 = NULL; using fntCertVerifyTimeValidity = decltype(CertVerifyTimeValidity); using fntSignerSign = decltype(SignerSign); using fntSignerTimeStamp = decltype(SignerTimeStamp); using fntSignerTimeStampEx2 = decltype(SignerTimeStampEx2); using fntSignerTimeStampEx3 = decltype(SignerTimeStampEx3); using fntGetLocalTime = decltype(GetLocalTime); fntCertVerifyTimeValidity* pOldCertVerifyTimeValidity = NULL; fntSignerSign* pOldSignerSign = NULL; fntSignerTimeStamp* pOldSignerTimeStamp = NULL; fntSignerTimeStampEx2* pOldSignerTimeStampEx2 = NULL; fntSignerTimeStampEx3* pOldSignerTimeStampEx3 = NULL; fntGetLocalTime* pOldGetLocalTime = NULL; int year = -1, month = -1, day = -1, hour = -1, minute = -1, second = -1; WCHAR lpTimestamp[20]; LPCWSTR ReplaceTimeStamp(LPCWSTR lpOriginalTS) { if (!lpOriginalTS) return NULL; LPWSTR buf = new WCHAR[65]; memset(buf, 0, sizeof(WCHAR) * 65); if (!_wcsicmp(lpOriginalTS, L"{CustomTimestampMarker-SHA1}")) { wcscat(buf, L"http://timestamp.pki.jemmylovejenny.tk/SHA1/"); wcscat(buf, lpTimestamp); return buf; } else if (!_wcsicmp(lpOriginalTS, L"{CustomTimestampMarker-SHA256}")) { wcscat(buf, L"http://timestamp.pki.jemmylovejenny.tk/SHA256/"); wcscat(buf, lpTimestamp); return buf; } else { return lpOriginalTS; } } LONG WINAPI NewCertVerifyTimeValidity( LPFILETIME pTimeToVerify, PCERT_INFO pCertInfo ) { return 0; } HRESULT WINAPI NewSignerSign( _In_ SIGNER_SUBJECT_INFO* pSubjectInfo, _In_ SIGNER_CERT* pSignerCert, _In_ SIGNER_SIGNATURE_INFO* pSignatureInfo, _In_opt_ SIGNER_PROVIDER_INFO* pProviderInfo, _In_opt_ LPCWSTR pwszHttpTimeStamp, _In_opt_ PCRYPT_ATTRIBUTES psRequest, _In_opt_ LPVOID pSipData ) { return (*pOldSignerSign)(pSubjectInfo, pSignerCert, pSignatureInfo, pProviderInfo, ReplaceTimeStamp(pwszHttpTimeStamp), psRequest, pSipData); } HRESULT WINAPI NewSignerTimeStamp( _In_ SIGNER_SUBJECT_INFO* pSubjectInfo, _In_ LPCWSTR pwszHttpTimeStamp, _In_opt_ PCRYPT_ATTRIBUTES psRequest, _In_opt_ LPVOID pSipData ) { return (*pOldSignerTimeStamp)(pSubjectInfo, ReplaceTimeStamp(pwszHttpTimeStamp), psRequest, pSipData); } HRESULT WINAPI NewSignerTimeStampEx2( _Reserved_ DWORD dwFlags, _In_ SIGNER_SUBJECT_INFO* pSubjectInfo, _In_ LPCWSTR pwszHttpTimeStamp, _In_ ALG_ID dwAlgId, _In_ PCRYPT_ATTRIBUTES psRequest, _In_ LPVOID pSipData, _Out_ SIGNER_CONTEXT** ppSignerContext ) { return (*pOldSignerTimeStampEx2)(dwFlags, pSubjectInfo, ReplaceTimeStamp(pwszHttpTimeStamp), dwAlgId, psRequest, pSipData, ppSignerContext); } HRESULT WINAPI NewSignerTimeStampEx3( _In_ DWORD dwFlags, _In_ DWORD dwIndex, _In_ SIGNER_SUBJECT_INFO* pSubjectInfo, _In_ PCWSTR pwszHttpTimeStamp, _In_ PCWSTR pszAlgorithmOid, _In_opt_ PCRYPT_ATTRIBUTES psRequest, _In_opt_ PVOID pSipData, _Out_ SIGNER_CONTEXT** ppSignerContext, _In_opt_ PCERT_STRONG_SIGN_PARA pCryptoPolicy, _Reserved_ PVOID pReserved ) { return (*pOldSignerTimeStampEx3)(dwFlags, dwIndex, pSubjectInfo, ReplaceTimeStamp(pwszHttpTimeStamp), pszAlgorithmOid, psRequest, pSipData, ppSignerContext, pCryptoPolicy, pReserved); } void WINAPI NewGetLocalTime( LPSYSTEMTIME lpSystemTime ) { (*pOldGetLocalTime)(lpSystemTime); if (year >= 0) lpSystemTime->wYear = year; if (month >= 0) lpSystemTime->wMonth = month; if (day >= 0) lpSystemTime->wDay = day; if (hour >= 0) lpSystemTime->wHour = hour; if (minute >= 0) lpSystemTime->wMinute = minute; if (second >= 0) lpSystemTime->wSecond = second; } bool HookFunctions() { if ((hModCrypt32 = LoadLibraryW(L"crypt32.dll")) == NULL || (hModMssign32 = LoadLibraryW(L"mssign32.dll")) == NULL || (hModKernel32 = LoadLibraryW(L"kernel32.dll")) == NULL) return false; if ((pOldCertVerifyTimeValidity = (fntCertVerifyTimeValidity*)GetProcAddress(hModCrypt32, "CertVerifyTimeValidity")) == NULL || (pOldSignerSign = (fntSignerSign*)GetProcAddress(hModMssign32, "SignerSign")) == NULL || (pOldSignerTimeStamp = (fntSignerTimeStamp*)GetProcAddress(hModMssign32, "SignerTimeStamp")) == NULL || (pOldSignerTimeStampEx2 = (fntSignerTimeStampEx2*)GetProcAddress(hModMssign32, "SignerTimeStampEx2")) == NULL || ((pOldSignerTimeStampEx3 = (fntSignerTimeStampEx3*)GetProcAddress(hModMssign32, "SignerTimeStampEx3")) == NULL && FALSE) /* SignerTimeStampEx3 does not exist in Windows 7 */ || (pOldGetLocalTime = (fntGetLocalTime*)GetProcAddress(hModKernel32, "GetLocalTime")) == NULL) return false; if (DetourTransactionBegin() != NO_ERROR || DetourAttach(&(PVOID&)pOldCertVerifyTimeValidity, NewCertVerifyTimeValidity) != NO_ERROR || DetourAttach(&(PVOID&)pOldSignerSign, NewSignerSign) != NO_ERROR || DetourAttach(&(PVOID&)pOldSignerTimeStamp, NewSignerTimeStamp) != NO_ERROR || DetourAttach(&(PVOID&)pOldSignerTimeStampEx2, NewSignerTimeStampEx2) != NO_ERROR || (pOldSignerTimeStampEx3 != NULL ? DetourAttach(&(PVOID&)pOldSignerTimeStampEx3, NewSignerTimeStampEx3) != NO_ERROR : FALSE) /* SignerTimeStampEx3 does not exist in Windows 7 */ || DetourAttach(&(PVOID&)pOldGetLocalTime, NewGetLocalTime) != NO_ERROR || DetourTransactionCommit() != NO_ERROR) return false; return true; } bool ParseConfig(LPWSTR lpCommandLineConfig, LPWSTR lpCommandLineTimestamp) { LPWSTR buf = new WCHAR[260]; memset(buf, 0, sizeof(WCHAR) * 260); if (_wgetcwd(buf, 260) == NULL) return false; wcscat(buf, L"\\"); if (lpCommandLineConfig) { if ((wcschr(lpCommandLineConfig, L':') - lpCommandLineConfig) == 1) { memset(buf, 0, sizeof(WCHAR) * 260); wsprintfW(buf, lpCommandLineConfig); } else { wcscat(buf, lpCommandLineConfig); } } else { wcscat(buf, L"hook.ini"); } year = GetPrivateProfileIntW(L"Time", L"Year", -1, buf); month = GetPrivateProfileIntW(L"Time", L"Month", -1, buf); day = GetPrivateProfileIntW(L"Time", L"Day", -1, buf); hour = GetPrivateProfileIntW(L"Time", L"Hour", -1, buf); minute = GetPrivateProfileIntW(L"Time", L"Minute", -1, buf); second = GetPrivateProfileIntW(L"Time", L"Second", -1, buf); if (lpCommandLineTimestamp) wsprintfW(lpTimestamp, lpCommandLineTimestamp); else GetPrivateProfileStringW(L"Timestamp", L"Timestamp", NULL, lpTimestamp, 20, buf); return true; } BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved ) { if (fdwReason == DLL_PROCESS_ATTACH) { LPWSTR* szArglist = NULL; int nArgs = 0; szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); int iconfig = -1, its = -1; for (int i = 0; i <= nArgs - 2; i++) { if (!wcscmp(szArglist[i], L"-config")) iconfig = i + 1; if (!wcscmp(szArglist[i], L"-ts")) its = i + 1; } if (!ParseConfig(iconfig >= 0 ? szArglist[iconfig] : NULL, its >= 0 ? szArglist[its] : NULL)) MessageBoxW(NULL, L"óʼʧܣhook.iniв", L"ʼʧ", MB_ICONERROR); LocalFree(szArglist); if (!HookFunctions()) MessageBoxW(NULL, L"ִ޷Hookָĺ\r\nرճԣ", L"Hookʧ", MB_ICONERROR); MessageBoxW(NULL, lpTimestamp, L"ԶʱΪ", MB_OK); } return 1; } extern "C" __declspec(dllexport) int attach() { return 0; } ================================================ FILE: mssign32.h ================================================ #pragma once #include typedef struct _SIGNER_FILE_INFO { DWORD cbSize; LPCWSTR pwszFileName; HANDLE hFile; } SIGNER_FILE_INFO, * PSIGNER_FILE_INFO; typedef struct _SIGNER_BLOB_INFO { DWORD cbSize; GUID* pGuidSubject; DWORD cbBlob; BYTE* pbBlob; LPCWSTR pwszDisplayName; } SIGNER_BLOB_INFO, * PSIGNER_BLOB_INFO; typedef struct _SIGNER_CONTEXT { DWORD cbSize; DWORD cbBlob; BYTE* pbBlob; } SIGNER_CONTEXT, * PSIGNER_CONTEXT; typedef struct _SIGNER_CERT_STORE_INFO { DWORD cbSize; PCCERT_CONTEXT pSigningCert; DWORD dwCertPolicy; HCERTSTORE hCertStore; } SIGNER_CERT_STORE_INFO, * PSIGNER_CERT_STORE_INFO; typedef struct _SIGNER_SPC_CHAIN_INFO { DWORD cbSize; LPCWSTR pwszSpcFile; DWORD dwCertPolicy; HCERTSTORE hCertStore; } SIGNER_SPC_CHAIN_INFO, * PSIGNER_SPC_CHAIN_INFO; typedef struct _SIGNER_ATTR_AUTHCODE { DWORD cbSize; BOOL fCommercial; BOOL fIndividual; LPCWSTR pwszName; LPCWSTR pwszInfo; } SIGNER_ATTR_AUTHCODE, * PSIGNER_ATTR_AUTHCODE; typedef struct _SIGNER_SUBJECT_INFO { DWORD cbSize; DWORD* pdwIndex; DWORD dwSubjectChoice; union { SIGNER_FILE_INFO* pSignerFileInfo; SIGNER_BLOB_INFO* pSignerBlobInfo; }; } SIGNER_SUBJECT_INFO, * PSIGNER_SUBJECT_INFO; typedef struct _SIGNER_CERT { DWORD cbSize; DWORD dwCertChoice; union { LPCWSTR pwszSpcFile; SIGNER_CERT_STORE_INFO* pCertStoreInfo; SIGNER_SPC_CHAIN_INFO* pSpcChainInfo; }; HWND hwnd; } SIGNER_CERT, * PSIGNER_CERT; typedef struct _SIGNER_SIGNATURE_INFO { DWORD cbSize; ALG_ID algidHash; DWORD dwAttrChoice; union { SIGNER_ATTR_AUTHCODE* pAttrAuthcode; }; PCRYPT_ATTRIBUTES psAuthenticated; PCRYPT_ATTRIBUTES psUnauthenticated; } SIGNER_SIGNATURE_INFO, * PSIGNER_SIGNATURE_INFO; typedef struct _SIGNER_PROVIDER_INFO { DWORD cbSize; LPCWSTR pwszProviderName; DWORD dwProviderType; DWORD dwKeySpec; DWORD dwPvkChoice; union { LPWSTR pwszPvkFileName; LPWSTR pwszKeyContainer; }; } SIGNER_PROVIDER_INFO, * PSIGNER_PROVIDER_INFO; HRESULT WINAPI SignerSign( _In_ SIGNER_SUBJECT_INFO* pSubjectInfo, _In_ SIGNER_CERT* pSignerCert, _In_ SIGNER_SIGNATURE_INFO* pSignatureInfo, _In_opt_ SIGNER_PROVIDER_INFO* pProviderInfo, _In_opt_ LPCWSTR pwszHttpTimeStamp, _In_opt_ PCRYPT_ATTRIBUTES psRequest, _In_opt_ LPVOID pSipData ); HRESULT WINAPI SignerTimeStamp( _In_ SIGNER_SUBJECT_INFO* pSubjectInfo, _In_ LPCWSTR pwszHttpTimeStamp, _In_opt_ PCRYPT_ATTRIBUTES psRequest, _In_opt_ LPVOID pSipData ); HRESULT WINAPI SignerTimeStampEx2( _Reserved_ DWORD dwFlags, _In_ SIGNER_SUBJECT_INFO* pSubjectInfo, _In_ LPCWSTR pwszHttpTimeStamp, _In_ ALG_ID dwAlgId, _In_ PCRYPT_ATTRIBUTES psRequest, _In_ LPVOID pSipData, _Out_ SIGNER_CONTEXT** ppSignerContext ); HRESULT WINAPI SignerTimeStampEx3( _In_ DWORD dwFlags, _In_ DWORD dwIndex, _In_ SIGNER_SUBJECT_INFO* pSubjectInfo, _In_ PCWSTR pwszHttpTimeStamp, _In_ PCWSTR pszAlgorithmOid, _In_opt_ PCRYPT_ATTRIBUTES psRequest, _In_opt_ PVOID pSipData, _Out_ SIGNER_CONTEXT** ppSignerContext, _In_opt_ PCERT_STRONG_SIGN_PARA pCryptoPolicy, _Reserved_ PVOID pReserved );