passing character pointers to an external x86 32bit function

189 Views Asked by At

I am trying to write a small program that takes two hard coded character pointers and switches the contents that they point to using an external x86 32bit function located in a .S file. I am using the basic gcc compiler. Here is my C code:

valSwap.c:

#include <stdio.h>

void extern swapMe(char* c, char* d);

int main() {
        char* c = "boi";
        char* d = "bra";
        printf("%s, %s", c, d);

        swapMe(c, d);

        printf("%s, %s", c, d);
        return 0;

}

Before running swapMe(c, d) the strings that c and d point to are quite clear. After running swapMe(c, d) I get a Segmentation Fault. Here is my code for the swapMe external function:

swapMe.S:

.intel_syntax noprefix
.text
.global swapMe

swapMe:
        push edi
        push esi
        mov eax, [esp+4]
        mov ecx, [esp+8]

        mov edi, [eax]
        mov esi, [ecx]
        mov [eax], esi
        mov [ecx], edi

        pop esi
        pop edi

        ret

Now since swapMe(c, d) is taking in 2 parameters using the cdecl calling convention I should find c and d on the stack at $esp+4 and $esp+8. I tried to print these values to confirm that they are what I expect. Either they are not what I expected or I tried to print them incorrectly:

(gdb) p/s $esp+4
$1 = (void *) 0xffffdb08
(gdb) x/s $esp+4
0xffffdb08:     ""
(gdb) p/s *($esp+4)
Attempt to dereference a generic pointer.
(gdb) x/s *($esp+4)
Attempt to dereference a generic pointer.

I also tried printing $eax as a string since I moved the contents of $esp+4 into $eax.

(gdb) p/x $eax
$3 = 0xf7fa0000
(gdb) x/s $eax
0xf7fa0000:     "\260=\033"
(gdb) x/s *$eax
0x1b3db0:       <error: Cannot access memory at address 0x1b3db0>
(gdb) x/x $eax
0xf7fa0000:     0xb0

I also printed the hex values of c and d before entering swapMe to see if I'm at least getting the correct value:

(gdb) p &c
$12 = (char **) 0xffffdb2c
(gdb) p c
$16 = 0x565556c0 "boi"
(gdb) p &d
$14 = (char **) 0xffffdb28
(gdb) p d
$15 = 0x565556c4 "bra"

I printed a few others values that may be relevant as well:

   30x56555621 <swapMe+2>   mov    eax,DWORD PTR [esp+0x4]                                                             3
   30x56555625 <swapMe+6>   mov    ecx,DWORD PTR [esp+0x8]                                                             3
  >30x56555629 <swapMe+10>  mov    edi,DWORD PTR [eax]                                                                 3
   30x5655562b <swapMe+12>  mov    esi,DWORD PTR [ecx]

(gdb) p/x $eax
$8 = 0xf7fa0000



0x56555621 <swapMe+2>   mov    eax,DWORD PTR [esp+0x4]                                                             3
   30x56555625 <swapMe+6>   mov    ecx,DWORD PTR [esp+0x8]                                                             3
   30x56555629 <swapMe+10>  mov    edi,DWORD PTR [eax]                                                                 3
  >30x5655562b <swapMe+12>  mov    esi,DWORD PTR [ecx]                                                                 3
   30x5655562d <swapMe+14>  mov    DWORD PTR [eax],esi                                                                 3
   30x5655562f <swapMe+16>  mov    DWORD PTR [ecx],edi

p/x $edi
$11 = 0x1b3db0


 30x56555621 <swapMe+2>   mov    eax,DWORD PTR [esp+0x4]                                                             3
   30x56555625 <swapMe+6>   mov    ecx,DWORD PTR [esp+0x8]                                                             3
   30x56555629 <swapMe+10>  mov    edi,DWORD PTR [eax]                                                                 3
   30x5655562b <swapMe+12>  mov    esi,DWORD PTR [ecx]                                                                 3
  >30x5655562d <swapMe+14>  mov    DWORD PTR [eax],esi                                                                 3
   30x5655562f <swapMe+16>  mov    DWORD PTR [ecx],edi

(gdb) p/x $ecx
$19 = 0x565555f5
(gdb) p/x $esi
$20 = 0x8310c483

I don't understand why I'm getting different values when I print the values of $eax, $edi, $ecx, and $esp in swapMe vs when I print the values associated with c and d before calling swapMe. Since swapMe takes in c and d as parameters, I expected to see the same values on the stack when calling swapMe but I do not. I did not see 0xffffdb2c or 0x565556c0 once when printing any registers. Please clarify what I did wrong when calling the function, passing in the parameters, or printing the values in the registers. I'm very new to x86 so I probably made a rookie mistake somewhere.

0

There are 0 best solutions below