2

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

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

任何建议都会很棒。我更愿意在 C 或 C++ 中实现它。

4

2 回答 2

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)

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

于 2013-09-03T21:42:27.650 回答
0

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

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

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

于 2013-09-03T21:44:33.023 回答