A large part of diagnosing Hopper issues is trying new things. I always encourage calculated change to see how change may affect your Hopper outcomes. Often however, what you think might be an updated executable is actually just a rebuilt version of the prior one with an updated timestamp which is not helpful.
So how do you know that your changes made it into the new binary?
Microsoft provides a utility called dumpbin that can tell you exactly what is in each binary. If you can read and understand ARM assembly then the process is easy – you simply look for your change in the output and if its present then you are done. If not, your change got lost somewhere during the build or sysgen and you need more investigation. If you cannot read and understand ARM assembly, you are still in luck since you can focus on finding change – simply compare the old version with the new binary to determine the difference. For example, we needed to make a change to Hopper that dealt with how we handled the CEFlushDBVol() function call – this is what the assembler looked like before we made the change:
Dumpbin /disasm hopper.exe > oldHopper.out
…
00036DE4: EB002851 bl SetLastError
00036DE8: E3A00000 mov r0, #0
00036DEC: EB00284C bl CeFlushDBVol << Call that we change here
00036DF0: E3500000 cmp r0, #0
00036DF4: 1A000004 bne 00036E0C
00036DF8: EB002804 bl GetLastError
00036DFC: E59F1044 ldr r1, [pc, #0x44]
00036E00: E1A02000 mov r2, r0
00036E04: E5950000 ldr r0, [r5]
00036E08: EBFFFB4D bl 00035B44
00036E0C: E5869000 str r9, [r6]
00036E10: EA000000 b 00036E18
…
And then we perform the same check on the new binary with our changes (in this case a check to see if CeFlushDBVol() failed with ERROR_OUT_OF_MEMORY):
Dumpbin /disasm hopper.exe > newHopper.out
…
0004F898: EB00254A bl SetLastError
0004F89C: E3A00000 mov r0, #0
0004F8A0: EB002584 bl CeFlushDBVol << Here is the same call
0004F8A4: E3500000 cmp r0, #0 << Checking return same as above
0004F8A8: 1A000009 bne 0004F8D4
0004F8AC: EB0024C1 bl GetLastError
0004F8B0: E1A02000 mov r2, r0
0004F8B4: E5950000 ldr r0, [r5]
0004F8B8: E3520008 cmp r2, #8 << Compare for out of memory error
0004F8BC: 1A000002 bne 0004F8CC
0004F8C0: E59F1040 ldr r1, [pc, #0x40]
0004F8C4: EBFFF43E bl 0004C9C4
0004F8C8: EA000001 b 0004F8D4
…
Notice how there is no check for error code #8 in the first disassembler output? Since it shows up in the latest binary we can be certain that the change made it into the latest revision. Warning: This is not a perfect solution since the code optimizer can move code which might obscure your changes. You can always turn off the optimizing to increase your chances of finding this scenario with the /Od flag.