- 论坛徽章:
- 2
|
为了阐述清楚。 这里给出一个原型。
我从这里: http://www.dll-files.com/dllindex/dll-files.shtml?libglesv2 抓到的 libglesv2.dll 。 Linux上。。。 想编译都编译不了。。。
- $ objdump -p libglesv2.dll | awk -f implib.awk > libglesv2.cpp
- $ cat implib.awk
- #!/usr/bin/awk -f
- BEGIN {
- FS="[][ \t]+"
- print "#include <windows.h>"
- print "extern \"C\" {"
- printf "static HMODULE libglesv2 = LoadLibrary(%s);\n", "\"libglesv2.dll\""
- }
- END { print "}" }
- /^\[Ordinal\/Name Pointer\] Table$/ , /^$/ {
- if ($2!="Ordinal/Name" && $3)
- {
- printf "int (*__imp_%s)(void) = (int(*)(void))GetProcAddress(libglesv2,(LPCSTR)%s);\n",$3,$2
- printf "int %s(void) { return (*__imp_%s)(); }\n",$3,$3
- }
- }
复制代码 产生的cpp文件大致是这样:
- #include <windows.h>
- extern "C" {
- static HMODULE libglesv2 = LoadLibrary("libglesv2.dll");
- int (*__imp_glActiveTexture)(void) = (int(*)(void))GetProcAddress(libglesv2,(LPCSTR)0);
- int glActiveTexture(void) { return (*__imp_glActiveTexture)(); }
- int (*__imp_glAttachShader)(void) = (int(*)(void))GetProcAddress(libglesv2,(LPCSTR)1);
- int glAttachShader(void) { return (*__imp_glAttachShader)(); }
- ...
- }
复制代码 将它编译之后就是一个导入库了。 也许吧。。。 能检查的地方我尽量检查了。 包括g++ -O2 -c 后会使用尾调用优化。 这样就与实际的签名无关了。
但没有真正环境很恼火。。。
导入库大致也就是做这个事情。需要改进的地方:
1. 写一个真正的PE分析器而不是objdump -p | awk 。。。 来得到导出的名字与序号。
2. 如果c++文件编译出的目标文件能和其他c文件编译出的目标文件顺利链接起来 —— 尤其是会将cpp产生的初始化代码放到合适的位置 —— 其实就不需要写一个PE的产生器了?
直接用穷人的元编程。。。
还有一些细节的地方就是用cpp的初始化机制好像比“普通”的__imp_f要来得晚可能会造成问题。 (至于错误检查这里为了简单就没有加)。
3. 如果就是不想用c++编译器。。。 其实也可以写一个PE产生器。 如果想避免 _f 与 __imp_f 名字之间的关联可以把PE的相应部分架空, 为每个指令集写分别写一点点代码。 其实也就2个指令。。。 |
|