gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 12:08:39 25 4
gpt4 key购买 nike

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

如果可能的话,我如何分析十六进制流以提取有意义的信息?

最佳答案

这里我添加了一个访问远程进程地址空间的演示,有两个程序 local.c 将在另一个名为 remote.c 的程序中读取和写入一个变量(这些程序假设 sizeof(int) ==4 )

本地.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;
}

远程.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;
}

如果你在 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]$

使用类似的方法可以将堆栈帧读取到 io vector ,但是您需要知道堆栈帧结构格式才能从堆栈帧中解析局部变量的值。栈帧包含函数参数、返回地址、局部变量等

关于c - 如何读取C程序的堆栈段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57788012/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com