访问一个进程的所有地址空间

时间:2022-08-28 21:22:30
希望各位高手帮忙看一下,谢谢!
    1、如何用c语言编写一个程序,访问一个进程的所有地址空间,并报告每一个地址单元是否可读,是否可写,希望给出代码? 

11 个解决方案

#1


一般只要
/proc/pid/maps 就能查看进程内存范围及权限

编程难点在于无法区分到底是禁止读还是禁止写,都是产生SIGSEGV 信号报一个断错误

程序还是挺有意思的
lz等我调下

#2


进程的所有地址并非都可以访问,你只能访问用户空间的地址。
直接访问内核空间的地址会coredump。

#3


以下代码只判断了0x0-0xffffffff的读权限
因为有的地址虽然可写,但是也不能乱写值,这里就没有做
lz有意的话可以自己把写权限判断加上


#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include  <setjmp.h>  
volatile int flag;
static   jmp_buf   jmpbuffer;
char *p=0x0;
char tmp;
void handler(int signo)
{   
  siglongjmp(jmpbuffer,   1); 
}
int main()
{

     signal(SIGSEGV,handler);
while((unsigned int)p<0xffffffff)
{
 
if( sigsetjmp(jmpbuffer,1)!=0)   
{  
printf("0x%x can not read\n",(unsigned int)p);
goto jixu;
   }   
signal(SIGSEGV,handler);
tmp=*p;
printf("0x%x can read \n",(unsigned int)p);
jixu:
p++;
}

return 0;
}

#4


学习下.
:-)

#5


另,请教下,0x0-0xffffffff是4GB的地址空间,
要是支持物理地址扩展(hysical Address Extension ,PAE),那如何做?
例如 现在的GM45芯片组, CPU, OS都支持的话,最高到8 GB内存.

#6


猜测下,是否要用 long long 就OK了.

#7


后来又想,如果能读的话。就可能把读到的值写回去,没有影响
但是连读权限都没有的地址,就不敢测试写权限了,因为不知道该写什么进去测试好
以下是完整程序

#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include  <setjmp.h>  
volatile int flag; //标志位,1为当前判断的是读权限, 2为当前判断的是写权限
static   jmp_buf   jmpbuffer;
//从0x0 开始 查看maps得知其实要到很高的地址才能有读权限内存区,在我的pc上是0x08049000 ,lz可改大点方便观察
unsigned char *p=(char *)0x0;
unsigned char tmp;
void handler(int signo)
{   
  siglongjmp(jmpbuffer,   1); 
}
int main()
{

     signal(SIGSEGV,handler);
while((unsigned int)p<0xffffffff)
{
 
if( sigsetjmp(jmpbuffer,1)!=0)   
{  
if(flag==1)
{
printf("0x%-8x can not read\n",(unsigned int)p);
goto jixu;
//如果连读权限都没有,就不测试写权限了,以免随便写入造成破坏
}
if(flag==2)
{
printf("0x%-8x can not write\n",(unsigned int)p);
goto jixu;
}

   }   
signal(SIGSEGV,handler);

//测试读
flag=1;
tmp=*p;
printf("0x%-8x can read \n",(unsigned int)p);
//测试写
flag=2;
*p=tmp;
printf("0x%-8x can write \n",(unsigned int)p);
jixu:
p++;
}

return 0;
}

#8


因为不知道该写什么进去测试好 
------------------------------
*p= *p;这样可行么,编译器会不会优化掉?或者关闭优化选项试试.

#9


引用 8 楼 wenxy1 的回复:
因为不知道该写什么进去测试好
 ------------------------------
 *p= *p;这样可行么,编译器会不会优化掉?或者关闭优化选项试试.

这个操作本身要求*p可读

#10


引用楼主 ganyuanchao2006 的回复:
希望各位高手帮忙看一下,谢谢!
    1、如何用c语言编写一个程序,访问一个进程的所有地址空间,并报告每一个地址单元是否可读,是否可写,希望给出代码?


。。
自己一个个地址循环检测呗

#11


如果纯粹为了得到进程虚存的状况,可以遍历进程中vm_area_struct列表,
task_struct->mm(mm_struct)->mmap(vm_area_struct)。
结果就是/proc/pid/maps显示的信息。

#1


一般只要
/proc/pid/maps 就能查看进程内存范围及权限

编程难点在于无法区分到底是禁止读还是禁止写,都是产生SIGSEGV 信号报一个断错误

程序还是挺有意思的
lz等我调下

#2


进程的所有地址并非都可以访问,你只能访问用户空间的地址。
直接访问内核空间的地址会coredump。

#3


以下代码只判断了0x0-0xffffffff的读权限
因为有的地址虽然可写,但是也不能乱写值,这里就没有做
lz有意的话可以自己把写权限判断加上


#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include  <setjmp.h>  
volatile int flag;
static   jmp_buf   jmpbuffer;
char *p=0x0;
char tmp;
void handler(int signo)
{   
  siglongjmp(jmpbuffer,   1); 
}
int main()
{

     signal(SIGSEGV,handler);
while((unsigned int)p<0xffffffff)
{
 
if( sigsetjmp(jmpbuffer,1)!=0)   
{  
printf("0x%x can not read\n",(unsigned int)p);
goto jixu;
   }   
signal(SIGSEGV,handler);
tmp=*p;
printf("0x%x can read \n",(unsigned int)p);
jixu:
p++;
}

return 0;
}

#4


学习下.
:-)

#5


另,请教下,0x0-0xffffffff是4GB的地址空间,
要是支持物理地址扩展(hysical Address Extension ,PAE),那如何做?
例如 现在的GM45芯片组, CPU, OS都支持的话,最高到8 GB内存.

#6


猜测下,是否要用 long long 就OK了.

#7


后来又想,如果能读的话。就可能把读到的值写回去,没有影响
但是连读权限都没有的地址,就不敢测试写权限了,因为不知道该写什么进去测试好
以下是完整程序

#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include  <setjmp.h>  
volatile int flag; //标志位,1为当前判断的是读权限, 2为当前判断的是写权限
static   jmp_buf   jmpbuffer;
//从0x0 开始 查看maps得知其实要到很高的地址才能有读权限内存区,在我的pc上是0x08049000 ,lz可改大点方便观察
unsigned char *p=(char *)0x0;
unsigned char tmp;
void handler(int signo)
{   
  siglongjmp(jmpbuffer,   1); 
}
int main()
{

     signal(SIGSEGV,handler);
while((unsigned int)p<0xffffffff)
{
 
if( sigsetjmp(jmpbuffer,1)!=0)   
{  
if(flag==1)
{
printf("0x%-8x can not read\n",(unsigned int)p);
goto jixu;
//如果连读权限都没有,就不测试写权限了,以免随便写入造成破坏
}
if(flag==2)
{
printf("0x%-8x can not write\n",(unsigned int)p);
goto jixu;
}

   }   
signal(SIGSEGV,handler);

//测试读
flag=1;
tmp=*p;
printf("0x%-8x can read \n",(unsigned int)p);
//测试写
flag=2;
*p=tmp;
printf("0x%-8x can write \n",(unsigned int)p);
jixu:
p++;
}

return 0;
}

#8


因为不知道该写什么进去测试好 
------------------------------
*p= *p;这样可行么,编译器会不会优化掉?或者关闭优化选项试试.

#9


引用 8 楼 wenxy1 的回复:
因为不知道该写什么进去测试好
 ------------------------------
 *p= *p;这样可行么,编译器会不会优化掉?或者关闭优化选项试试.

这个操作本身要求*p可读

#10


引用楼主 ganyuanchao2006 的回复:
希望各位高手帮忙看一下,谢谢!
    1、如何用c语言编写一个程序,访问一个进程的所有地址空间,并报告每一个地址单元是否可读,是否可写,希望给出代码?


。。
自己一个个地址循环检测呗

#11


如果纯粹为了得到进程虚存的状况,可以遍历进程中vm_area_struct列表,
task_struct->mm(mm_struct)->mmap(vm_area_struct)。
结果就是/proc/pid/maps显示的信息。