Bootstrap

任意调用EXE可执行文件中的函数

两步解决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 *

END

;