需求是这样的,某个dll有一堆导出函数,需要写一个劫持dll,但是又不想写太多的函数。原始dll某些导出函数是stdcall的,导出函数名类似"_Test@12"这种格式,想要用一个通用函数实现所有的导出函数。
首先按照最直接的想法测试了一下,要在导出函数中加上@,直接写就可以了。例如导出函数名叫“test@4”
#include <windows.h>
extern "C" void test(DWORD)
{
}
#pragma comment(linker, "/EXPORT:test@4=test")
在使用VS的linker.exe,生成的文件,查看导出表中的函数名为“test”。
如果要导出“test@4”,那么要写成下面的形式(貌似只能靠函数声明实现,可能有其他方法但是我没找到,如果各位大佬知道欢迎留言):
#include <windows.h>
extern "C" void __stdcall test(DWORD)
{
}
#pragma comment(linker, "/EXPORT:test@4=_test@4")
经过多种方法测试(VS的Def文件等等都不行),可以使用其他编译器来实现,比如:Clang,使用CLang(验证使用的12.0)
#include <windows.h>
extern "C" void test(DWORD)
{
}
#pragma comment(linker, "/EXPORT:test@4=_test")
使用Clang编译上面的代码可以到达预期效果
个人理解,这个@符号是VS编译器自己用的,在导出函数转发的情况下,如果后面的函数带有@,那么写@是生效的。例如:
#pragma comment(linker, "/EXPORT:test@4=addfas.test@4")
其他情况是不行的,要么编译器自动生成stdcall的@,要么就是没有(写了也没用,就像最开始的代码)。VS的规则是这样,但其他的编译器应该是可以的,例如Clang、GCC
