我正在编写小型C程序,以自学如何使用GDB分解代码。有问题的C是:

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


反汇编是: -0x400620。我也理解指针在这里被初始化为100个字符:0x400624-0x400628。在0x40063dstrcpy中。

有人可以帮我解决这个问题吗?

#1 楼

因此,我假设您了解堆栈框架初始化部分以及通过PLT(过程链接表)对malloc的调用。 malloc功能的代码并将其保存在rdx寄存器中。此值对应于您刚刚通过malloc调用创建的内存空间的地址。根据您的源代码)并将其存储在char **pointer寄存器中。

0x400636:    mov    %rax,%rdx


这行代码将分配的存储区的地址转移到rax变量。 >
0x400639:    mov    -0x8(%rbp),%rax


pointerfunction的第一个参数的(不必要的)副本(寄存器已经存储了该值,可能是编译器的故障,它没有充分优化)。 />
0x40063d:    mov    %rdx,(%rax)


rax设置为rax指向的地址。

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


要了解这一点,您需要分解幻数pointer并将其切成碎片。让我们使用0x2073692073696854来实现以下目的: >
0x400644:    mov    (%rax),%rax


这行代码中,前一个幻数存储在gdb指向的地址中。

0x400647:    movabs 
(gdb) p /c 0x54
 = 84 'T'
(gdb) p /c 0x68
 = 104 'h'
(gdb) p /c 0x69
 = 105 'i'
(gdb) p /c 0x73
 = 115 's'
(gdb) p /c 0x20
 = 32 ' '
(gdb) ...
x2073692073696854,%rcx

实际上,字符串的结尾(与单词pointer对应)。

0x400651:    mov    %rcx,(%rax)


复制text字符以将字符串结尾在正确的位置(0xc是字符串的大小,rax是字符串的起始地址。

评论


文本在寄存器值中的顺序似乎不正确-这是因为x86 / 64将值存储在little-endian中

–user45891
2015年9月12日上午10:52

我忘了告诉我,这不是很明显吗?

–恐怖
2015年9月12日下午13:52

对于不那么深入汇编的人来说,这种可能性很明显。我在这里尝试阅读答案,好像我几乎一无所知,并将其视为可能的后续问题

–user45891
2015年9月12日14:06在

这几乎可以解释它。我以为这些字符串存储在那些有趣的数字而不是字符串中。感谢您的解释。

–David Lee Braun
2015年9月12日15:14在

#2 楼

查看0x400647处的十六进制数字,并将它们转换为ASCII字符,逐字节(2位数乘2位数)。结果会响起吗?

由于strcpy的源是常量字符串,因此编译器将“逐字节复制静态字符串的内容,直到到达strcpy”优化为“填充”

如果要查看经过优化的0x40065b后的内存情况,请在x/20b *$rax上设置断点并输入q4312079q。

评论


因为我没有使用任何优化标志,所以我从来没有想到编译器会获得自由并进行优化。感谢您指出Guntram。

–David Lee Braun
2015年9月12日15:16