Thread: accessing memory used by another program

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    accessing memory used by another program

    I was hoping that this

    Code:
    printf("%s\n", &argv[1]);
    would make a simple one line program that would print the string pointed to by a pointer from another program if argv[1] was the address of the pointer (eg, bfde768f), but it seems not to work.

    Now I notice that if I ask gdb (running without an input program) "x/s 0xbfde768f", it can't access this memory (it's "out of bounds"). I had thought memory was "protected" by simple assigned (ie. the same address won't be handed out twice) and not by actual restriction, as appears to be the case.

    Is there a way around this?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Each program will have it's own memory space, and gdb will access the stack (and other accesses to the debuggee application) via some debug interface that the OS supports.

    You can use this interface yourself. In Linux that would be the ptrace system call:
    http://linux.die.net/man/2/ptrace

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    thanks matsp...this implies unless the other program is a forked child, it's memory space is permanently out-of-bounds.

    Which means there is not much purpose in trying to do the following, but given that char address[9] is a string containing a memory address, how can I actually get the content of that address if it's "in bounds" (as it turns out, &address doesn't do that)?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The next sentence
    Alternatively, the parent may commence trace of an existing process using PTRACE_ATTACH.
    You can check if the address is valid in the child process:
    On success, PTRACE_PEEK* requests return the requested data, while other requests return zero. On error, all requests return -1, and errno is set appropriately. Since the value returned by a successful PTRACE_PEEK* request may be -1, the caller must check errno after such requests to determine whether or not an error occurred.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    ptrace seems to work but any ideas about how to pass that address (other than in a string, which seems to be a dead end)?

    For example: This is program1, which gives up its pid and a char pointer address, then waits around using getc...
    Code:
    #include <stdio.h>
    
    int main () {
            short int pid=getpid();
            char this[]="that";
            printf("%d\t%x\n", pid, this);
            getc(stdin);
    }
    This is program2, which accepts a pid and a "memory address":
    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/ptrace.h>
    
    int main (int argc, char *argv[]) {
            int pid=atoi(argv[1]), word;
            if ((ptrace(PTRACE_ATTACH,pid,NULL,NULL)) != 0) {perror("ptrace fail");return -1;}
            if ((word=ptrace(PTRACE_PEEKTEXT,pid,(void*)argv[2],NULL)) == -1) perror("peektext fail");
            else printf("%d\n", word);
            ptrace(PTRACE_DETACH,pid,NULL,NULL);
    }
    peektext always fails with an Input/output error
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What are you ACTUALLY trying to do? [not the "I want to undo a bolt", but "I want to replace my wheel, because I have a puncture"]

    Edit: You may find that PEEKTEXT fails because the address of this is in the stack, so the data segment rather than the text (code) segment?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by matsp View Post
    What are you ACTUALLY trying to do? [not the "I want to undo a bolt", but "I want to replace my wheel, because I have a puncture"]

    Edit: You may find that PEEKTEXT fails because the address of this is in the stack, so the data segment rather than the text (code) segment?

    --
    Mats
    Eventually I'd like to ride down the hill

    I think PEEKTEXT fails because passing it a string from a character array can't work. This is why I asked "given that char address[9] is a string containing a memory address, how can I actually get the content of that address". Here's what I mean:
    Code:
    #include <stdio.h>
    
    int main () {
            char this[]="that", that[9];
            sprintf(that, "%x", this);
            printf("%s\n", that);   //returns same as &that  
    }
    This just prints the address -- which is to say that is a string containing an address (as a string), but it's useless for obtaining the contents of an actual location in memory. So that's probably true of argv[2] in program2. Generally, one would use *ptr=this and never deal with addresses as string values. But I don't see a way to pass "the information" otherwise...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What, you want to convert a string to an unsigned long? Why not use strtoul? (You'll probably have to specify the base appropriately.)

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by tabstop View Post
    What, you want to convert a string to an unsigned long? Why not use strtoul? (You'll probably have to specify the base appropriately.)
    I guess this is where my ignorance of these matters is really exposed! I can't even ask the right question!

    If I convert take the address as an unsigned long int it still seems useless.

    Code:
    #include <stdio.h>
    
    int main () {
            unsigned long addr;
            char this[]="that", that[12];
            sprintf(that, "&#37;s\n", this);
            addr=atoi(that);
            printf("%s\n", &addr);
    }
    The goal here is to print "that" (literally) without using anything except a literal number or string as the address (no "%p"). Besides w/ the ptrace example, this would be the same as if you asked for user input in the form of a memory address, where the user might type:

    0xbfbc446d

    Now, how could you use that address (a string literal inputted by the user) the same way you would a *ptr? It seems it cannot be done...

    [I'm going to move this question to a new thread...]
    Last edited by MK27; 09-16-2008 at 12:06 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Not &addr, but *addr. (Edit: not tested, but I think it should work. If it doesn't work, make addr an actual pointer type.)
    Last edited by tabstop; 09-16-2008 at 12:21 PM.

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    It is hard to understand
    but - do you want something like

    Code:
    char sAddr[] = "0x00ac0098";
    unsigned int uAddr = strtoul(sAddr,NULL,0);
    int* pAddr = (int*) uAddr;
    
    int res = *pAddr;
    printf("&#37;d", res);
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by tabstop View Post
    Not &addr, but *addr. (Edit: not tested, but I think it should work. If it doesn't work, make addr an actual pointer type.)
    Wrong on both counts.

    Quote Originally Posted by vart View Post
    It is hard to understand
    but - do you want something like

    Code:
    char sAddr[] = "0x00ac0098";
    unsigned int uAddr = strtoul(sAddr,NULL,0);
    int* pAddr = (int*) uAddr;
    
    int res = *pAddr;
    printf("%d", res);
    And this causes a segfault.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  13. #13
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by MK27 View Post
    Wrong on both counts.



    And this causes a segfault.
    AS it should. What to you expect to get dereferencing some random address?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  14. #14
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    You can only expect a fixed address like this if you have some way of making your executable operate within a fixed address. Which is highly unlikely that you have this capability at your disposal. Thus you need to go about acquiring the address location you are wanting to manipulate via other means.

  15. #15
    Registered User
    Join Date
    Sep 2008
    Posts
    21
    Have you ever though of using the shared memory functions that are part of IPC from Unix SVR4?

    Take a look at this:

    http://www.cs.cf.ac.uk/Dave/C/node27.html

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Client-server system with input from separate program
    By robot-ic in forum Networking/Device Communication
    Replies: 3
    Last Post: 01-16-2009, 03:30 PM
  2. Assignment Operator, Memory and Scope
    By SevenThunders in forum C++ Programming
    Replies: 47
    Last Post: 03-31-2008, 06:22 AM
  3. Program that displays amount of free memory
    By trancedeejay in forum Linux Programming
    Replies: 3
    Last Post: 01-13-2006, 01:27 PM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. my C++ program hangs during memory deallocation.
    By the-tzar in forum C++ Programming
    Replies: 6
    Last Post: 03-06-2004, 10:39 AM