我很难理解Perl的print
命令解释十六进制值的方式。我正在使用一个只有8行的非常简单的程序来演示我的问题。以下代码gdb
将详细解释我的问题:
anil@anil-Inspiron-N5010:~/Desktop$ gcc -g code.c
anil@anil-Inspiron-N5010:~/Desktop$ gdb -q ./a.out
Reading symbols from ./a.out...done.
(gdb) list
1 #include <stdio.h>
2
3 int main(int argc, char* argv[])
4 {
5 int i;
6 for (i =0; i<argc; ++i)
7 printf ("%p\n", argv[i]);
8 return 0;
9 }
(gdb) break 8
Breakpoint 1 at 0x40057a: file code.c, line 8.
(gdb) run $(perl -e 'print "\xdd\xcc\xbb\xaa"') $(perl -e 'print "\xcc\xdd\xee\xff"')
Starting program: /home/anil/Desktop/a.out $(perl -e 'print "\xdd\xcc\xbb\xaa"') $(perl -e 'print "\xcc\xdd\xee\xff"')
0x7fffffffe35d
0x7fffffffe376
0x7fffffffe37b
Breakpoint 1, main (argc=3, argv=0x7fffffffdfe8) at code.c:8
8 return 0;
(gdb) x/2x argv[1]
0x7fffffffe376: 0xaabbccdd 0xeeddcc00
在上面显示的行中,我使用gdb
来调试程序。作为命令行参数,我传递了两个(十六进制)参数(不包括程序本身的名称):\xdd\xcc\xbb\xaa
和\xcc\xdd\xee\xff
。由于little-endian体系结构,这些参数应该被解释为0xaabbccdd
和0xffeeddcc
,但正如您可以看到上面显示的最后一行调试显示0xaabbccdd
和0xeeddcc00
。为什么会这样?我错过了什么?其他一些论点也发生了这种情况。我请你帮我这个。
PS:2 ^ 32 = 4294967296且0xffeeddcc
= 4293844428(2 ^ 32> 0xffeeddcc
)。我不知道是否还有任何联系。
答案 0 :(得分:2)
通过将字符串打印为数字,您会感到困惑。在小端架构中,在一个四字节值(如0xDDCCBBAA)中,字节从起始地址编号为从左到右。
那么让我们来看一下调试器命令的输出:
(gdb) x/2x argv[1]
0x7fffffffe376: 0xaabbccdd 0xeeddcc00
逐字节查看,它将是:
0x7fffffffe376: dd
0x7fffffffe377: cc
0x7fffffffe378: bb
0x7fffffffe379: aa
0x7fffffffe37a: 00 # This NUL terminates argv[1]
0x7fffffffe37b: cc # This address corresponds to argv[2]
0x7fffffffe37c: dd
0x7fffffffe37d: ee
哪个不出意外,不是吗?
您可能希望使用类似的内容以十六进制显示参数:
x/8bx argv[1]
(在 x adecimal中显示 8 b ytes)
答案 1 :(得分:2)
命令行参数是以NUL结尾的字符串。
参数argv[1]
是指向NUL终止字符串的第一个字符的指针。
7FFFFFFFE376 DD CC BB AA 00
argv[2]
是指向NUL终止字符串的第一个字符的指针。
7FFFFFFFE37B CC DD EE FF 00
如果你注意,你会注意到它们恰好一个接一个地位于记忆中。
7FFFFFFFE376 DD CC BB AA 00 CC DD EE FF 00
您要求从argv[1]
7FFFFFFFE376 DD CC BB AA 00 CC DD EE FF 00
----------- -----------
0xAABBCCDD 0xEEDDCC00
要使x/2x
更正确,您需要使用
perl -e'print "\xdd\xcc\xbb\xaa\xcc\xdd\xee\xff"'
-or-
perl -e'print pack "i*", 0xaabbccdd, 0xffeeddcc'
对于您传递的参数,您需要使用
(gdb) x argv[1]
0x3e080048cbd: 0xaabbccdd
(gdb) x argv[2]
0x3e080048cc2: 0xffeeddcc