我希望能够使用自己的参数调用已编译的可执行文件中的函数。例如,函数偏移量可以是0x00402120,它接受2个参数。我想调用的函数本质上很简单,并且不调用任何库函数,所以我不需要担心导入库并尝试修复库地址。
过去,我编写了调试器脚本来执行此操作,但我不想将可执行文件加载到调试器中。
任何建议都会很棒。我宁愿用C或C ++实现它。
答案 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)
最大的问题是程序每次都不能在同一地址执行。因此,您必须知道可执行文件中函数的偏移量。
另一个问题:操作系统可以“页面”删除未使用的可执行文件的功能,并按需将它们读入内存。只有操作系统才能知道它们的位置。
您可以使用工具从可执行文件中提取函数并将其放入文件中。但是该函数可能在文件的其他地方具有依赖性。需要提取这些内容并重新调整地址。可能,但不建议。