【问题标题】:How do you find a functions virtual call address in assembly?如何在汇编中找到函数虚拟调用地址?
【发布时间】:2010-05-24 01:33:07
【问题描述】:

我已经用谷歌搜索了,但我不确定我问的是不是正确的问题,无论如何我都找不到太多,也许链接会有所帮助。

我制作了一个显示消息框的 c++ 程序,然后我用 Ollydbg 打开它并转到它调用 MessageBoxW 的部分。

每次我运行应用程序时,MessageBoxW 的调用地址都会发生变化,因为 Windows 正在更新我的 Imports 表以具有 MessageBoxW 的正确地址。所以我的问题是如何在导入表中找到 MessageBoxW 的虚拟地址,以及如何在 ollydbg 中使用它?

基本上,我正在尝试在程序集中创建一个代码洞穴以再次调用 MessageBoxW。 通过使用十六进制编辑器搜索可执行文件并找到调用的位置,我非常接近,我想我找到了虚拟地址。但是当我在 olly 中调用该虚拟地址并将其保存到可执行文件时,下次我打开它时,该调用被一堆 DB xyz 替换(看起来像虚拟地址,但为什么 call 被删除了?

对不起,如果我的术语不正确,因为我是新手,所以我不太确定该叫什么。

【问题讨论】:

  • 我不明白你的大部分问题......你想用代码洞穴实现什么? “找到呼叫的位置”是什么意思?或许 GetProcAddress 函数会对您有所帮助?
  • 是的,对不起,就像我说的那样,我的术语很可能是错误的。 GetProcAddress 会很棒,除了它的地址不是像其他任何改变一样吗?我怎样才能找到它的地址?对于代码洞穴,我只想显示第二个消息框以用于学习目的。 “找到调用的位置”意味着我想我在十六进制编辑器中找到了CALL MessageBoxW 的字节,所以如果“调用”的操作码是一个字节并且调用的地址是 4 个字节,那么这 4 个字节必须是调用虚拟地址吧?
  • (作为答案回复,因为文字不符合评论长度限制)

标签: function assembly virtual virtual-address-space


【解决方案1】:

(回复原帖的评论)

啊,不,“调用”操作码中指定的地址是相对于调用指令的。但是,对于导入的函数,它很可能是间接调用(从内存位置读取函数的地址)。

真的没有“官方”/可靠的方法来获取任何函数的地址,而无需访问导入段。如果您正在修补某个可执行文件,只需查看 Windows 在其导入段中放置的值。如果您从另一个进程注入代码,您可以依赖这样一个事实,即系统 DLL 中的函数地址相对于 DLL 的加载地址将保持不变。也可以手动定位解析程序在内存中的导入段。

【讨论】:

  • 是的,我希望能够使用导入表中的间接调用。我刚刚阅读了msdn.microsoft.com/en-us/library/ms809762.aspx 的一部分,它显示:(虚拟地址 0x10464)-(基地址 0x10000)= RVA 0x00464。这是否意味着我可以将基本内存地址放入 eax,添加 RVA 0x0046,然后添加 call eax
  • 嗯,类似的,虽然可能还有更多。如果可执行文件是使用重定位信息构建的并且受制于 ASLR,则基地址可能会在每次运行时发生变化。
  • 是的,我一直遇到 ASLR 问题,如果没有它,生活会变得如此轻松!
【解决方案2】:

1- 在可执行模块中查找消息框的地址。假设你的 exe 文件是 a1.exe

可执行模块> 选择a1.exe > 按ctrl + N 找到消息框的地址。假设地址是 00402008

2-使用ff25 08204000机器码调用消息框,但在推送参数之前推送你的EIP返回地址。

【讨论】:

    猜你喜欢
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    相关资源
    最近更新 更多