简体   繁体   中英

Command line input to a C program (using 'print' command of Perl)

I am having difficulty in understanding the way print command of Perl interprets the hexadecimal values. I am using a very simple program of just 8 lines to demonstrate my question. Following code with gdb will explain my question in detail:

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

In above shown lines I have used gdb to debug the program. As command line arguments, I have passed two (hexadecimal) arguments (excluding the name of the program itself): \\xdd\\xcc\\xbb\\xaa and \\xcc\\xdd\\xee\\xff . Owing to the little-endian architecture, those arguments should be interpreted as 0xaabbccdd and 0xffeeddcc but as you can see the last line of above shown debugging shows 0xaabbccdd and 0xeeddcc00 . Why is this so? What am I missing ?? This has happened with some other arguments too. I am requesting you to help me with this.

PS: 2^32 = 4294967296 and 0xffeeddcc = 4293844428 (2^32 > 0xffeeddcc ). I don't know if still there is any connection.

You are confusing yourself by printing strings as numbers. In a little-endian architecture, in a four-byte value such as 0xDDCCBBAA, the bytes are numbered left-to-right from the starting address.

So let's take a look at the output of your debugger command:

(gdb) x/2x argv[1]
0x7fffffffe376: 0xaabbccdd  0xeeddcc00

Looking at that byte by byte, it would be:

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

Which is not unexpected, no?

You might want to use something like this to display arguments in hex:

x/8bx argv[1]

(which will show 8 b ytes in he x adecimal)

Command-line arguments are NUL-terminated strings.

Arguments argv[1] is a pointer to the first character of a NUL-terminated string.

7FFFFFFFE376  DD CC BB AA 00

argv[2] is a pointer to the first character of a NUL-terminated string.

7FFFFFFFE37B  CC DD EE FF 00

If you pay attention, you'll notice they happen to be located immediately one after the other in memory.

7FFFFFFFE376  DD CC BB AA 00 CC DD EE FF 00

You asked to print two (32-bit) integers starting at argv[1]

7FFFFFFFE376  DD CC BB AA 00 CC DD EE FF 00
              ----------- -----------
               0xAABBCCDD 0xEEDDCC00

For x/2x to be correct, you would have needed to use

perl -e'print "\xdd\xcc\xbb\xaa\xcc\xdd\xee\xff"'
   -or-
perl -e'print pack "i*", 0xaabbccdd, 0xffeeddcc'

For the arguments you passed, you need to use

(gdb) x argv[1]
0x3e080048cbd:  0xaabbccdd
(gdb) x argv[2]
0x3e080048cc2:  0xffeeddcc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM