I'm going through the book Practical Malware Analysis (specifically, Lab07-03) and I've been stuck on a rather simple problem. I've divided the code section of main() into three parts to ease my analysis. (Note: I'm assuming the stack is growing downwards here.)

Part 1) mov eax, [esp+argc]
sub esp, 44h
cmp eax, 2

Part 2) push ebx
push ebp
push esi
push edi
jnz ExitProgram

Part 3) mov eax, [esp+54h+argv]
mov esi, offset hardcodedString
mov eax, [eax+4]

Part 1:

This looks simple enough, the stack pointer (esp) is added with the memory location of argc and the value at that address is saved in the eax register. Then 44h is subtracted from esp to make room for some local variables of the main function. Finally, eax is compared to 2 and the appropriate flags are set in the flag register (the value of eax is not modified).

Part 2: Based on a similar question on StackOverFlow, it seems that the registers are pushed in Part 2 as they are callee save registers. This seems to be true as when main exits, it is popping these exact registers. Is my understanding of this correct?

Part 3: I'm adding the variables below if that helps in correcting me.

.text:00401440 var_44          = dword ptr -44h
.text:00401440 var_40          = dword ptr -40h
.text:00401440 var_3C          = dword ptr -3Ch
.text:00401440 var_38          = dword ptr -38h
.text:00401440 var_34          = dword ptr -34h
.text:00401440 var_30          = dword ptr -30h
.text:00401440 var_2C          = dword ptr -2Ch
.text:00401440 var_28          = dword ptr -28h
.text:00401440 var_24          = dword ptr -24h
.text:00401440 var_20          = dword ptr -20h
.text:00401440 var_1C          = dword ptr -1Ch
.text:00401440 var_18          = dword ptr -18h
.text:00401440 var_14          = dword ptr -14h
.text:00401440 var_10          = dword ptr -10h
.text:00401440 var_C           = dword ptr -0Ch
.text:00401440 hObject         = dword ptr -8
.text:00401440 var_4           = dword ptr -4
.text:00401440 argc            = dword ptr  4
.text:00401440 argv            = dword ptr  8
.text:00401440 envp            = dword ptr  0Ch

I also don't understand the instruction mov eax, [esp+54h+argv]. It looks like the first argument that is passed to the program is being saved in eax, so wouldn't mov eax, [esp+44h+argv] make more sense? I recognize the function of the instruction mov eax, [eax+4] is to fetch the actual input passed to the program (i.e. argv[1]), which is what makes the previous instruction's indexing so confusing.

The mov esi, offset hardcodedString is just moving the address of the first character of the string into esi, so it looks good to me.

I'd appreciate some help here!

1 Answer 1


esp had 0x44 subtracted, then an additional three registers pushed, so esp is now -0x50. Then the access is 0x50+argv+4, which is argv[1].

  • But extended registers are 4 bytes in size, so after pushing the three registers, esp should be -56h right? Adding [54h+argv] would then bring esp to 06h, which is in the middle of argv? Jan 9 at 6:55
  • 1
    0x44+(3*4=0x0c)=0x50. Jan 24 at 23:33
  • apologies for the late reply - looks like I accepted your solution only in my mind. 😅. I do not know why I messed up such a simple calculation! May 4 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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