I'm working in a Delphi binary and found a little issue while generating pseudocode. This is the output (after some clean up) that IDA gives me:
Integer __fastcall LBCommon::TLBMemStream::GetFromId(PLBMemStream Self, Integer Id)
{
int v4[2]; // [esp+0h] [ebp-10h] BYREF
if ( LBCommon::IndexFromId(Self->FFullData, Id, &v4[1]) )
v4[0] = &Self->FFullData[*&Self->FFullData[sizeof(TLBDataEntry) * v4[1] + 0x19] + offsetof(TLBDataItem, FData)];
else
v4[0] = 0;
return v4[0];
}
As you can see, it is just a simple piece of code where it does some simple math en then returns. But there is a problem: v4 is represented as an array of integers instead of two separated variables.
In theory, v4[0] is a "Pointer" to memory that will be returned while v4[1] is a variable that should have a number of times to advance. But IDA thinks of them as an array and just sticks them together. I tried separating them by setting the type to "int v4" and it worked, but IDA then told me:
/ local variable allocation has failed, the output may be wrong!
It also shows the two variables generated with the color red signaling that something is wrong.
I don't know a lot about how IDA generates the Pseudocode from the ASM, but I believe that the issue is with how the code access the memory regions. For v4[0] it does "mov edx, [esp+10h+var_10]" and for v4[1] it does "mov edx, [esp+10h+var_10+4]" so I believe that it is the reason why they are seen as an array.
Here is the function in ASM just in case:
CODE:0046A7E4 var_10 = dword ptr -10h
CODE:0046A7E4
CODE:0046A7E4 push ebx
CODE:0046A7E5 push esi
CODE:0046A7E6 add esp, 0FFFFFFF8h
CODE:0046A7E9 mov esi, edx
CODE:0046A7EB mov ebx, eax
CODE:0046A7ED lea ecx, [esp+10h+var_10+4] ; Index
CODE:0046A7F1 mov edx, esi ; FId
CODE:0046A7F3 mov eax, [ebx+4] ; Header
CODE:0046A7F6 call LBCommon::IndexFromId
CODE:0046A7FB test al, al
CODE:0046A7FD jz short loc_46A818
CODE:0046A7FF mov eax, [ebx+4]
CODE:0046A802 mov edx, [esp+10h+var_10+4]
CODE:0046A806 mov eax, [eax+edx*8+19h]
CODE:0046A80A mov edx, [ebx+4]
CODE:0046A80D lea eax, [edx+eax]
CODE:0046A810 add eax, 0Dh
CODE:0046A813 mov [esp+10h+var_10], eax
CODE:0046A816 jmp short loc_46A81D
CODE:0046A818 ; ---------------------------------------------------------------------------
CODE:0046A818
CODE:0046A818 loc_46A818:
CODE:0046A818 xor eax, eax
CODE:0046A81A mov [esp+10h+var_10], eax
CODE:0046A81D
CODE:0046A81D loc_46A81D:
CODE:0046A81D mov eax, [esp+10h+var_10]
CODE:0046A820 pop ecx
CODE:0046A821 pop edx
CODE:0046A822 pop esi
CODE:0046A823 pop ebx
CODE:0046A824 retn
Is there a way to fix the issue without generating an error? Because I don't believe the original developers used an array here to do this simple thing and it is a problem that has been repeating itself for a while in some parts.