dll函数的导出

  1. _declspec(dllexport) 导出的函数名会被改变
1
2
_declspec(dllexport)   bool HookStart(void);
_declspec(dllexport) void HookStop(void);

使用vs的工具->命令行->开发者命令提示 使用命令 dumpbin /exports *.dll 查看dll的导出函数

1
2
3
4
ordinal hint RVA      name

1 0 0001136B ?HookStart@KeyHook@@QEAA_NXZ = @ILT+870(?HookStart@KeyHook@@QEAA_NXZ)
2 1 00011294 ?HookStop@KeyHook@@QEAAXXZ = @ILT+655(?HookStop@KeyHook@@QEAAXXZ)

  • 解决办法:

在前面加上这个

1
2
#pragma comment(linker, "/EXPORT:HookStart=?HookStart@KeyHook@@QEAA_NXZ")
#pragma comment(linker, "/EXPORT:HookStop=?HookStop@KeyHook@@QEAAXXZ")

编译器就会按照我们指定的函数名导出函数了

  1. 因为版本问题,导出函数前面如果加上 extern “C” 可能会出现不符合编译链接规范

解决办法:

1
2
3
4
5
6
7
8
#ifdef _cplusplus
extern "C"{
#endif
_declspec(dllexport) bool HookStart(void);
_declspec(dllexport) void HookStop(void);
#ifdef _cplusplus
extern "C" }
#endif

可以兼容c/c++

无法解析的外部符号

  • 问题:
    _ImmGetContext@4 / _ImmGetCompositionStringA@16 等API调用出错

  • 解决:

项目->属性->链接器->输入->附加依赖项
添加 imm32.lib / winmm.lib

直接将控制台程序转变为win32程序

项目->属性

1)c/c++ —> 预处理 —>预处理定义 :

_CONSOLE改为:_WINDOWS

2)连接器 —> 系统 —>子系统:

控制台 (/SUBSYSTEM:CONSOLE)改为:窗口 (/SUBSYSTEM:WINDOWS)

字符集

可选字符集为宽字符与unicode字符集,如果使用unicode字符集,如SetWindowsHook 会自动扩展到SetWindowsHookExW ,尽量不要为了简便将所有类似的函数直接指定为FunctionA。