Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从可执行文件调用函数_C++_Assembly_Code Injection - Fatal编程技术网

C++ 从可执行文件调用函数

C++ 从可执行文件调用函数,c++,assembly,code-injection,C++,Assembly,Code Injection,我想从可执行文件调用函数。到达该进程的唯一方法是在父进程中插入dll。我可以在父进程中插入dll,但如何从子进程调用函数? 差不多 _asm { call/jmp address } 不起作用。我希望你明白我的意思。执行基础 要调用函数,您需要一个地址或中断号。地址被加载到程序计数器寄存器中,执行被转移。一些处理器允许软件中断,其中程序执行调用软件中断的特殊指令。这是执行函数的基础。 更多背景相对地址 可执行文件有两种常见形式:绝对寻址和相对或位置无关代码PIC。在绝对寻址中,函数位于硬编码

我想从可执行文件调用函数。到达该进程的唯一方法是在父进程中插入dll。我可以在父进程中插入dll,但如何从子进程调用函数? 差不多

_asm
{ 
call/jmp address
}
不起作用。我希望你明白我的意思。

执行基础 要调用函数,您需要一个地址或中断号。地址被加载到程序计数器寄存器中,执行被转移。一些处理器允许软件中断,其中程序执行调用软件中断的特殊指令。这是执行函数的基础。

更多背景相对地址 可执行文件有两种常见形式:绝对寻址和相对或位置无关代码PIC。在绝对寻址中,函数位于硬编码地址。这些函数不会移动。通常用于嵌入式系统

在相对寻址模型中,地址与程序计数器寄存器中的值相对。例如,您的函数可能有1024字节远,因此编译器将发出1024字节远的相对分支指令

操作系统和移动目标 许多操作系统在每次调用的不同位置加载程序。这意味着您的可执行文件可能从地址1000开始,下一次从地址127654开始。在这些操作系统中,无法保证每次在同一位置启动可执行文件

在程序中执行 在程序中执行函数很容易。链接器决定所有函数的位置并决定如何执行它们;使用绝对寻址、PIC还是混合寻址

在另一个可执行文件中执行函数 根据上述知识,在另一个程序中执行函数存在问题:

函数在外部可执行文件中的位置 确定可执行文件是否处于活动状态 可执行文件的调用协议 大多数可执行文件不包含有关其函数位置的任何信息,因此您需要知道函数位置。您还需要知道函数是绝对寻址还是PIC。您还需要知道,当您需要该功能时,该功能是否在内存中,或者操作系统是否已将该功能分页到硬盘驱动器

了解功能位置是必要的。但是,如果操作系统没有加载可执行文件,则该位置没有任何用处。在调用另一个可执行文件中的函数之前,需要知道在执行调用时该函数是否存在于内存中

最后,您需要了解用于外部功能的协议。例如,值是通过寄存器传递的吗?它们在堆栈上吗?它们是通过指针地址传递的吗

解决方案:共享库 操作系统OS已经发展到允许动态共享功能。这些函数存在于动态链接库DLL或共享库.SO中。您的程序告诉操作系统将库加载到内存中,然后您通过给它函数名来告诉操作系统执行函数

需要注意的是,您想要的函数必须在库中。如果可执行文件不使用共享库,或者您需要的函数不在库中,那么您的任务将更加困难

执行基础 要调用函数,您需要一个地址或中断号。地址被加载到程序计数器寄存器中,执行被转移。一些处理器允许软件中断,其中程序执行调用软件中断的特殊指令。这是执行函数的基础。

更多背景相对地址 可执行文件有两种常见形式:绝对寻址和相对或位置无关代码PIC。在绝对寻址中,函数位于硬编码地址。这些函数不会移动。通常用于嵌入式系统

在相对寻址模型中,地址与程序计数器寄存器中的值相对。例如,您的函数可能有1024字节远,因此编译器将发出1024字节远的相对分支指令

操作系统和移动目标 许多操作系统在每次调用的不同位置加载程序。这意味着您的可执行文件可能从地址1000开始,下一次从地址127654开始。在这些操作系统中,无法保证每次在同一位置启动可执行文件

在程序中执行 在程序中执行函数很容易。链接器决定所有函数的位置并决定如何执行它们;使用绝对寻址、PIC还是混合寻址

在另一个可执行文件中执行函数 根据上述知识,在另一个程序中执行函数存在问题:

地方 外部可执行文件中函数的 确定可执行文件是否处于活动状态 可执行文件的调用协议 大多数可执行文件不包含有关其函数位置的任何信息,因此您需要知道函数位置。您还需要知道函数是绝对寻址还是PIC。您还需要知道,当您需要该功能时,该功能是否在内存中,或者操作系统是否已将该功能分页到硬盘驱动器

了解功能位置是必要的。但是,如果操作系统没有加载可执行文件,则该位置没有任何用处。在调用另一个可执行文件中的函数之前,需要知道在执行调用时该函数是否存在于内存中

最后,您需要了解用于外部功能的协议。例如,值是通过寄存器传递的吗?它们在堆栈上吗?它们是通过指针地址传递的吗

解决方案:共享库 操作系统OS已经发展到允许动态共享功能。这些函数存在于动态链接库DLL或共享库.SO中。您的程序告诉操作系统将库加载到内存中,然后您通过给它函数名来告诉操作系统执行函数


需要注意的是,您想要的函数必须在库中。如果可执行文件不使用共享库,或者您需要的函数不在库中,那么您的任务将更加困难

如果在进程内部运行,则需要知道要调用的函数从包含该函数的模块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中很重要,请确保它与正在调用的函数的调用约定相匹配。

如果在进程内部运行,则需要知道要调用的函数相对于包含该函数的模块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中很重要,请确保它与正在调用的函数的调用约定相匹配。

您应该在指针定义中指定函数调用约定。否则,具有不正确约定的函数调用将损坏堆栈并导致程序终止。应在指针定义中指定函数调用约定。否则,使用不正确约定的函数调用将损坏堆栈并导致程序终止。