2

I'm attempting to print the address of all arguments in argv as segmented chars.

The address of argv[0]

0x7ffdf0451078

I want to print this as

0x7ffd f0 45 10 78

Then truncate the beginning id, and print this into a formatted gird similar to

 +------+------+------+------+
 |  f0  |  45  |  10  |  78  | 
 +------+------+------+------+

I'm assuming the easiest way to accomplish this is to hold the address of argv[0] as a string, or char array, and then do some manipulation to that string / array.

However I have not been able to get the address into any type of container thus far.

MKUltra
  • 349
  • 2
  • 14
  • see [snprintf](http://www.cplusplus.com/reference/cstdio/snprintf/)/[sprintf](http://www.cplusplus.com/reference/cstdio/sprintf/). You can pass a pointer with `%p` (http://www.cplusplus.com/reference/cstdio/printf/). – BurnsBA Oct 06 '17 at 18:46

3 Answers3

3

You could do

char str[100];
sprintf(str, "%p", argv[0]);

Now str would have "0x7ffdf0451078" if argv[0] is 0x7ffdf0451078.

You need only the f0451078 part. ie, the str+6 part.

Now use sscanf() like

char d[4][3];
sscanf(str+6, "%2s%2s%2s%2s", d[0], d[1], d[2], d[3]);

and print them as you need.

If you used the %x format specifier instead of %p, use str+4.

Demo here.

J...S
  • 5,079
  • 1
  • 20
  • 35
  • Ahh yes, this looks to work correctly. for the `sscanf(str+4, "%2s%2s%2s%2s", d[0], d[1], d[2], d[3]);` it should be a +6, otherwise it grabs the incorrect section of the address. – MKUltra Oct 06 '17 at 19:14
1
void *ptr = argv[0];
printf("%02x %02x %02x %02x\n",
       (int)((ptr / 0x1000000) & 0xff),
       (int)((ptr / 0x10000) & 0xff),
       (int)((ptr / 0x100) & 0xff),
       (int)(ptr & 0xff));
pelya
  • 4,326
  • 2
  • 24
  • 23
  • I see what you're doing in this segment, however it is giving me an error for each segmentation `error: invalid operands of types ‘void*’ and ‘int’ to binary ‘operator/’ (int)((ptr / 0x100) & 0xff),` – MKUltra Oct 06 '17 at 19:02
1

If you want control over the representation of the pointer, you may wish to convert it to intptr_t so you have confidence in the behavior of printf style specifiers. (The output format of %p is implementation-defined.)

#include <stdio.h>
#include <inttypes.h>

int main(int argc, char *argv[])
{
    intptr_t address = (intptr_t) &argv[0];

    char repr[1 + 2*sizeof(intptr_t)]; // 2 chars per byte plus a '\0'
    snprintf(repr, sizeof repr, "%" PRIxPTR, address); // this is the magic

    printf("0x%.4s %.2s %.2s %.2s %.2s\n", repr, repr+4, repr+6, repr+8, repr+10);
    // output: 0x7ffd f0 45 10 78

    printf("+------+------+------+------+\n");
    printf("|  %.2s  |  %.2s  |  %.2s  |  %.2s  |\n", repr+4, repr+6, repr+8, repr+10);
    printf("+------+------+------+------+\n");
    // output:
    // +------+------+------+------+
    // |  f0  |  45  |  10  |  78  | 
    // +------+------+------+------+
}

I found this question for formatting an intptr_t, and I used the precision field of the %s format specifier to print sections of the string that snprintf created.

Although repr's size is defined in terms of sizeof(intptr_t), the printing code here assumes a 24 bit address.

trent
  • 25,033
  • 7
  • 51
  • 90