3

I am developing a Hobby operating system, for that I want to know the mechanism of memory allocation in Linux, to understand that, I created a simple C program that defines a unsigned char of some hex numbers and then runs in a empty infinite loop, I did this to keep the process alive. Then I used pmap to get page-mapping information. Now I know the location of stack segment, also I have created a program that uses process_vm_readv syscall to read the contents of that address, all I see a stream of 00 when I read the contents of stack segment and some random numbers at last, How can I be able to figure out how the array is stored in the stack segment?

If that is possible, how can I analyze the hex stream to extract meaningful information ?

10
  • Use a pointer? Try writing and reading from it and see if the contents of the stack change. Commented Sep 4, 2019 at 12:07
  • 1
    @Gerhardh A way to force it into the stack is to take its address. Commented Sep 4, 2019 at 12:12
  • 1
    I am assuming you have stack segment starting address. You should also need to know the stack frame structure in-order to read the auto variable (unsigned char) content. Commented Sep 4, 2019 at 12:14
  • 3
    @NarasimhaPrasannaHN You might want to declare your char array as volatile. If not, it may get optimized out because the compiler detects that you don't do anything with the data inside your array. Commented Sep 4, 2019 at 12:20
  • 1
    @NarasimhaPrasannaHN It is unclear what you are trying to achieve. The OS only 'allocates' the stack for your program. Decisions like where in the stack the individual variables are placed or how the stack itself is organized is upto the program itself. These decisions are made, in your case, by your compiler. The OS just allocates a chunk of memory for you and lets your program run. Commented Sep 4, 2019 at 12:32

1 Answer 1

3

Here I am adding a demonstration for accessing address space of a remote process, There are two programs local.c which will read and write a variable in another program named remote.c (These program assumes sizeof(int)==4 )

local.c

#define _GNU_SOURCE #include <sys/uio.h> #include <unistd.h> #include <stdio.h> #include <sys/syscall.h> int main() { char buf[4]; struct iovec local[1]; struct iovec remote[1]; int pid; void *addr; printf("Enter remote pid\n"); scanf("%d",&pid); printf("Enter remote address\n"); scanf("%p", &addr); local[0].iov_base = buf; local[0].iov_len = 4; remote[0].iov_base = addr; remote[0].iov_len = 4; if(syscall(SYS_process_vm_readv,pid,local,1,remote,1,0) == -1) { perror(""); return -1; } printf("read : %d\n",*(int*)buf); *(int*)buf = 4321; if(syscall(SYS_process_vm_writev,pid,local,1,remote,1,0) == -1) { perror(""); return -1; } return 0; } 

remote.c

#define _GNU_SOURCE #include <sys/uio.h> #include <unistd.h> #include <stdio.h> #include <sys/syscall.h> int main() { int a = 1234; printf("%d %p\n",getpid(),&a); while(a == 1234); printf ("'a' changed to %d\n",a); return 0; } 

And if you run this on a Linux machine,

[ajith@localhost Desktop]$ gcc remote.c -o remote -Wall [ajith@localhost Desktop]$ ./remote 4574 0x7fffc4f4eb6c 'a' changed to 4321 [ajith@localhost Desktop]$ [ajith@localhost Desktop]$ gcc local.c -o local -Wall [ajith@localhost Desktop]$ ./local Enter remote pid 4574 Enter remote address 0x7fffc4f4eb6c read : 1234 [ajith@localhost Desktop]$ 

Using the similar way you can read stack frame to the io-vectors, But you need to know the stack frame structure format to parse the values of local variables from stack frame. stack frame contains function parameters, return address, local variables, etc

Sign up to request clarification or add additional context in comments.

2 Comments

why use syscall instead of calling process_vm_readv directly?
some Linux distributions doesn't expose process_vm_readv() system call @ChrisDodd

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.