sub_xyz
)上的X键(列出外部引用)以查看调用哪个函数时,我只看到dd offset sub_xyz
两次,没有call sub_xyz
指令。没有其他地方写
call sub_xyz
我怎么看哪个函数正在调用
sub_xyz
?这只是IDA感到困惑吗?
#1 楼
尽管Nirlzr的回答很好地说明了这一点,但以下示例考虑了C ++代码和vtable的存在。代码摘自此处#include <iostream>
using namespace std;
class Vehicle {
public:
virtual void ApplyBreaks() { cout << "Vehicle Break" << endl; }
virtual void ApplyHorns() { cout << "Vehicle Horns" << endl; }
};
int main() {
Vehicle *v = new Vehicle();
v->ApplyBreaks(); // Calls vehicle ApplyBreak
v->ApplyHorns(); // Calls vehicle ApplyHorn
}
使用g ++进行编译并在IDA中打开对
ApplyBreaks
的引用。这在C ++应用程序中很常见,在vtables中具有函数引用。此外,在
Vehicle
中初始化此vtable时,已在对象中对其进行了设置,如您在此处看到的一样。在
main
中调用此类的成员函数时,地址的访问就像在编译时定义了偏移量的数组一样。 在
main+48
处访问第一个(第0个)成员ApplyBreaks
,并在main+71
处访问ApplyHorns
,该成员位于ApplyBreaks
旁边。评论
是的,VTables是一种很常见的情况,可能会发生。也许我应该更加关注这一点。好答案,+ 1 :)
– NirIzr
18年7月31日在18:08
#2 楼
如果没有其他引用,则表明没有call sub_xyz
(至少IDA已标识)。相反,IDA仅标识了对sub_xyz
的一个交叉引用,并且该引用是数据变量中的硬编码偏移量。通常,有一段代码可以访问该数据并间接调用该函数,因此您可以搜索对该数据区域的交叉引用。您应该注意,该引用不必引用
sub_xyz
偏移它的位置。取而代之的是,sub_xyz
的偏移量可以是更大的结构(或数组,或结构的数组)的一部分,可以列举出来。您需要搜索指向该区域周围的参考(这些参考也可以是地址较高的区域的偏移量,然后将其减去)。让我们举个例子
假设在查找对
sub_xyz
的交叉引用时,您在下面描述的地址00008540
上仅找到一个。unk_00008538
00008538 dd offset sub_foo
0000853c dd aFuncionFoo ; "Function Foo"
00008540 dd offset sub_xyz <- our sub_xyz reference
00008544 dd aFunctionXYZ ; "Function XYZ"
00008548 dd offset sub_abc
0000854c dd aFunctionABC ; "Function ABC"
您会注意到
dd offset sub_xyz
上方(位于地址00008540
)与另一个子例程sub_foo
(位于00008538
)有偏移,并且尽管没有对dd offset sub_xyz
(在00008540
处)的交叉引用,但有对dd offset sub_foo
(在00008538
处)的交叉引用。 > 您还可以注意到,在
00008548
处还有另一个子例程偏移量,并且在每个子例程偏移量之后还有另一个偏移量,即恰好在其中包含函数名称的字符串。这显然是一个相对简单的示例,我们可以假定它们实际上是一个结构的三个实例,每个实例都有两个成员,可以这样定义:typedef struct FunctionDefinition
{
void* func_addr;
char* func_name;
} _FunctionDefinition;
我们可以还猜测我们发现了一个由
FunctionDefinition
结构的三个实例组成的数组,并且一些代码枚举了该数组并遍历所有函数。更复杂的示例可以包括例如功能数组及其网络消息标识符,其中,例如,根据接收到的消息的类型来调度处理网络命令的功能。如果您正在使用C ++,甚至可能是函数虚拟表,也可以找到任何类的全局对象。选项是无止境的,您需要使用遇到的特定情况以及可以收集的其他信息(例如,引用该较大结构或数组的代码)来弄清楚。
评论
没有调用sub_xyz,我在外部参照中两次看到dd sub_xyz,所以您在sub_xyz区域中告诉seach外部参照,并期待在那里的呼叫?
– Keystone
18年7月30日在19:51
@Keystone我添加了一个示例,希望这可以帮助您更好地理解这一点。
– NirIzr
18年7月30日在20:30
评论
您可以拍摄dd sub_xyz周围区域的屏幕截图,还是可以提供二进制文件?那不可能。我需要在那里看什么?是反调试吗?