Ghidra is renaming EAX
as param_1
. Why is this happening? I find it very confusing since it is clearly not a parameter and different uses of EAX
are named as if they held the same value.
This is a feature that can be deactivated by unticking the option Markup Register Variable Reference
found in the Edit -> Tool Options
window in the pane Options -> Listing Fields -> Operands Field
.
I would personally not turn this off, because I suspect the proper way to resolve this is to get Ghidra to recognize the local variables the eax
usages present, which will then be renamed accordingly. This should only require some minor cleanup of the decompiled code, possibly even just by using Commit Local Names
, which is found in the context menu of the decompiler window.
-
This is correct. The
Commit Local Names
seems the correct way, however it is a bit confusing. After applying the option, EAX is renamed:CALL xxx; MOV EBX ,hModule
. ThishModule
suddenly appears "out of the blue", whereas if it wasEAX
it was obvious that was the value returned by theCALL
.hModule
could be a different value defined before theCALL
, it is not obvious it came from the returned value. – user1156544 Apr 15 '20 at 16:13 -
I think a better approach for Ghidra would be to rename
EAX
toparam_1
just as long as it is not changed by aCALL
. Then,EAX
is not reallyparam_1
anymore. – user1156544 Apr 15 '20 at 16:33 -
I suspect it is renamed to
hModule
because this is the return type of the call and thus also used for the local variable that holds the return value? There should be a local variablehModule
in the decompiler view, try renaming that. If this is a local variable that is reused but actually has a different meaning read reverseengineering.stackexchange.com/questions/21236/… and split out the variable into a new one – Florian Magin Apr 15 '20 at 16:45
Ghidra renamed EAX as param_1
because it is a parameter for the current function. This calling convention is similar to fastcall
, although not quite the same. Selecting how to pass arguments to functions is up to the compiler, so long as the code belong to the same program.
At the beginning of your code, param_1
(EAX) contains a pointer to a OLECHAR
object. Later, it is saved to local_8
.
@2af4 MOV param_1,EDI
. This sets the first parameter to the next call, @2af6.
Because EAX is used as parameter for many other functions inside your code, it may be correct to name it param_x
even when the value is clearly not the same. On 2b04, the saved original parameter is loaded into EAX, again, being the first parameter for the next call.
Personally, I like to use register names and not renaming them, but what you see here does make sense.
Edit: You can see that when calling external functions, like FindResourceW
the calling convention changes and param_1
is now on the stack. This is where it is shown in Green rather than Yellow.
-
The issue is that renaming the first argument of the function that is shown, will rename all occurrences of
param_1
. At2b13
I would expectparam_1
to be the return value ofFindResourceW
. Why do you think it is the originalparam_1
on the stack? My understanding of the color is that greens are the reads that directly depend on the variable that is written at the occurrence that was clicked on. – Florian Magin Apr 15 '20 at 14:39 -
FindResourceW
returns a value in EAX and right after the call there is amov EBX,param_1
. It would be safe to assume that is is EAX. Right after that EBX (with the return value) is pushed on to the stack and becomesparam_1
for the next function. The last call in this code is again an internal function withparam_1
in EAX and it is also Yellow again. – Yotamz Apr 15 '20 at 14:56 -
1I am fairly sure that you are mistaken. Your assumption seems to be that
param_1
means that it is the first parameter to various functions. This not the case, because if you rename the first argument of the functionFUN_00402ad0
fromparam_1
tofoo
all the occurrences ofparam_1
will be replaced withfoo
. – Florian Magin Apr 15 '20 at 15:31 -
1Your assumption about the meaning of the color is also mistaken (and thus I assume just speculation?). Under
Options -> Listing Fields -> Cursor Text Highlight
is an option forScoped Read Highlight Color
. If you change this, the color of those highlights will change from green to whatever you selected. Which proves my point that this is dataflow analysis that marks the reads from that register and has nothing to do with the variable being currently stored on the stack or in a register. – Florian Magin Apr 15 '20 at 15:35 -
I think you both are right in some of your comments: param_1 is used as a replacement for EAX, regardless of anything. It can be renamed to "foo" and it will be changed at every location. Colours are marked in blocks of usage, so they change as soon as the value is written.
MOV EBX, param_1; MOV ECX, param_1
will have same colour, but thenMOV param_1, xx
will start a new colour block. The colour does not mark the "same" variable.param_1
read before aCALL
can be identified with the same colour as aparam_1
read after theCALL
, and they are clearly not the same thing. – user1156544 Apr 15 '20 at 16:03