Linux read and write external memory.


 
Thread Tools Search this Thread
Top Forums Programming Linux read and write external memory.
# 1  
Old 03-15-2011
Linux read and write external memory.

Hi everyone. I asked once here and it went well, so I'm very happy with this community.

I have a new question to ask. I would like to read&write specify memory of a process which is not the process I'm doing it from, nor a child nor a parent.

So, I want to do a program similar to Cheat Engine. I already have done the speed hack module (thank you unix.com!), and now I'm going to start with memory modifying part.

First of all, I need to know how to read (and write) bytes from (and to) another process. In windows API those are (Read)&(Write)ProcessMemory I guess.

Second, I need to know which are the readable regions so I can do a full snapshot of all the readable memory of an application.

If you need to know the OS target:
Code:
uname -a
Linux littleEzek-desktop 2.6.35-27-generic #48-Ubuntu SMP Tue Feb 22 20:25:46 UTC 2011 x86_64 GNU/Linux

Thank you again for read.
# 2  
Old 03-15-2011
To mess with another process' memory in Linux you use ptrace as described here. This is the same way things like gdb do it. The obvious way to do so, /proc/pid/mem, won't work until you've connected with ptrace.

Getting the readable regions is a little more easy.
Code:
$ cat /proc/self/maps
00400000-0040b000 r-xp 00000000 08:05 264334                             /bin/cat
0060a000-0060b000 r--p 0000a000 08:05 264334                             /bin/cat
0060b000-0060c000 rw-p 0000b000 08:05 264334                             /bin/cat
01d91000-01db2000 rw-p 00000000 00:00 0                                  [heap]
7ffe71387000-7ffe714d7000 r-xp 00000000 08:05 264645                     /lib64/libc-2.11.2.so
7ffe714d7000-7ffe716d6000 ---p 00150000 08:05 264645                     /lib64/libc-2.11.2.so
7ffe716d6000-7ffe716da000 r--p 0014f000 08:05 264645                     /lib64/libc-2.11.2.so
7ffe716da000-7ffe716db000 rw-p 00153000 08:05 264645                     /lib64/libc-2.11.2.so
7ffe716db000-7ffe716e0000 rw-p 00000000 00:00 0 
7ffe716e0000-7ffe716fe000 r-xp 00000000 08:05 264632                     /lib64/ld-2.11.2.so
7ffe718d5000-7ffe718d8000 rw-p 00000000 00:00 0 
7ffe718fc000-7ffe718fd000 rw-p 00000000 00:00 0 
7ffe718fd000-7ffe718fe000 r--p 0001d000 08:05 264632                     /lib64/ld-2.11.2.so
7ffe718fe000-7ffe718ff000 rw-p 0001e000 08:05 264632                     /lib64/ld-2.11.2.so
7ffe718ff000-7ffe71900000 rw-p 00000000 00:00 0 
7fffba285000-7fffba2a7000 rw-p 00000000 00:00 0                          [stack]
7fffba3a3000-7fffba3a4000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
$

...where 'self' is 'self' to get cat's own memory, or any PID of your choosing.

---------- Post updated at 05:52 PM ---------- Previous update was at 05:50 PM ----------

I think the meaning of the columns is
Code:
beginning-end file_offset permissions ...

file_offset is only meaningful if it's actually a mapped file of course.
These 2 Users Gave Thanks to Corona688 For This Post:
# 3  
Old 03-21-2011
I'm getting in trouble trying to do this. Firstly, a c++ problem:

This is on memory.cpp (it got compiled):
Code:
template<class T>
bool peekValue(T * value, char * offset, pid_t pid)
{
    // Get /proc/$pid/mem
    char mem_file_name[255];
    sprintf(mem_file_name, "/proc/%d/mem", pid);
    // Opening /proc/$pid/mem
    FILE * mem_fd = fopen(mem_file_name, "r");
    // Tracing the app.
    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
        return false;
    // Force it to wait
    if (waitpid(pid, NULL, 0) == -1)
    {
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
        return false;
    }
    // Move pointer to offset.
    fseek(mem_fd, (long int)offset, SEEK_SET);
    // Read from memory.
    fread(value, 1, sizeof(T), mem_fd);
    // End petrace.
    ptrace(PTRACE_DETACH, pid, NULL, NULL);
    return true;
}

and in main.cpp:

Code:
many includes after:

int main(int argc, char ** argv)
{
    programinfo pnfo;
    int m;
    long int offset = 0;

    ...
    cout << "Enter the PID of the program you want to hack" << endl;
    cin >> pnfo.pid;
    cout << "Enter the pointer to int you want to read" << endl;
    cin >> offset;
    pnfo.mem_blocks = getMemoryMemblocks(pnfo.pid);
    peekValue<int>(&m, (char*)offset, pnfo.pid);
    cout << m << endl;
    return 0;
}

Got error (from linker):
Code:
/home/***/proyectos/xeat_engine/main.cpp|22|undefined reference to `bool peekValue<int>(int*, char*, int)'|

So I changed it to:
Code:
/*template<class T>*/
bool peekValue(int * value, char * offset, pid_t pid)
{
    // Get /proc/$pid/mem
    char mem_file_name[255];
    sprintf(mem_file_name, "/proc/%d/mem", pid);
    // Opening /proc/$pid/mem
    FILE * mem_fd = fopen(mem_file_name, "r");
    // Tracing the app. This fails:
    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
        return false;
    // Force it to wait
    if (waitpid(pid, NULL, 0) == -1)
    {
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
        return false;
    }
    // Move pointer to offset.
    fseek(mem_fd, (long int)offset, SEEK_SET);
    // Read from memory.
    fread(value, 1, sizeof(int), mem_fd);
    // End petrace.
    ptrace(PTRACE_DETACH, pid, NULL, NULL);
    return true;
}

And:

Code:
many includes after:

int main(int argc, char ** argv)
{
    programinfo pnfo;
    int m;
    long int offset = 0;

    ...
    cout << "Enter the PID of the program you want to hack" << endl;
    cin >> pnfo.pid;
    cout << "Enter the pointer to int you want to read" << endl;
    cin >> offset;
    pnfo.mem_blocks = getMemoryMemblocks(pnfo.pid);
    peekValue/*<int>*/(&m, (char*)offset, pnfo.pid);
    cout << m << endl;
    return 0;
}

It "works". Any idea about this?

The second question is that it "works". It means the function got executed but it doesn't do its job. It fails on ptrace attachment. I'm trying to ptrace pid 6000, which is the pid of neverball (a videogame of a ball), but it returns -1.

What are the conditions to do a ptrace? Any idea?

Thank you for read.

---------- Post updated at 04:55 PM ---------- Previous update was at 11:09 AM ----------

I've solved the above problem (super user privileges).

Now I'm wonder a thing. Is to write in /proc/pid/mem possible?

Last edited by lilezek; 03-21-2011 at 01:35 PM..
# 4  
Old 03-22-2011
Quote:
Originally Posted by lilezek
...It "works". Any idea about this?
I'm not sure, but I do know it's wasteful to have 9 different kinds of functions that differ only in one way, size -- this is one of the really wasteful things about the C++ model, people forget how to write truly generic functions.

You shouldn't be using fopen() on raw devices either, you don't want them buffered by accident, use the basic system calls instead. Doesn't matter so much on read but could matter a lot on write. How about this?
Code:
/*template<class T>*/
bool peekValue(void *value, void *offset, size_t size, pid_t pid)
{
    // Get /proc/$pid/mem
    char mem_file_name[255];
    sprintf(mem_file_name, "/proc/%d/mem", pid);
    // Opening /proc/$pid/mem
    int fd=open(mem_file_name, O_RDWR);
    // Tracing the app. This fails:
    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
        return false;
    // Force it to wait
    if (waitpid(pid, NULL, 0) == -1)
    {
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
        return false;
    }
    // Move pointer to offset.
    lseek(fd, (off_t)offset, SEEK_SET);
    // Read from memory.
    read(value, size, fd);
    // End petrace.
    ptrace(PTRACE_DETACH, pid, NULL, NULL);
    return true;
}

Ideally, you'd want to just attach to the process once and use the same fd over and over, too, though it'd naturally be more complicated starting and stopping the child etc etc etc.
Quote:
I've solved the above problem (super user privileges).
I think the process either has to be a child of yours, or you have to be root. You might have more luck as a limited user if your own program launched the application with fork/exec.
Quote:
Now I'm wonder a thing. Is to write in /proc/pid/mem possible?
Yes. Only to segments which allow writing of course. Beyond that there shouldn't be anything special about it. Of course the program may have optimized certain variables out for all you know and respond either badly or not at all to writes in certain places; hard to tell when you don't control the source!

Last edited by Corona688; 03-22-2011 at 01:06 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

BASH script to read external file to perform text replacements?

Hi all, I have a moderate size (300 lines) BASH Shell script that performs various tasks on different source reports (CSV files). One of the tasks that it performs, is to use SED to replace 'non-conforming' titles with conformant ones. For example "How to format a RAW Report" needs to become... (3 Replies)
Discussion started by: richardsantink
3 Replies

2. Shell Programming and Scripting

Redirect output to memory instead of an external file

I use the following as an example. I find myself always doing this and I believe my scripts would run much faster if I put the sed results into a place in memory rather than writing to files. Again, its not about sed, its about redirecting to a place in memory rather than an external file. ... (5 Replies)
Discussion started by: popeye
5 Replies

3. Shell Programming and Scripting

How to Read different values from external file?

Hi , I am new to this scripting , I am facing an issue like how to read different values from external file by using different variables, In script I supposed to declare var 1 var 2 var 3 I know how to call this variables from external file (I am using awk command by giving same... (3 Replies)
Discussion started by: chandini
3 Replies

4. IP Networking

read/write,write/write lock with smbclient fails

Hi, We have smb client running on two of the linux boxes and smb server on another linux system. During a backup operation which uses smb, read of a file was allowed while write to the same file was going on.Also simultaneous writes to the same file were allowed.Following are the settings in the... (1 Reply)
Discussion started by: swatidas11
1 Replies

5. UNIX for Dummies Questions & Answers

Write/Read in Shared memory

I have created and attached a shared memory segment. However I do not know how am I supposed to write and read data from it. I want to save various different data on this segment such as process IDs and other. Do you know how am I supposed to write these and be able to read such data in the correct... (1 Reply)
Discussion started by: tyron
1 Replies

6. Programming

Urgent!!!! - Write/read to/from shared memory

I created a shared memory and attached it. I also created the appropriate semaphores to sync. my read/write operations. However I do not know how am I supposed to do so. Anyone has got any ideas? I want to write int the form of 1234:23:444:... where each number between : means something to the... (0 Replies)
Discussion started by: tyron
0 Replies

7. Shell Programming and Scripting

Find all files with group read OR group write OR user write permission

I need to find all the files that have group Read or Write permission or files that have user write permission. This is what I have so far: find . -exec ls -l {} \; | awk '/-...rw..w./ {print $1 " " $3 " " $4 " " $9}' It shows me all files where group read = true, group write = true... (5 Replies)
Discussion started by: shunter63
5 Replies

8. HP-UX

Can I copy a Unix file to a external memory stick?

I'm doing server maintainence to a HP UX server and I have 2 files that someone need for an unknown reason. I was wondering If I can put this files on a memory stick, or is there someother way I have to copy it for them? (3 Replies)
Discussion started by: MarcKim
3 Replies

9. UNIX for Advanced & Expert Users

How to Mount a Remote NTFS Share for Read/Write under Linux

I've done this in the past, but I didn't save the syntax. I'm still kicking myself about that... I am trying to mount \\server_name\share_name for read/write under CentOS 5.2 (a "generic" version of RedHat). As I recall, there was a fairly simple (maybe a oneline) command that would allow NTFS... (2 Replies)
Discussion started by: shew01
2 Replies

10. Programming

shared memory read/write using threads

I am looking for C program source code. Could you please help me in finding the source code required mentioned below. program to create multiple threads (one master thread and rest worker threads) and using the threads write into and read from shared memory Restrictions: Only one thread... (2 Replies)
Discussion started by: kumars
2 Replies
Login or Register to Ask a Question