为什么 IDA 在伪代码中显示错误的函数参数?

逆向工程 艾达 拆卸
2021-06-25 15:53:05

我在 IDA v7 中打开了一个 DLL。在一个子程序中,有一个PathAllocCombine()函数。伪代码在其中显示了六个参数。但是文档显示有四个参数,即PathAllocCombine(PCWSTR, PCWSTR, unsigned long, PWSTR);

伪代码如下:

_QWORD *__fastcall sub_180040994(_QWORD *a1, __int64 a2, __int64 a3)
{
  _QWORD *v3; // rbx
  signed int v4; // ST20_4
  unsigned int v5; // eax
  void *retaddr; // [rsp+38h] [rbp+0h]

  v3 = a1;
  v4 = 1;
  *a1 = 0i64;
  v5 = PathAllocCombine(a2, a3, 1i64, a1, v4, -2i64);
  if ( (v5 & 0x80000000) != 0 )
  {
    sub_18000A7A4(retaddr, 106i64, "unknown.cpp", v5);
    JUMPOUT(*(_QWORD *)&byte_1800409F9);
  }
  return v3;
}

这是该子程序的图形视图(删除了条件跳转):

PathAllocCombine_call

那么,这是 IDA 的内部错误吗?还是我做错了什么?

2个回答

感谢 @anton-kukoba 的提示。我已经解决了我的问题,这是我的程序。

PathAllocComnbine()在伪代码模式下右键单击该函数,然后选择“设置项目类型”。然后添加如下函数(去掉所有的 SAL 和变量名):

HRESULT PathAllocCombine(PCWSTR, PCWSTR, unsigned long, PWSTR*);

现在伪代码变成如下,其中包含四个参数:

_QWORD *__fastcall sub_180040994(_QWORD *a1, __int64 a2, __int64 a3)
{
  _QWORD *v3; // rbx
  HRESULT v4; // eax
  void *retaddr; // [rsp+38h] [rbp+0h]

  v3 = a1;
  *a1 = 0i64;
  v4 = PathAllocCombine((PCWSTR)a2, (PCWSTR)a3, 1u, (PWSTR *)a1);
  if ( v4 < 0 )
  {
    sub_18000A7A4(retaddr, 106i64, "unknown.cpp", (unsigned int)v4);
    JUMPOUT(*(_QWORD *)&byte_1800409F9);
  }
  return v3;
}

是的,如果参数通过寄存器传递,IDA 无法检测到参数编号是很常见的事情。它经常发生在 fastcall 约定中,因为很难跟踪寄存器并确定它是临时值还是参数。因此,由您来帮助 IDA 并指定正确的函数定义。或者,如果您足够熟练,您可以尝试为 IDA 实现一个插件,该插件将扩展自动分析功能。