https://github.com/yaoruisheng/SigntoolHook
将编译出来的cryptbase.dll放在signtool.exe同级目录,就能让signtool接受过期的证书。
一、32位DLL
打开 x86 Native Tools Command Prompt for VS 2022
进入项目目录:
cd signtoolhook
执行以下命令:
cmake -S . -B build32 -A Win32 cmake --build build32 --config Release
二、64位DLL
打开x64 Native Tools Command Prompt for VS 2022
进入项目目录:
cd signtoolhook
执行以下命令:
cmake -S . -B build64 -A x64 cmake --build build64 --config Release
这个项目综合了各路hook的优点,挑选了cryptbase.dll作为Hook点,这样支持各版本的signtool(实测win7 sdk,win10 sdk都可以)。
用的processmonitor 观察signtool加载的dll,旧版和新版的signtool共同加载的dll挺多,但是许多是直接从系统目录里加载的,即使放在signtool同级目录,也无法加载。
一个个测试,发现cryptbase.dll 可以。
用的dumpbin /exports 导出cryptbase.dll的导出函数。
代码使用了Detours库进行API钩取(Hooking),主要实现对系统时间相关函数的篡改。以下是核心功能分析:
一、导出函数重定向
1.导出函数声明
通过EMPTY_EXPORT宏声明了11个空函数(如SystemFunction001-041),每个函数包含唯一ID防止编译器优化合并。这些函数会被其他程序调用。
2.动态补丁机制
加载系统目录下的cryptbase.dll
遍历ExportOrdinals数组,获取cryptbase.dll中对应序号的函数地址
使用PatchExportFunction,直接二进制而非汇编将本DLL的空函数入口代码修改为跳转到cryptbase.dll的对应函数
示例(x64架构):
FF 25 00 00 00 00 ; JMP [RIP+0] [目标函数地址] ; 8字节地址
二、API钩取功能
1.钩取的原始函数
FileTimeToSystemTime(文件时间转系统时间)
CompareFileTime(文件时间比较)
2.篡改逻辑
// 1. 时间转换篡改 BOOL WINAPI DetourFileTimeToSystemTime(...) { // 先调用原始函数 result = TrueFileTimeToSystemTime(...); // 篡改结果:将输出时间增加1天 GetSystemTime(¤tSystemTime); SystemTimeToFileTime(..., ¤tFileTime); currentFileTime += 864000000000ULL; // 增加1天 TrueFileTimeToSystemTime(&newFileTime, lpSystemTime); // 覆盖结果 } // 2. 时间比较篡改 LONG WINAPI DetourCompareFileTime(...) { return 0; // 永远返回"相等" }
三、DLL入口点
DllMain流程:
四、关键实现细节
1.跨平台支持
x86:6字节跳转指令(PUSH + RET)
x64:14字节绝对跳转(JMP [RIP])
使用VirtualProtect和FlushInstructionCache确保内存安全
2.防优化技巧
volatile int pad[8] = {id}; // 阻止链接器合并函数