0

I've open a DLL in IDA v7. In one subroutine, there is a PathAllocCombine() function. The pesudocode shows six arguments in it. But the documentations shows there are four arguments i.e. PathAllocCombine(PCWSTR, PCWSTR, unsigned long, PWSTR);

The pseudocode is as follows:

_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;
}

And here is the graph view of that subroutine (conditional jump is removed):

PathAllocCombine_call

So, is this an internal bug in IDA? Or am I doing anything wrong?

  • The x64 calling convention passed the first 4 parameters in registers, but the others in stack. Because of this, if the function definition is not known by the decompiler, it is hard to distinguish additional parameters from setting value of local variables. Since the PathAllocCombine function was called at the start of the function, the 5th and 6th may be just local variables. However, it is only a guess without the assembly code. – ebux Apr 3 '18 at 7:21
3

Yes it's a common thing for IDA to fail to detect the arguments number if they are passed through the registers. It often happens for fastcall convention, because it's hard to track registers and determine if it was a temporary value or an argument. So it's up to you to help IDA and specify the correct function definition. Or if you're skilled enough, you may try to implement a plugin for IDA which will extend autoanalysis feature.

4

Thanks @anton-kukoba for the tip. I've resolved my issue and here is my procedure.

Right click on the PathAllocComnbine() function in pseudocode mode and choose "Set Item Type". Then add the function as follows (remove all the SAL and variable names):

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

Now the pseudocode becomes as follows which contains four parameters:

_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;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.