3

我尝试用我糟糕的汇编技能分析一个 dll 文件,如果我无法实现非常琐碎的事情,请原谅我。我的问题是,在调试应用程序时,我只在调试会话中找到我正在寻找的代码,在我停止调试器后,地址就消失了。dll 看起来没有被混淆,因为许多代码都是可读的。看看截图。我正在寻找的代码位于 debug376 部分中的地址 07D1EBBF。顺便说一句,我从哪里得到这个 debug376 部分?

所以我的问题是,如何在不调试的情况下找到此功能?谢谢

更新

好的,正如我所说,一旦我停止调试器,代码就会消失。我什至无法通过字节序列找到它(但我可以在调试模式下)。当我启动调试器时,代码并没有立即反汇编,我应该在那个地方添加一个硬件断点,只有当断点被命中时,IDA才会显示反汇编代码。看看这个屏幕截图 你会看到我感兴趣的代码行,如果程序没有在调试模式下运行,它是不可见的。我不确定,但我认为这类似于在运行时解包代码,这在设计时是不可见的。

无论如何,任何帮助将不胜感激。我想知道为什么隐藏该代码,直到断点命中(它显示为“db 8Bh”等)以及如果可能的话如何在不调试的情况下找到该地址。顺便说一句,这可能是来自不同模块(dll)的代码吗?

谢谢

更新 2

我发现 debug376 是在运行时创建的段。这么简单的问题:我怎样才能找出这个片段来自哪里:)

4

2 回答 2

7

因此,一旦程序运行,您就会在调试器窗口中看到代码,并且一旦它不再运行,您似乎在原始 Hex-Dump 中找不到非常相同的操作码?

拍摄内存快照可能会对您有所帮助。在您感兴趣的指令附近暂停程序的执行以确保它们在那里,然后从“调试器”菜单中选择“获取内存快照”。IDA 将询问您是否只复制在定义为“加载程序段”(PE 加载程序从预定义表中创建的段)或当前似乎属于被调试程序的“所有段”的段中找到的数据(包括这样可能是由解包例程、解密器等创建的)。选择“所有段”,您应该可以看到包括调试段在内的内存内容(调试时创建或识别的段)在不调试应用程序时在 IDA 中。

您可以随时通过按Shift+F7或单击“视图” > “打开子视图”中的“分段”来查看分段列表。

请记住,您尝试分析的程序可能会选择在下次加载时在其他位置创建该段,以使您更难理解发生了什么。

更新以匹配您的第二个问题

当程序从某处解压数据时,它必须在某处复制内容。Windows 是一种虚拟机,如今当您尝试在不允许的位置执行或编写代码时,它会让您非常讨厌。所以任何程序,只要我们在windows下都会以某种方式

  1. 注册一堆新内存或覆盖它已经拥有的内存。这通常是通过调用类似 malloc 之类的东西来完成的[你的代码看起来好像它可能是一种非常密集的指针语言......也许是 VB 或面向对象的东西]它主要归结为从 Windows调用VirtualAllocVirtualAllocEx kernel32.dll,有关其调用约定的更多详细信息,请参见http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx
  2. 如果在调用 VirtualAlloc 时还没有,也许可以设置 Windows 异常处理并将内存范围标记为可​​执行。这将通过再次从 kernel32.dll调用VirtualProtect来完成。请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspxhttp://msdn.microsoft.com/en-us/library/windows/ desktop/aa366786(v=vs.85).aspx以获取更多信息。

所以现在,您应该在程序中迈出一步,从其默认入口点 (OEP) 开始,并寻找对这些函数之一的调用,可能将内存保护设置为 PAGE_EXECUTE 或后代。之后可能会出现某种循环解密内存内容,将它们复制到新位置。您可能只想跳过它,这取决于您对程序的兴趣,只需将光标放在循环之后(通常是 IDA 中的粗蓝线),然后从右键单击出现的菜单中单击“运行到光标”汇编代码。

如果失败,只需尝试在 kernel32.dll 的 VirtualAlloc 上放置一个硬件断点,看看在进入 return 语句时是否有任何有趣的事情,以便在 Alloc 或 Protect 调用之后执行链将带你到任何地方。

于 2012-06-13T23:14:18.827 回答
1

您需要找到该代码的相对虚拟地址,这将允许您再次找到它,而不管加载地址如何(这些天几乎所有使用 ASLR 的系统都非常方便)。RVA 通常计算为virtual address - base load address = RVA,但是,您可能还需要考虑截面基数。

另一种方法是每次使用 IDA 的变基工具将 dll 变基到相同的地址。

于 2012-06-05T06:59:20.137 回答