gpt4 book ai didi

c++ - 使用内联汇编获取调用我的函数的函数的地址

转载 作者:太空宇宙 更新时间:2023-11-04 14:58:44 26 4
gpt4 key购买 nike

我想知道如何使用内联汇编检索调用我的函数的函数的地址。我的想法是获取调用我的函数将返回的地址,并使用它之前的指令(即对调用我的函数的调用)检索调用我的函数的地址添加到给定的偏移量调用,到下一条指令的地址(调用我的函数将返回的地址)。到目前为止,我能够做到这一点,但得到了我的地址。它相当简单并且有效:

_asm
{
mov eax, [ebp+4]
mov returnTo,eax
}

long addressOfMine = (*((long*)(returnTo - sizeof(long)))) + returnTo)

这会很好地检索我的地址。 (通过知道 [ebp+4] 是我的返回地址)

为了做同样的事情,但比上面的一步我试着得到旧的 ebp 并做同样的事情。我在一个网站上看到 [ebp+0] 是旧的 ebp,所以我尝试了:

_asm
{
mov eax, [ebp]
mov ebx, [eax+4]
mov returnTo,ebx
}

long addressOfCaller = (*((long*)(returnTo - sizeof(long)))) + returnTo)

但它不起作用。所以,我的假设是错误的,或者我做错了什么,所以我想请你帮忙。

最佳答案

好吧,只要你知道你在做一些不可移植的事情。你知道吗?

我的意思是,已经有十几个人没有说过了...

所以。对于 x86(但不是 X64)上的函数,当未启用帧指针省略和其他优化时,这应该有效。不适用于所有调用约定,但它应该适用于标准 C/C++ 调用约定。

void ** puEBP = NULL;
__asm { mov puEBP, ebp };
void * pvReturn = puEBP[1]; // this is the caller of my function

puEBP = (void**)puEBP[0]; // walk back to the previous frame
void * pvReturn2 = puEBP[1]; // this is the caller's caller

编辑:好的,我现在正式感到困惑。我再次查看了您的问题,据我所知,您的第一个代码片段在功能上与我刚刚编写的相同。但是您说该代码为您提供了函数的地址——但这不应该是真的。该代码片段应该将调用者的地址返回给您的函数。

edit2:添加代码以获取调用者的调用者。

顺便说一句,您在问题中显示的这段代码

long addressOfCaller = (*((long*)(returnTo - sizeof(long)))) + returnTo)

不会工作。它基于以下假设:调用电话的唯一方式是

call symbol

其中 symbol 是函数的 4 字节绝对地址。但这不是调用电话的唯一方式。也可以间接调用

mov eax, symbol
call [eax]

call [ref_symbol]

也可以相对于当前指令调用

call +12

但你不需要这样做,一旦你知道调用函数中的任何地址,你就可以使用 Debug Help Library找到调用你的函数的地址。

为了使用 DebugHelp,您必须拥有代码的调试符号。然后就用 SymFromAddr .

关于c++ - 使用内联汇编获取调用我的函数的函数的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2170316/

26 4 0
文章推荐: java - 文本提取和分割打开简历
文章推荐: html - 如何在不影响宽度的情况下更改textarea字体大小
文章推荐: java - 文本在小程序上无法正确显示
文章推荐: html -
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com