C 溢出的字节与我在GDB上看到的不同?

C 溢出的字节与我在GDB上看到的不同?,c,security,debugging,gdb,buffer-overflow,C,Security,Debugging,Gdb,Buffer Overflow,我正试着做这件事。我知道解决方案(在写了一篇文章之后),但我正试图想出一种不同的方法 以下是我们试图在其上执行外壳代码的程序的源代码: #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main(int argc, char **argv) { char buffer[64]; gets(buffer); } 很好,我

我正试着做这件事。我知道解决方案(在写了一篇文章之后),但我正试图想出一种不同的方法

以下是我们试图在其上执行外壳代码的程序的源代码:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}

很好,我的回信地址满是4141。正如所料。现在,我要做的是将返回地址更改为接下来的4个字节,这样

00xbffff7a8: |saved frame pointer| - | return address| - |shellcode part 1| - |...| - |shellcode part n|
但是,当我尝试写入76“41”时,然后写入地址0xbffff7a8+4(即0xbffff7b0),它会不断写入错误的内容。以下是我输入的内容:

41414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141b0f7ffbf
请注意,我们是在一个小的endian系统中

然而,当我输入这个(ASCII)时,我在$esp和$ebp上看到的是:

(gdb) n
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA°÷ÿ¿
11      in stack5/stack5.c
(gdb) x/30x $esp
0xbffff760:     0xbffff770      0xb7ec6165      0xbffff778      0xb7eada75
0xbffff770:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff780:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff790:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff7a0:     0x41414141      0x41414141      0x41414141      0xb7c3b0c2
0xbffff7b0:     0xbfc2bfc3      0xbffff800      0xbffff86c      0xb7fe1848
0xbffff7c0:     0xbffff820      0xffffffff ...
(gdb) p $ebp
$1 = (void *) 0xbffff7a8
如您所见,写入的是0xb7c3b0c2,而不是预期的0xbfff7b0

有人知道这是为什么吗


注意:我意识到我真正想要的地址是0xbffff7ac,而不是0xbffff7b0。我会解决这个问题,但它不会改变我遇到的问题。

因此我最终在上发布了这个问题,LiveOverflow将我指向了这个方向

这段视频将比我更好地解释它,但实际上,python2和python3并没有将十六进制打印成相同的ascii。Python3插入额外字符,而python2打印原始十六进制字符串

我强烈鼓励你观看这段视频,因为它会深入地解释这段视频

这里另一个问题的答案@dsh也解释了这一点:

字节序列c3be是 字符U+00FE

Python2将字符串处理为字节序列,而不是 人物。所以“\xfe”是一个包含一个字节的str对象

在Python 3中,字符串是(Unicode)字符序列。所以 代码“\xfe”是包含一个字符的字符串。当您打印 字符串,则必须将其编码为字节。因为您的环境选择了 UTF-8的默认编码,它被相应地编码

如何解决这个问题取决于您的数据。是字节还是字符?如果 字节,然后更改代码以告诉解释器:print(b'\xfe')。 如果是字符,但您需要不同的编码,请进行编码 相应的字符串为:print('\xfe'.encode('latin1'))


因此,我最终在上发布了这期文章,LiveOverflow为我指明了这一方向

这段视频将比我更好地解释它,但实际上,python2和python3并没有将十六进制打印成相同的ascii。Python3插入额外字符,而python2打印原始十六进制字符串

我强烈鼓励你观看这段视频,因为它会深入地解释这段视频

这里另一个问题的答案@dsh也解释了这一点:

字节序列c3be是 字符U+00FE

Python2将字符串处理为字节序列,而不是 人物。所以“\xfe”是一个包含一个字节的str对象

在Python 3中,字符串是(Unicode)字符序列。所以 代码“\xfe”是包含一个字符的字符串。当您打印 字符串,则必须将其编码为字节。因为您的环境选择了 UTF-8的默认编码,它被相应地编码

如何解决这个问题取决于您的数据。是字节还是字符?如果 字节,然后更改代码以告诉解释器:print(b'\xfe')。 如果是字符,但您需要不同的编码,请进行编码 相应的字符串为:print('\xfe'.encode('latin1'))


@ChristianGibbons使用
get()
的目的是导致溢出。这是一个常见的示例代码,它暴露了在接受输入时不进行边界检查(以及该文章中提到的所有其他内容)的缺陷。
get()
的“坏”用法是故意的。@我知道这一点。我正在尝试使用溢出,但我在堆栈上找到的字节与我输入的字节不同(请参阅问题的最后一部分)。哈哈,我回答了其他人,他们建议您不要使用
get()
。他们显然删除了他们的评论。你能告诉我你是如何输入字节的吗?@VeridianDynamics没问题:)要得到$ebp+0x4,我需要76个字符。所以我输入'A'76次,然后输入相当于b0 f7 ff bf的asccii。当我查看GDB上的堆栈时,所有内容都是我期望的值,除了B0F7FF bf部分。如您所见,改为写入0xb7c3b0c2。如果你需要更多的信息,问题的结尾会更清楚。谢谢你的回复!您输入的确切ASCII码是什么?@ChristianGibbons使用
gets()
的目的是导致溢出。这是一个常见的示例代码,它暴露了在接受输入时不进行边界检查(以及该文章中提到的所有其他内容)的缺陷。
get()
的“坏”用法是故意的。@我知道这一点。我正在尝试使用溢出,但我在堆栈上找到的字节与我输入的字节不同(请参阅问题的最后一部分)。哈哈,我回答了其他人,他们建议您不要使用
get()
。他们显然删除了他们的评论。你能告诉我你是如何输入字节的吗?@VeridianDynamics没问题:)要得到$ebp+0x4,我需要76个字符。所以我输入'A'76次,然后输入相当于b0 f7 ff bf的asccii。当我查看GDB上的堆栈时,所有内容都是我期望的值,除了B0F7FF bf部分。如您所见,改为写入0xb7c3b0c2。如果你需要更多的信息,问题的结尾会更清楚。谢谢你的回复!您输入了什么确切的ASCII码?
(gdb) n
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA°÷ÿ¿
11      in stack5/stack5.c
(gdb) x/30x $esp
0xbffff760:     0xbffff770      0xb7ec6165      0xbffff778      0xb7eada75
0xbffff770:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff780:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff790:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff7a0:     0x41414141      0x41414141      0x41414141      0xb7c3b0c2
0xbffff7b0:     0xbfc2bfc3      0xbffff800      0xbffff86c      0xb7fe1848
0xbffff7c0:     0xbffff820      0xffffffff ...
(gdb) p $ebp
$1 = (void *) 0xbffff7a8