两步解决exe无导出表与重定位表问题
As we know,可执行文件(.exe)是没有导出表和重定位表的,想要调用一个 .exe 文件中的函数,我知道的有两种思路。思路一:给二进制文件添加重定位表区段以及导出表
,在没有深刻理解 PE 结构的情况下,不建议这么做!这种方法又困难又耗时;思路二:修改程序的dll特征码
,使用相对虚拟地址来调用函数,具体步骤:
- 下载一个 PE Editor 之类的 PE 编辑器,修改二进制文件的入口点为0
- 在 dll 特征码那一栏,必须勾选可执行镜像以及 dll,其它的可视情况勾选
使用RVA相对地址调用函数
将 test.c 编程成 .exe 文件,源码如下,使用 gcc test.c -o test.exe
#include <stdio.h>
void func(){
printf("You have successed!!!\n");
}
int main(){
func();
return 0;
}
生成的这个 .exe 不能直接用 LoadLibrary()+GetProcAddress() 来调用函数。先按照之前的步骤,修改这个文件特征码,将入口点改为0,勾选可执行镜像以及dll
,然后这个 .exe 才能正确被装载到主调程序的内存中
这时候我们需要写主调程序来调用上述的 .exe 中的 func 函数。call_exe.c 的源码如下:
#include <stdio.h>
#include <windows.h>
typedef void (*func1)();
int main(){
HMODULE hdll = NULL;
hdll = LoadLibrary("test.exe");
if(hdll != NULL){
printf("YES\n");
/*
func1 myfunc = ((func1)((PBYTE)hdll+0x1560));
myfunc();
*/
((func1)((PBYTE)hdll+0x1560))();
}else{
printf("NO\n");
}
FreeLibrary(hdll);
return 0;
}
特别说明:
-
0x1560
这个地址就是 test.exe 中 func 的相对虚拟地址,对逆向熟悉的朋友应该了解,使用 IDA 之类的反汇编器可以轻松找到这个地址 - 在调用之前,一定要声明这个函数,函数的参数形式要与 IDA 中查看到的一致,诸如
typedef int(* func1)(int,int);
或者typedef void(* func2)(int);
,注意函数是指针类型 - 注意强制类型转换,比如 HMODULE 类型是不可以直接加减运算的,需要转换成
PBYTE
类型,即BYTE *