1

While reverse enginnering a simple C program for training, I asked myself what was the point of those lines :

                         LAB_001006b5                                    XREF[1]:     0010069d(j)  
    001006b5 48 8b 45 e0     MOV        RAX,qword ptr [RBP + local_28]
    001006b9 48 83 c0 08     ADD        RAX,0x8
    001006bd 48 8b 00        MOV        RAX,qword ptr [RAX]
    001006c0 48 89 c7        MOV        argc,RAX
    001006c3 e8 98 fe        CALL       <EXTERNAL>::atoi                                 int atoi(char * __nptr)
             ff ff

I thought that the function atoi called from the CALL instruction just pop the param from the stack (so lines from 001006b5 to 001006c0 were pointless ?) Am I getting it right or not?

Last question : what "MOV argc,RAX" means ?? I mean, argc is a constant ?

enter image description here

2 Answers 2

2

argc is an argument to the function main()

main is normally prototyped as

int __cdecl main (int argc , char *argv[] ) when locale is not used

argc is the number of arguments passed to main if you pass 5 arguments like
foo.exe 1 2 3 4 5

then argc will be 6 ( 5 arguments (space delimited ) + 1 program )

argv is a buffer that holds those arguments

argv[0]="foo.exe",argv[1]="1",argv[2]="2",argv[3]="3",argv[4]="4",argv[5]="5"

each of these arguments are 8 byte long in a 64 bit program (size of pointer)

mov [rbp+1c] , argc --> saves the numebr of arguments
cmp [rbp+1c] , 3 --> checks if you passed 2 arguments (default progname + 2 args)
if the jz jumps it reaches xxxxx6b5 to load the start of argv buffer

skips the first member argv[0] by adding 8
dereferences the second member argv1 via mov rax , [rax]

the next mov argc , rax is a misrepresentation by ghidra

(you may need to split args and rename it )

it is not argc it is rdi the default first argument that is passed by register in System V AMD64 ABI

you may check it by unlabelling or redefining the function prototype in Ghidra or

disassembling 48 89 c7 in an external disassembler like shell storm

the atoi() takes one parameter a char * and returns an integer

1
  1. MOV RAX,qword ptr [RBP + local_28]
     
    The address of the array argv (i.e., the pointer to the argv[0] element) is loaded into the RAX register.  
     

  2. ADD RAX,0x8
     
    The value in RAX register is incremented by 8 (= length of int in bytes), so now in RAX is the pointer to the argv[1] element.  
     

  3. MOV RAX,qword ptr [RAX]
     
    Now, into the RAX register is loaded the quadruple-word (i.e., 8 bytes) from the address in RAX, i.e., the value of the argv[1] element.  
     

  4. MOV argc,RAX
     
    The value in RAX, i.e., the value of argv[1], is loaded into the argc variable.  
     

The argc means “arguments count”, i.e., number of arguments.

In this particular case, in argv[0] is the only argument for the atoi() function, and argv[1] is not the (non-existing) second argument – it is in fact argc (1 in this case) immediately following argv[0].

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.