In all honesty, the GTAIV eboots are at the top of my list for difficulty, mostly because it was written in C++. Even once you have an analyzed IDA db, the vast majority of XREFs (cross-references) will be wrong, and manual effort is needed to fix them up. Don't get me wrong here, if you are properly motivated, much can be learned that will have relevancy to just about any RE you do in the future.
Here is a quick example of the biggest issue you will be met with, what I call a "sub-TOC", it probably has a more clever name in actuality but I have not read about this monster in any documents it is merely a by-product of the compiler.
C pseudo-code:
Code:
r30 = *(TOC - 0x7FD0); // 0x11959F8 - 0x7FD0 = 0x118DA28
r31 = *(TOC - 0x7FCC); // 0x11959F8 - 0x7FCC = 0x118DA2C
There are plenty of well-written documents to be found on the 'net explaining the TOC so I will not go into any detail here about it, google is your friend in this case. This happens to be from GTAIV EFLC which has a TOC address of
0x11959F8, in this function there are 2 sub-TOCs utilized: r30 and r31. In the above pseudo-code you can see the value placed into r30/r31 is dereferenced, meaning the value comes from a pointer which is represented in assembly as
offset(register), and using a load/store. Here is an example of this in assembly:
Code:
lwz r30, -0x7FD0(r2) # 0x118DA28 -> 0x11CA294
lbz r0, 0(r30) # 0x11CA294
...
lwz r31, -0x7FCC(r2) # 0x118DA2C -> 0x11C36D0
stw r0, 0(r31) # 0x11C36D0
In the above snippet 0x11959F8 - 0x7FD0 = 0x118DA28, so the long-word at 0x118DA28 (0x11CA294) is loaded into the r30 register, and then the byte located at 0x11CA294 is loaded into r0. Often there is an additional offset calculation in the use of r30/r31, but in this case the offset is 0. For r31, 0x11959F8 - 0x7FCC = 0x118DA2C, loads the long-word at 0x118DA2C (0x11C36D0) into r31, and stores the word located in r0 to 0x11C36D0. It is extremely important you grasp this before even thinking any further about looking over the GTAIV assembly code, it is utilized in just about every function. In IDA you can fix up these occurences with CTRL-R, but be sure to adjust the "Base Address" to 32-bits, 0x11C36D00118D9F0 needs to be fixed to 0x11C36D0, once fixed the XREF will be proper. For bonus points, automate this task.
I wish you luck trying to realize anything meaningful with just the ProDG output, it could be done, but would be extremely time intensive. Both tools have their proper place, utilize IDA to locate locations for breakpoints, and use ProDG to interrogate memory and registers at a particular section of code.