dewolf
dewolf copied to clipboard
[Expression Propagation Memory] Implement propagation of global variables
Proposal
Currently, we do not propagate (re)definitions of global variables, as there are cases where it could lead to incorrect decompilation. Consider the following example test_global.zip:
00004010 uint32_t glob = 0x4
propagate_globals:
0 @ 0000118a [glob].d = 0xa @ mem#0 -> mem#1
1 @ 00001194 rax#1 = [glob].d @ mem#1 //<---------it is OK to propagate glob = 0xa here, then rax#1 = 0xa
2 @ 0000119a rax_1#2 = rax#1 + 0xa
...
00004010 uint32_t glob = 0x4
do_not_propagate_globals:
0 @ 00001159 [glob].d = 2 @ mem#0 -> mem#1
1 @ 00001163 rax#1 = 0
2 @ 00001168 mem#2 = change_glob() @ mem#1 //<-------------------- potentially changes glob
3 @ 0000116d rax_1#2 = [glob].d @ mem#2 //<-----------------------------cannot propagate glob = 2 here, since function call may change value of glob
....
Our current strategy was not to propagate global variables. However, such propagation would lead to cleaner decompiled code - in cases where it is possible (correct) ;)
Approach
Modify EPM (ExpressionPropagationMemory
) to handle also global variables.
It can be done in the same fashion as by variables that have pointers to it:
check if between definition and use on any path exist instruction that potentially changes the global variable - for global variables, it would be any (non-library?) function call; or, in case pointer on global variable exist, write-uses of this pointer.
There could be more corner cases here; they should be handled correspondingly.