C程序的命令行输入(使用Perl的'print'命令)
Command line input to a C program (using 'print' command of Perl)
我很难理解 print
Perl 命令解释十六进制值的方式。我正在使用一个只有 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
)。不知道还有没有联系。
您将字符串打印为数字让自己感到困惑。在小端架构中,在四字节值(例如 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]
(这将显示 8 bytes in hexadecimal)
命令行参数是以 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
我很难理解 print
Perl 命令解释十六进制值的方式。我正在使用一个只有 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
)。不知道还有没有联系。
您将字符串打印为数字让自己感到困惑。在小端架构中,在四字节值(例如 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]
(这将显示 8 bytes in hexadecimal)
命令行参数是以 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