从可执行文件调用函数
Call function from executable
我想从可执行文件调用一个函数。访问该进程的唯一方法是在父进程中注入 dll。我可以在父进程中注入 dll,但如何从子进程调用函数?类似的东西
_asm
{
call/jmp address
}
不行。我希望你明白我的意思。
如果你在进程内运行,你需要知道要从包含函数的模块(exe(的基数调用的函数的偏移量。 然后,你只需要创建一个函数指针并调用它。
// assuming the function you're calling returns void and takes 0 params
typedef void(__stdcall * voidf_t)();
// make sure func_offset is the offset of the function when the module is loaded
voidf_t func = (voidf_t) (((uint8_t *)GetModuleHandle('module_name')) + func_offset);
func(); // the function you located is called here
如果您知道函数的地址,则您拥有的解决方案将适用于 32 位系统(64 位不允许内联程序集(,但您需要确保正确实现调用约定。 上面的代码使用 GetModuleHandle 解析要调用其函数的模块的当前加载基础。
一旦将模块注入到正在运行的进程,ASLR 就不是真正的问题,因为您只需向 windows 询问包含要调用的代码的模块基。 如果要查找运行当前进程的 exe 的基,可以使用参数 NULL 调用 GetModuleHandle。 如果您确信函数偏移量不会更改,则可以在反汇编器或其他工具中找到偏移量后,对要调用的函数的偏移量进行硬编码。 假设包含函数的 exe 未更改,则该偏移量将是恒定的。
如注释中所述,调用约定在函数 typedef 中很重要,请确保它与要调用的函数的调用约定匹配。
执行基础
要调用函数,您需要一个地址或中断号。 地址被加载到程序计数器寄存器中,并传输执行。 一些处理器允许"软件中断",其中程序执行调用软件中断的特殊指令。 这是执行功能的基础。
更多背景 -- 相对地址
有两种常见的可执行文件形式:绝对寻址和相对(或位置独立代码,PIC(。 在绝对寻址中,函数位于硬编码地址。 函数不会移动。 通常用于嵌入式系统。
在相对寻址模型中,地址相对于程序计数器寄存器中的值。 例如,您的函数可能在 1024 字节之外,因此编译器将发出 1024 字节(远方(的相对分支指令。
操作系统和移动目标
许多操作系统在每次调用的不同位置加载程序。 这意味着可执行文件可能从地址 1000 开始,下次从地址 127654 开始。 在这些操作系统中,不能保证可执行文件每次都会在同一位置启动。
在程序中执行
在程序中执行函数很容易。 链接器决定所有函数的位置并确定如何执行它们;是使用绝对寻址、PIC 还是混合。
在另一个可执行文件中执行函数
有了上述知识,在另一个程序中执行函数存在问题:
- 函数在外部可执行文件中的位置
- 确定可执行文件是否处于活动状态
- 可执行文件的调用协议
大多数可执行文件不包含有关其功能位置的任何信息,因此您需要知道它的位置。 您还需要知道该函数是绝对寻址还是 PIC。 您还需要知道该函数在您需要时是否在内存中,或者操作系统是否已将函数分页到硬盘驱动器。
了解功能位置是必要的。 但是,如果操作系统尚未加载可执行文件,则该位置没有用。 在调用另一个可执行文件中的函数之前,您需要知道执行调用时该函数是否存在于内存中。
最后,您需要知道用于外部函数的协议。 例如,值是否通过寄存器传递? 它们在堆栈上吗? 它们是否通过指针(地址(传递?
解决方案:共享库
操作系统 (OS( 已经发展到允许动态共享功能。 这些函数存在于动态链接库 (DLL( 或共享库 (.所以(。 程序告诉操作系统将库加载到内存中,然后通过为其提供函数名称来告诉操作系统执行函数。
需要注意的是,您想要的功能必须在库中。 如果可执行文件不使用共享库或您需要的功能不在库中,那么您的任务将更加困难。
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销