Steps to reproduce:
- Compile the following code as an x86 Debug MSVC console application:
void test(void* pData,void** var)
{
*(void**)pData = var;
}
int main(int argc, char* argv[])
{
test(&argc, (void**)argv);
return 0;
}
- Open the resulting executable in IDA with the PDB loaded, and navigate to the pseudocode of the
testfunction. You will see the following code:
void __cdecl test(_DWORD *pData, void **var)
{
*pData = var;
}
- Rename this decompiled function to
test2, copy it back into the original source code, and include"defs.h". The code will look something like this:
#include "D:\Program Files\IDA Professional 9.5 BETA1\include\defs.h"
void test(void* pData,void** var)
{
*(void**)pData = var;
}
void __cdecl test2(_DWORD* pData, void** var)
{
*pData = var;
}
int main(int argc, char* argv[])
{
test(&argc, (void**)argv);
return 0;
}
- Compiling this will result in the following error:
1>qwdq.cpp
1>Z:\qwdq\qwdq\qwdq.cpp(13,11): error C2440: '=': cannot convert from 'void **' to 'uint32'
1> Z:\qwdq\qwdq\qwdq.cpp(13,11):
1> There is no context in which this conversion is possible
1>Done building project "qwdq.vcxproj" -- FAILED.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
========== Rebuild completed at 6:51 and took 01.521 seconds ==========
- Furthermore, if you try to forcefully change the type of
pDataback tovoid*inside IDA, you will get the following pseudocode:
void __cdecl test(void *pData, void **var)
{
*(_DWORD *)pData = var;
}
This is still not valid, compilable code, as it continues to trigger the same C2440 (invalid cast) error.
Conclusion:
Therefore, I believe there is a bug in IDA’s pseudocode generation logic when it comes to setting contents/assigning values to dereferenced void* pointers. The decompiler seems to incorrectly cast the destination to an integer type (_DWORD) instead of maintaining the proper pointer-to-pointer cast (void**).