命令行输入到C程序(使用'打印' Perl命令)

时间:2015-01-16 17:02:55

标签: c perl debugging command-line gdb

我很难理解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体系结构,这些参数应该被解释为0xaabbccdd0xffeeddcc,但正如您可以看到上面显示的最后一行调试显示0xaabbccdd0xeeddcc00。为什么会这样?我错过了什么?其他一些论点也发生了这种情况。我请你帮我这个。

PS:2 ^ 32 = 4294967296且0xffeeddcc = 4293844428(2 ^ 32> 0xffeeddcc)。我不知道是否还有任何联系。

2 个答案:

答案 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]

开始打印两个(32位)整数
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