简体   繁体   English

如何读取C程序的堆栈段?

[英]How to read the stack segment of a C program?

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.我正在开发一个 Hobby 操作系统,为此我想知道 Linux 中的内存分配机制,为了理解这一点,我创建了一个简单的 C 程序,它定义了一些十六进制数的unsigned char ,然后在一个空的无限循环中运行,我这样做是为了让这个过程保持活力。 Then I used pmap to get page-mapping information.然后我使用pmap来获取页面映射信息。 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?现在我知道堆栈段的位置,我还创建了一个程序,它使用process_vm_readv系统调用来读取该地址的内容,当我读取堆栈段的内容和一些随机数时,我看到的都是00流,最后如何我能弄清楚数组是如何存储在堆栈段中的吗?

If that is possible, how can I analyze the hex stream to extract meaningful information ?如果可能,我如何分析十六进制流以提取有意义的信息?

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 将在另一个名为 remote.c 的程序中读取和写入变量(这些程序假定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,如果你在 Linux 机器上运行它,

[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.使用类似的方法可以将堆栈帧读取到 io-vectors,但是您需要知道堆栈帧结构格式才能从堆栈帧解析局部变量的值。 stack frame contains function parameters, return address, local variables, etc栈帧包含函数参数、返回地址、局部变量等

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM