函数调用:外部参照类型总是“Code_Far_Call”还是“Code_Near_Call”?

逆向工程 艾达 拆卸 部件 蟒蛇 Python
2021-06-30 12:45:17

给定 IDA Pro 中的拆卸线,例如

.text:0040255B      call    sub_407C10

我是否正确假设使用分析归属地址

idautils.XrefsFrom(0x0040255B)

总是返回“Code_Far_Call”(xref.type 16)或“Code_Near_Call”(xref.type 17)类型的外部参照,而不是“Code_Near_Jump”或“Code_Far_Jump”类型的外部参照?

换句话说,是否可以通过检查外部参照类型是 16 类型还是 17 类型,然后取外部参照中的值来始终识别函数调用目标地址?

当然,除了 Call/Jump 外部参照之外,上面的语句总是返回一个类型为 21(普通控制流)的外部参照。

可以在此处找到可能的外部参照类型列表:https : //code.google.com/p/idapython/source/browse/trunk/python/idautils.py

Code_Far_Call 外部参照和 Code_Near_Call 外部参照有什么区别?

谢谢你的帮助!

1个回答

这在一定程度上取决于您的编译器,实际上,由于您似乎使用的是 32 位操作系统,因此我不希望有任何远调用。

Near 调用和 Far 调用是 16 位区域的残余,其中同一 64 KB 段内的调用仅更改IP,但未更改CS,被命名为 a near call,而对地址空间中任何位置的调用,更改CS IP,被命名为一个far call相应地,有两个不同的指令retretf从子程序返回,这将仅从堆栈中弹出IP, 或CSIP

随着保护模式和 32 位段的引入,段寄存器的管理成为操作系统的责任,用户模式程序不再摆弄它们。因此,您不应该再看到任何远距调用或retf指令——除非您可能正在拆卸处理任务切换的操作系统部分。

然而,您可能会看到偶尔跳转到一个函数(参考类型 19),这取决于您的编译器。如果编译器优化尾递归,它将用“jmp self”指令替换最后的“call self / ret”指令,如果参数类型匹配,它也可能用“jmp someotherfunction”替换“call someotherfunction / ret” . 我在 ARM 代码和 64 位英特尔代码中经常看到这种情况,但现在不记得在 32 位编译的英特尔代码中看到过它。但是,我最近很少使用 32 位 Intel 程序集,因此可能有一些较新的编译器在我没有注意到的情况下执行此操作。