从Compiled Executable执行函数

时间:2013-09-03 21:19:40

标签: c++ c

我希望能够使用自己的参数调用已编译的可执行文件中的函数。例如,函数偏移量可以是0x00402120,它接受2个参数。我想调用的函数本质上很简单,并且不调用任何库函数,所以我不需要担心导入库并尝试修复库地址。

过去,我编写了调试器脚本来执行此操作,但我不想将可执行文件加载到调试器中。

任何建议都会很棒。我宁愿用C或C ++实现它。

2 个答案:

答案 0 :(得分:3)

在这里,我做了以下几点。

这是我的C ++代码:

#include<iostream>

void foo(int x) {
  std::cout<<"calling foo("<<x<<")"<<std::endl;
}

int main() {
  return 0;
}

这是我编译它的方式:

g++ program.cpp -o program -O0

这就是我确定foo函数名称的方式:

[myprompt ~] nm program
0000000100001090 S _NXArgc
0000000100001098 S _NXArgv
0000000100000e70 t __GLOBAL__sub_I_program.cpp
0000000100000dcc T __Z3fooi
0000000100000e28 t __Z41__static_initialization_and_destruction_0ii
                 U __ZNSolsEPFRSoS_E
                 U __ZNSolsEi
                 U __ZNSt8ios_base4InitC1Ev
                 U __ZNSt8ios_base4InitD1Ev
                 U __ZSt4cout
                 U __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
0000000100001088 s __ZStL8__ioinit
                 U __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
                 U ___cxa_atexit
00000001000010a8 S ___progname
0000000100000000 T __mh_execute_header
00000001000010a0 S _environ
                 U _exit
0000000100000e1d T _main
0000000100001000 s _pvars
                 U dyld_stub_binder
0000000100000d90 T start

这就是我调用foo函数的方法(我是用Python做的,因为我很懒,但你可以使用任何其他允许你加载库的程序来实现这一点。)

import ctypes
program = ctypes.CDLL("./program")
program._Z3fooi(ctypes.c_int(2))

执行命令

[myprompt ~] python callprogram.py
calling foo(2)

这不可移植(名称重整可能因编译器而异;从平台到平台)。这个对我有用。但我从来不需要这样做,所以我想知道它有多么有用。

答案 1 :(得分:0)

最大的问题是程序每次都不能在同一地址执行。因此,您必须知道可执行文件中函数的偏移量。

另一个问题:操作系统可以“页面”删除未使用的可执行文件的功能,并按需将它们读入内存。只有操作系统才能知道它们的位置。

您可以使用工具从可执行文件中提取函数并将其放入文件中。但是该函数可能在文件的其他地方具有依赖性。需要提取这些内容并重新调整地址。可能,但不建议。