Search code examples
c++cpointersdereferencevariable-address

Dereferencing a char pointer in C/C++?


I am working in a program using the DWARF and ELF info. I am hooked to another program using a tool called Pin. I have the addresses from the global variables declared in "Y" program and I hook it into my Pin module which I will call "X".

I am getting a bunch of addresses for these global variables. Unfortunately I am having troubles when I try to dereference them. For example (right now I am doing things manually to see if it is doing what is supposed to be doing):

char * limit, * address1;

for(address1 = (char *) 0x804A040, limit = address1 + bytesize; address1 < limit; address1++)
      cout <<  *(address1) << "\n";

I should be getting the variable that is stored in that address which is a char * to a word. Do I have to dereference two pointers in this case? The address and then the char * stored in that address?

This works perfectly fine when I want to dereference an int variable, but whenever I try to dereference a char pointer or variable I get non-ASCII values...


Solution

  • Think like this: if you want to dereference an int, you use int *:

    int *addr = (int *)0x12345678;
    printf("%d\n", *addr);
    

    But a string is already a pointer, so if you do this:

    char *addr = (char *)0x12345678;
    

    You don't need to dereference it to print it out, so you get it this way:

    printf("%s\n", addr);
    

    Additionally, suppose you have this memory:

    00000001:  0x12345678
    ...
    12345678:  'A'
    12345679:  'B'
    1234567A:  '\0'
    ...
    

    Let's access the address 0x00000001 and see what we can do:

    unsigned int *addr = (unsigned int *)0x00000001;
    

    Now *addr holds an integer which is the address of the first character of our string. Functions that take a string argument, usually ask for the string address, that is, a pointer to it, so *addr is also the string we should print on cout or printf for example.

    // This should print "AB"
    printf("%s\n", (char *)(*addr));
    

    Now if you dereference our value (0x12345678), we'd get the string's first character, and only it, as a char. So if you misuse it and dereference it to a char *, printf would try to search for the memory 'A', which is 0x00000041, and would probably get a segmentation fault.

    So, the right way to dereference its value, to get the first character would be this:

    // This should print "A"
    printf("%c\n", (char)(**addr));
    

    So, as a conclusion, if you are still getting non-ASCII values, that's probably an issue with this kind of hierarchy between addresses, and I would recommend you to strictly debug the memory and see if creating a pointer to a pointer is the right path to your string.