I am working with x64 and I have a program that I am disassembling through Ida so that I can outline the stack of a function and understand how much space each arg is taking up on the stack. Note I am using Intel flavor.
I am trying to disassemble the "getpwnam" C function. This function takes in a string (a username) and returns a pointer to the "passwd" structure (in the pwd.h file) for that username.
The structure has the following fields:
char *pw_name (username)
char *pw_passwd (user password)
uid_t pw_uid (user id)
gid_t pw_gid (group id)
char *pw_gecos (user info.)
char *pw_dir (user's home directory)
char *pw_shell (user's shell program)
Here is the segments of code I am trying to deconstruct:
call _getpwnam
mov [rbp- 8], rax
cmp [rbp- 8], 0
jz (exit)
mov rax, [rbp- 8]
mov eax, [rax+ 10h]
mov [rbp- 0Ch], eax
mov rax, [rbp- 8]
mov eax, [rax+ 14h]
mov [rbp- 10h], eax
mov rax, [rbp- 8]
mov rax, [rax+ 20h]
mov rdi, rax
This is my interpretation of what's going on:
mov rax, [rbp -8]
I pass in the username (from rdi register) to getpwnam which returns a pointer to its structure, and the pointer to the structure for that username is stored in rbp- 8 (8 bytes).
The next instruction mov eax, [rax + 10h]
takes the value in the rax register + 16 bytes (since rax holds the pointer to the structure, this advances 16 bytes from the beginning of the structure) which is the uid_t pw_uid field (I believe that in 64- bit each char * type is 8 bytes?) and places this 32- bit value in the eax register.
Now we are at mov [rbp- 0Ch], eax
which places this 4 byte pw_uid value into the stack at rbp- 10.
Next mov rax, [rbp- 8]
puts the pointer to the structure back into rax.
Next mov eax, [rax + 14h]
places the value of the beginning of the structure + 20 bytes (gid_t pw_gid) into eax.
Next mov [rbp- 10h], eax
transfers the pw_gid value stored in eax onto the stack at rbp- 16.
Next mov rax, [rbp- 8]
again places the pointer to the structure into rax.
Next mov rax, [rax + 20h]
puts the value of rax + 32 bytes (char *pw_gecos) into rax.
mov rdi, rax
puts *pw_gecos into rdi...
Am I interpreting this correctly, and where are my missteps?