Full Code of JemmyLoveJenny/HookSigntool for AI

master 11c7a536f08f cached
13 files
64.0 KB
17.5k tokens
40 symbols
1 requests
Download .txt
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
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <VCProjectVersion>15.0</VCProjectVersion>
    <ProjectGuid>{E3ACE1E9-7437-4DA6-8B12-1A9A1870AF33}</ProjectGuid>
    <RootNamespace>HookSigntool</RootNamespace>
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v142</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>MultiByte</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <IncludePath>include;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
    <LibraryPath>lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86</LibraryPath>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <SDLCheck>true</SDLCheck>
      <ConformanceMode>true</ConformanceMode>
    </ClCompile>
    <Link>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="include\detours.h" />
    <ClInclude Include="include\detver.h" />
    <ClInclude Include="include\syelog.h" />
    <ClInclude Include="mssign32.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>

================================================
FILE: HookSigntool.vcxproj.filters
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="源文件">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="头文件">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
    </Filter>
    <Filter Include="资源文件">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="mssign32.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="include\detours.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="include\detver.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="include\syelog.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
</Project>

================================================
FILE: HookSigntool.vcxproj.user
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup />
</Project>

================================================
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 "<URL>" <filename>`
对于之后的任意个签名打时间戳:`signtool timestamp /tp <index> /tr "<URL>" <filename>`
其中`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 <imagehlp.h>
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 <dbghelp.h>
#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 <stdio.h>
#include <limits.h>
#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 <windows.h>
#include <detours.h>
#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 <stdarg.h>

#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 <Windows.h>
#include <wchar.h>
#include <detours.h>
#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 <Windows.h>

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
);
Download .txt
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
Download .txt
SYMBOL INDEX (40 symbols across 4 files)

FILE: include/detours.h
  type LONG (line 70) | typedef LONG LONG_PTR;
  type ULONG (line 71) | typedef ULONG ULONG_PTR;
  type GUID (line 265) | typedef struct  _GUID
  type DETOUR_TRAMPOLINE (line 316) | typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE;
  type DETOUR_SECTION_HEADER (line 321) | typedef struct _DETOUR_SECTION_HEADER
  type DETOUR_SECTION_RECORD (line 346) | typedef struct _DETOUR_SECTION_RECORD
  type DETOUR_CLR_HEADER (line 353) | typedef struct _DETOUR_CLR_HEADER
  type DETOUR_EXE_RESTORE (line 367) | typedef struct _DETOUR_EXE_RESTORE
  type DETOUR_EXE_HELPER (line 390) | typedef struct _DETOUR_EXE_HELPER
  type VOID (line 468) | typedef VOID * PDETOUR_BINARY;
  type VOID (line 469) | typedef VOID * PDETOUR_LOADED_BINARY;
  type IMAGEHLP_MODULE (line 778) | typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
  type PIMAGEHLP_MODULE (line 779) | typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
  type IMAGEHLP_SYMBOL (line 780) | typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
  type PIMAGEHLP_SYMBOL (line 781) | typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
  function LONG (line 783) | static inline
  type DETOUR_SYM_INFO (line 816) | typedef struct _DETOUR_SYM_INFO
  type DETOUR_IA64_BUNDLE (line 868) | struct DETOUR_IA64_BUNDLE

FILE: include/syelog.h
  type SYELOG_MESSAGE (line 33) | typedef struct _SYELOG_MESSAGE

FILE: main.cpp
  function LPCWSTR (line 26) | LPCWSTR ReplaceTimeStamp(LPCWSTR lpOriginalTS) {
  function LONG (line 45) | LONG WINAPI NewCertVerifyTimeValidity(
  function HRESULT (line 52) | HRESULT WINAPI NewSignerSign(
  function HRESULT (line 64) | HRESULT WINAPI NewSignerTimeStamp(
  function HRESULT (line 73) | HRESULT WINAPI NewSignerTimeStampEx2(
  function HRESULT (line 85) | HRESULT WINAPI NewSignerTimeStampEx3(
  function NewGetLocalTime (line 100) | void WINAPI NewGetLocalTime(
  function HookFunctions (line 119) | bool HookFunctions()
  function ParseConfig (line 148) | bool ParseConfig(LPWSTR lpCommandLineConfig, LPWSTR lpCommandLineTimestamp)
  function BOOL (line 184) | BOOL WINAPI DllMain(
  function attach (line 218) | __declspec(dllexport) int attach()

FILE: mssign32.h
  type SIGNER_FILE_INFO (line 4) | typedef struct _SIGNER_FILE_INFO {
  type SIGNER_BLOB_INFO (line 9) | typedef struct _SIGNER_BLOB_INFO {
  type SIGNER_CONTEXT (line 16) | typedef struct _SIGNER_CONTEXT {
  type SIGNER_CERT_STORE_INFO (line 22) | typedef struct _SIGNER_CERT_STORE_INFO {
  type SIGNER_SPC_CHAIN_INFO (line 28) | typedef struct _SIGNER_SPC_CHAIN_INFO {
  type SIGNER_ATTR_AUTHCODE (line 35) | typedef struct _SIGNER_ATTR_AUTHCODE {
  type SIGNER_SUBJECT_INFO (line 43) | typedef struct _SIGNER_SUBJECT_INFO {
  type SIGNER_CERT (line 52) | typedef struct _SIGNER_CERT {
  type SIGNER_SIGNATURE_INFO (line 62) | typedef struct _SIGNER_SIGNATURE_INFO {
  type SIGNER_PROVIDER_INFO (line 72) | typedef struct _SIGNER_PROVIDER_INFO {
Condensed preview — 13 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (73K chars).
[
  {
    "path": ".gitignore",
    "chars": 24,
    "preview": ".vs/\n.vscode/\n\nRelease/\n"
  },
  {
    "path": "HookSigntool.sln",
    "chars": 912,
    "preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 16\r\nVisualStudioVersion = 16.0.2"
  },
  {
    "path": "HookSigntool.vcxproj",
    "chars": 2898,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.micros"
  },
  {
    "path": "HookSigntool.vcxproj.filters",
    "chars": 1307,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "HookSigntool.vcxproj.user",
    "chars": 163,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbu"
  },
  {
    "path": "README.md",
    "chars": 4946,
    "preview": "# HookSigntool\n## 简介\n本项目编译结果为`HookSigntool.dll`,用于亚洲诚信数字签名工具(或其他类似的签名工具,如天威诚信代码签名证书助手,沃通代码签名工具,环玺信息数字签名工具等等)它的作用如下:\n1. H"
  },
  {
    "path": "include/detours.h",
    "chars": 38625,
    "preview": "/////////////////////////////////////////////////////////////////////////////\r\n//\r\n//  Core Detours Functionality (detou"
  },
  {
    "path": "include/detver.h",
    "chars": 756,
    "preview": "//////////////////////////////////////////////////////////////////////////////\r\n//\r\n//  Common version parameters.\r\n//\r\n"
  },
  {
    "path": "include/syelog.h",
    "chars": 3637,
    "preview": "//////////////////////////////////////////////////////////////////////////////\r\n//\r\n//  Detours Test Program (syelog.h o"
  },
  {
    "path": "main.cpp",
    "chars": 8415,
    "preview": "#pragma comment(lib, \"detours.lib\")\r\n#define _CRT_SECURE_NO_WARNINGS\r\n\r\n#include <Windows.h>\r\n#include <wchar.h>\r\n#inclu"
  },
  {
    "path": "mssign32.h",
    "chars": 3886,
    "preview": "#pragma once\r\n#include <Windows.h>\r\n\r\ntypedef struct _SIGNER_FILE_INFO {\r\n    DWORD   cbSize;\r\n    LPCWSTR pwszFileName;"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the JemmyLoveJenny/HookSigntool GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 13 files (64.0 KB), approximately 17.5k tokens, and a symbol index with 40 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!