You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ DLL代理指定修饰名导出实现调用拦截及相关问题咨询

问题1解决:汇编跳转参数传递与返回值处理

你不需要手动处理参数和返回值,只要将包装函数声明为__declspec(naked),函数内部不修改栈和寄存器直接跳转即可,调用约定的处理逻辑由原函数自行实现:

  • 针对__cdecl调用约定的静态成员函数,栈参数由调用方维护,直接跳转不会破坏栈结构
  • 针对__thiscall调用约定的普通成员函数,ecx寄存器存储的this指针、栈上存储的参数都会原封不动传递给原函数,原函数执行完成后的返回值会存储在eax寄存器中,直接返回给上层调用方

示例代码如下:

class CRfebUsbApp
{
public:
    #pragma comment(linker, "/export:?GetInstance@CRfebUsbApp@@SAPAV1@XZ=?GetInstance@CRfebUsbApp@@SAPAV1@XZ")
    __declspec(naked) static CRfebUsbApp* __cdecl GetInstance();

    #pragma comment(linker, "/export:?CmtReadRegs@CRfebUsbApp@@QAEEEQAEG@Z=?CmtReadRegs@CRfebUsbApp@@QAEEEQAEG@Z")
    __declspec(naked) unsigned char __thiscall CmtReadRegs(unsigned char, unsigned char* const, unsigned short);
private:
};

// 全局提前加载好的原函数地址
static FARPROC getInstance, cmtReadRegs;

__declspec(naked) CRfebUsbApp* __cdecl CRfebUsbApp::GetInstance(void)
{
    _asm {
        // 如需添加日志逻辑,此处先push所有用到的寄存器保存现场,日志执行完pop恢复再跳转
        jmp [getInstance]
    }
}

__declspec(naked) unsigned char __thiscall CRfebUsbApp::CmtReadRegs(unsigned char, unsigned char* const, unsigned short)
{
    _asm {
        // 如需添加日志逻辑,此处先push所有用到的寄存器保存现场,日志执行完pop恢复再跳转
        jmp [cmtReadRegs]
    }
}
问题2解决:批量封装60+导出函数

可以通过宏定义+脚本预生成的方式完全避免重复手动编码:

  1. 先通过dumpbin /exports OriginalDll.dll命令导出原DLL所有的修饰名、序号、调用约定列表,整理为统一的配置表
  2. 选择以下两种方式之一批量生成代码:
  • 宏批量生成:定义通用包装宏,每个函数只需要一行代码生成完整逻辑:
// 通用包装宏定义
#define DEFINE_WRAP(raw_func_name, mangled_name, func_ptr, ret_type, call_conv, ...) \
    #pragma comment(linker, "/export:" #mangled_name "=" #mangled_name) \
    __declspec(naked) ret_type call_conv CRfebUsbApp::raw_func_name(__VA_ARGS__) { \
        _asm { jmp [func_ptr] } \
    }

// 批量声明原函数指针
static FARPROC getInstance, cmtReadRegs /* 剩余所有函数指针依次声明 */;

// 批量生成包装函数,每个函数只需要一行
DEFINE_WRAP(GetInstance, ?GetInstance@CRfebUsbApp@@SAPAV1@XZ, getInstance, CRfebUsbApp*, __cdecl, void)
DEFINE_WRAP(CmtReadRegs, ?CmtReadRegs@CRfebUsbApp@@QAEEEQAEG@Z, cmtReadRegs, unsigned char, __thiscall, unsigned char, unsigned char* const, unsigned short)
// 剩余60+函数按格式补全即可
  • 脚本自动生成:写简单的Python/JS脚本读取dumpbin的输出结果,自动生成所有函数的声明、指针定义、包装代码,完全不需要手动填写。

也可以用模块定义文件(.def)统一管理所有导出项,不需要逐个添加编译指令:

EXPORTS
?GetInstance@CRfebUsbApp@@SAPAV1@XZ=?GetInstance@CRfebUsbApp@@SAPAV1@XZ @1
?CmtReadRegs@CRfebUsbApp@@QAEEEQAEG@Z=?CmtReadRegs@CRfebUsbApp@@QAEEEQAEG@Z @2
; 其他导出项按序号依次添加即可

内容的提问来源于stack exchange,提问作者Marco Arigliani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 17:45:01