5

I'm writing small C programs to teach myself how to use GDB to disassemble code. The C in question is:

void function( char **pointer )
{
   *pointer = malloc(100);
   strcpy(*pointer,"This is text");
}

The disassembly is:

0x400620:    push   %rbp
0x400621:    mov    %rsp,%rbp
0x400624:    sub    $0x10,%rsp
0x400628:    mov    %rdi,-0x8(%rbp)
0x40062c:    mov    $0x64,%edi
0x400631:    callq  0x4004f0 <malloc@plt>
0x400636:    mov    %rax,%rdx
0x400639:    mov    -0x8(%rbp),%rax
0x40063d:    mov    %rdx,(%rax)
0x400640:    mov    -0x8(%rbp),%rax
0x400644:    mov    (%rax),%rax
0x400647:    movabs $0x2073692073696854,%rcx
0x400651:    mov    %rcx,(%rax)
0x400654:    movl   $0x74786574,0x8(%rax)
0x40065b:    movb   $0x0,0xc(%rax)
0x40065f:    leaveq 
0x400660:    retq   

I understand the prologue: 0x400620-0x400624. I also understand that the pointer is being initialized to 100 char here: 0x400628-0x40063d.

I cannot seem to figure out what strcpy is doing and I do not understand how to examine the contents of the addresses listed in 0x400647 and 0x400654.

Can someone help me work through this?

5

So, I assume that you understood the stack-frame initialization part and the call to the malloc through the PLT (Procedure Linking Table).

0x400636:    mov    %rax,%rdx

This line take the return code of the malloc function and save it in the rdx register. This value correspond to the address of the memory space you just created through the malloc call.

0x400639:    mov    -0x8(%rbp),%rax

Here, you take the first argument of the function we are in (char **pointer according to your source code) and it is stored in the rax register.

0x40063d:    mov    %rdx,(%rax)

This line transfert the address of the allocated memory area to the pointer variable.

0x400640:    mov    -0x8(%rbp),%rax

An (unnecessary) copy of the first argument of function in rax (the register already store this value, probably a glitch of the compiler that did not optimized enough).

0x400644:    mov    (%rax),%rax

Set rax as the address pointed by pointer.

0x400647:    movabs $0x2073692073696854,%rcx

To understand that, you need to decompose this magic number 0x2073692073696854 and cut it into pieces. Lets use gdb for that:

(gdb) p /c 0x54
$1 = 84 'T'
(gdb) p /c 0x68
$2 = 104 'h'
(gdb) p /c 0x69
$3 = 105 'i'
(gdb) p /c 0x73
$4 = 115 's'
(gdb) p /c 0x20
$5 = 32 ' '
(gdb) ...

I guess that you start to see what is the meaning of this big number by now...

0x400651:    mov    %rcx,(%rax)

On this line, the previous magic number is stored in the address pointed by pointer.

0x400654:    movl   $0x74786574,0x8(%rax)

This last magic number is, in fact, the end of your string (it correspond to the word text).

0x40065b:    movb   $0x0,0xc(%rax)

Copy the \0 character to end the string at the right place (0xc is the size of the string and rax is the start address of the string).

| improve this answer | |
  • The text seems to be in the wrong order in the register value - that is because x86/64 stores values in little-endian – user45891 Sep 12 '15 at 10:52
  • I forgot to tell about that, wasn't it obvious ? – perror Sep 12 '15 at 13:52
  • The likelihood of it being obvious for people not that deep into assembly are fairly low. I try to read answers here as if I knew next to nothing and saw that as a possible follow-up question – user45891 Sep 12 '15 at 14:06
  • This pretty much explains it. I was thinking that the string was stored at instead of the string was those funny numbers. Thanks for the explanation. – David Lee Braun Sep 12 '15 at 15:14
2

Look at the hex digits at 0x400647 and convert them to ascii characters, byte by byte (2 digits by 2 digits). Does the result ring a bell?

Since the source for your strcpy is a constant string, the compiler optimizes "copy the contents of a static string, byte by byte, until \0 is reached" to "fill the target with the expected bytes in the fastest way possible".

If you want to see what the memory looks like after the optimized strcpy, set a breakpoint on 0x40065b and enter x/20b *$rax.

| improve this answer | |
  • Because I did not use any optimization flags it never occurred to me that the compiler was taking liberties and optimizing. thanks for pointing this out Guntram. – David Lee Braun Sep 12 '15 at 15:16

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.