IDA Pro 和公认的库函数

逆向工程 艾达 调情签名
2021-06-23 19:42:36

我首先要说的是,尽管我在编程方面有多年的经验,但我对逆向主题完全陌生。

我在自动识别使用 Borland C++ 3.1 编译的 DOS 可执行文件的库函数时遇到了一些问题。

实际上,签名被正确识别为 bc31rtd(并且它指出 199 作为应用签名的实际数量)。例如strcmp,正确识别、着色等。

从这里开始,我在其余代码中盲目地依赖这些库函数,直到我意识到有问题,例如,我所看到的strcpy

在此处输入图片说明

这对我来说没有意义,因为src根本没有使用。然后 repne scasb应该扫描的字符串的长度,但放置在最后一个值di[bp+dest+2]像如果两个const char*dddw(所以只是偏移量,而没有任何特定的段,并且ds隐式地使用)。

由于这让我发疯了,我通过使用 IDA Pro 直接打开 BC++3.1 的 CC.LIB 来检查该函数的原始实现,并且实现确实不同:

在此处输入图片说明

那么问题出在哪里呢?

如何根据需要更改功能?我尝试直接修改堆栈变量 (Ctrl+K),但随后偏移量出现错误(例如[bp+8]标记为红色)。

如果我做出了一些我没有意识到的微不足道的错误假设,我很抱歉。

1个回答

哦,近函数与远函数、近指针与远指针以及混合模型(远函数、近指针)的快乐

回到 16 位世界,程序可以

  • 最多使用 64 KB 代码和 64 KB 数据,所有指针都使用 16 位,并忽略段寄存器。这被称为near模型,因为所有偏移量都在同一段内

或者

  • 选择能够拥有超过 64 KB 的代码,以及超过 64 KB 的数据;将指针设为 32 位(16 位段和 16 位偏移),并在使用指针时弄乱段寄存器。这被称为far模型,因为指针可以指向不同的段,实际上,整个地址空间

或者

  • 使用混合模型 - 代码的近指针和数据的远指针(更常用),反之亦然(我不知道使用它的单个程序)。

现在,问题是,strcpy您程序中的函数似乎是远代码近数据版本,而strcpy来自库的函数似乎是近代码远数据版本。

您会看到第一个函数如何确保es= ds( push ds; pop es) 但不会与段混淆。这将使它使用 16 位指针。retf在年底提出它使用far代码约定。

第二个函数使用LES di, [bp+src], 同时加载esdi这意味着它使用far堆栈上的数据指针,retn最后意味着它使用near代码模型。

发生的事情是,在您的反汇编程序中,IDA 看到了retf、扣除了far code,并且可能也假设far data了 - 这是错误的。如果数据确实是far,那么您将有 4 个字节用于src,另外还有 4 个字节用于dst,这就是 ida 在您的堆栈上显示的内容。但实际上,每个指针只有 2 个字节,因此dest在偏移量 6 处,但src在偏移量 8 处,而不是 0x0a (10)。这就是为什么访问src显示为dest+2,而 IDA 错误地假设为 的(错误的)偏移量 0x0asrc根本没有使用。

如图所示:

This is what IDA thinks:           and this is the real stack layout:

+----------------------------+     +--------------------------------+
|000c src  segment           |     |                                |
|000a src  offset            |     |                                |
|0008 dest segment           |     |0008 src                        |
|0006 dest offset            |     |0006 dest                       |
|0004 saved bp               |     |0004 saved bp                   |
|0002 return address segment |     |0002 return address segment     |
|0000 return address offset  |     |0000 return address offset      |
+----------------------------+     +--------------------------------+

要解决此问题,请打开函数原型对话框,并将指针定义更改为char near *