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.

enter image description here


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.

| improve this answer | |
  • 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. This hModule suddenly appears "out of the blue", whereas if it was EAX it was obvious that was the value returned by the CALL. hModule could be a different value defined before the CALL, it is not obvious it came from the returned value. – user1156544 Apr 15 at 16:13
  • I think a better approach for Ghidra would be to rename EAX to param_1 just as long as it is not changed by a CALL. Then, EAX is not really param_1 anymore. – user1156544 Apr 15 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 variable hModule 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 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.

| improve this answer | |
  • The issue is that renaming the first argument of the function that is shown, will rename all occurrences of param_1. At 2b13 I would expect param_1 to be the return value of FindResourceW. Why do you think it is the original param_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 at 14:39
  • FindResourceW returns a value in EAX and right after the call there is a mov 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 becomes param_1 for the next function. The last call in this code is again an internal function with param_1 in EAX and it is also Yellow again. – Yotamz Apr 15 at 14:56
  • 1
    I 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 function FUN_00402ad0 from param_1 to foo all the occurrences of param_1 will be replaced with foo. – Florian Magin Apr 15 at 15:31
  • 1
    Your 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 for Scoped 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 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 then MOV param_1, xx will start a new colour block. The colour does not mark the "same" variable. param_1 read before a CALL can be identified with the same colour as a param_1 read after the CALL, and they are clearly not the same thing. – user1156544 Apr 15 at 16:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.