I need to scan the entire memory of the calling process of my program and separate check which blocks are read-only, read-write, or inaccessible. It sounds pretty straight forward but I'm having trouble getting started. I'm wondering if anyone can point me in the right direction by providing relevant functions for scanning the memory of a calling process
For example, to start off, how would I obtain the starting and ending memory addresses of the calling process?
This might be kernel dependent, but on Linux the /proc file system can access it:
/proc/[pid]/mem is the contents of the memory by a process, so you just have to identify your parent's pid, and if you have access you can scan it.
The actual layout of the file will depend somewhat on the executable type and kernel in question.
http://linux.die.net/man/5/proc
Related
I need to scan another process' memory in Windows. The ReadProcessMemory function does it just fine but it copies each time memory from the target process to one of my buffers.. is there any way to access another process' memory without copying it to my process' memory every time? If there were I could use pointers to access the other process' memory
Debuggers use ReadProcessMemory, so if you're implementing something that functions like a debugger, that's the right way to do it.
If you're implementing something else, you're probably heading into the weeds and you should give us a higher-level view of the problem you're trying to solve.
I'm trying to write a program that reads the memory of other processes. This seems quite straightforward however I came across one problem. If the process I'm trying to read from has memory mapped but it has not use that memory so far (e.g. process called malloc, but never read from or wrote to that memory) the physical pages are not yet allocated. I presume this is the lazy allocation.
Now, when my program tries to read that memory it's immediately allocated. I would like to avoid that as I noticed some programs seems to allocate (or map) very large amounts that they don't normally use. This either causes very large memory consumption after the read or, in extreme cases, the process even being killed by OOM as the mapped region was bigger than the available ram. This is of course not acceptable as my reader should ideally be transparent and not affect the process being examined.
So far I just found information about /proc/pid/pagemap but I'm not fully sure if it suits my needs. There is a 'present' bit but I did not found information what it exactly means and if this is what I'm looking for.
Can someone confirm that? Or there's another way of achieving the same goal.
For educational purposes, I've managed to create a custom syscall that just prints a message in the kernel's log.
What I was thinking about now is to create a "cross-process memcpy" syscall that receives another process' PID, a memory address of that process' memory space, a lenght, and a pointer in the current's process memory space, and that copies memory from the other process to the current one.
My idea would be to write a program that asks the user for a string, and then prints its PID, the address of the variable in which the string is stored, and it's length. Then I'd write another process that asks for that PID, address and length, and uses my custom syscall to copy that info from the other process to this one.
In theory, I understand that the kernel should be able to access everything, including the other process memory. But in practice I've found that there are copy_from_user or copy_to_user functions to copy memory between userspace and kernelspace, but they don't receive a PID or any other process identifier. So it seems the syscall has somehow context information regarding the caller process - and I don't know if there's any limitation or API that prevents/allows to access another process' memory space from a syscall.
Does the Linux kernel have any API to access another process' memory, given it's PID and memory address?
Does the Linux kernel have any API to access another process' memory, given it's PID and memory address?
Yes, get_user_pages.
Note that the other process is not mapped into the address space of the caller. get_user_pages obtains the underlying pages.
We can use get_user_pages to get a reference on a range of pages which covers the requested area to be read or written. Then carefully copy the data into and out of those pages such that we only touch the requested area.
The /proc/<pid>/mem mechanism might be based on get_user_pages; in any case, it's worth taking a look to see how it works.
Also look at the ptrace system call and its PTRACE_PEEKDATA and PTRACE_POKEDATA operations. You may be able to solve your problem using ptrace or else crib something from its implementation.
Introducing a system call to access memory is probably a bad idea. You have to make sure it's securely coded and that it checks the credentials of the caller, otherwise you can open up a huge security hole.
I have to scan the memory space of a calling process in C. This is for homework. My problem is that I don't fully understand virtual memory addressing.
I'm scanning the memory space by attempting to read and write to a memory address. I can not use proc files or any other method.
So my problem is setting the pointers.
From what I understand the "User Mode Space" begins at address 0x0, however, if I set my starting point to 0x0 for my function, then am I not scanning the address space for my current process? How would you recommend adjusting the pointer -- if at all -- to address the parent process address space?
edit: Ok sorry for the confusion and I appreciate the help. We can not use proc file system, because the assignment is intended for us to learn about signals.
So, basically I'm going to be trying to read and then write to an address in each page of memory to test if it is R, RW or not accessible. To see if I was successful I will be listening for certain signals -- I'm not sure how to go about that part yet. I will be creating a linked list of structure to represent the accessibility of the memory. The program will be compiled as a 32 bit program.
With respect to parent process and child process: the exact text states
When called, the function will scan the entire memory area of the calling process...
Perhaps I am mistaken about the child and parent interaction, due to the fact we've been covering this (fork function etc.) in class, so I assumed that my function would be scanning a parent process. I'm going to be asking for clarification from the prof.
So, judging from this picture I'm just going to start from 0x0.
From a userland process's perspective, its address space starts at address 0x0, but not every address in that space is valid or accessible for the process. In particular, address 0x0 itself is never a valid address. If a process attempts to access memory (in its address space) that is not actually assigned to that process then a segmentation results.
You could actually use the segmentation fault behavior to help you map out what parts of the address space are in fact assigned to the process. Install a signal handler for SIGSEGV, and skip through the whole space, attempting to read something from somewhere in each page. Each time you trap a SIGSEGV you know that page is not mapped for your process. Go back afterward and scan each accessible page.
Do only read, however. Do not attempt to write to random memory, because much of the memory accessible to your programs is the binary code of the program itself and of the shared libraries it uses. Not only do you not want to crash the program, but also much of that memory is probably marked read-only for the process.
EDIT: Generally speaking, a process can only access its own (virtual) address space. As #cmaster observed, however, there is a syscall (ptrace()) that allows some processes access to some other processes' memory in the context of the observed process's address space. This is how general-purpose debuggers usually work.
You could read (from your program) the /proc/self/maps file. Try first the following two commands in a terminal
cat /proc/self/maps
cat /proc/$$/maps
(at least to understand what are the address space)
Then read proc(5), mmap(2) and of course wikipages about processes, address space, virtual memory, MMU, shared memory, VDSO.
If you want to share memory between two processes, read first shm_overview(7)
If you can't use /proc/ (which is a pity) consider mincore(2)
You could also non-portably try reading from (and perhaps rewriting the same value using volatile int* into) some address and catching SIGSEGV signal (with a sigsetjmp(3) in the signal handler), and do that in a -dichotomical- loop (in multiple of 4Kbytes) - from some sane start and end addresses (certainly not from 0, but probably from (void*)0x10000 and up to (void*)0xffffffffff600000)
See signal(7).
You could also use the Linux (Gnu libc) specific dladdr(3). Look also into ptrace(2) (which should be often used from some other process).
Also, you could study elf(5) and read your own executable ELF file. Canonically it is /proc/self/exe (a symlink) but you should be able to get its from the argv[0] of your main (perhaps with the convention that your program should be started with its full path name).
Be aware of ASLR and disable it if your teacher permits that.
PS. I cannot figure out what your teacher is expecting from you.
It is a bit more difficult than it seems at the first sight. In Linux every process has its own memory space. Using any arbitrary memory address points to the memory space of this process only. However there are mechanisms which allow one process to access memory regions of another process. There are certain Linux functions which allow this shared memory feature. For example take a look at
this link which gives some examples of using shared memory under Linux using shmget, shmctl and other system calls. Also you can search for mmap system call, which is used to map a file into a process' memory, but can also be used for the purpose of accessing memory of another process.
I am trying to achieve CPU and Memory usage information of current process, inside a system call.
I can get current process name, pid and uid by using :
current->comm //process name
current->pid //process id
current_uid() //uid
but that seems to be all.(I am using kernel 3.2.0-24-generic)
As I have seen from Memory usage of current process in C, reading(vfs_read) and parsing /proc/pid/status seems to be the only option to get memory and cpu usage.
Is there a better way to obtain this information, or am I on the right track?
I also test my code as a kernel module first, since both system calls and kernel modules are running in kernel space. Is that also bad approach?
current->mm is the place where all memory information is stored.
current->mm->mmap is a list of memory mappings for the process, so you can iterate it and see what you find there.
current->utime and current->stime may be useful for getting CPU information.