I want to read to and write from process' memory through /dev/mem
.
我想通过/dev/ memfrom进程的内存读取和写入。
First, I get process' memory map through a linux kernel module coded by myself, output is like this:
首先,我通过自己编写的linux内核模块获取进程的内存映射,输出如下:
start_code_segment 4000000000000000
end_code_segment 4000000000019c38
start_data_segment 6000000000009c38
end_data_segment 600000000000b21d
start_brk 6000000000010000
brk 6000000000034000
start_stack 60000fffffde7b00
Second, I can convert virtual address(VA) to PA thorough the linux kernel module, for example, I can convert VA:0x4000000000000008
to PA:0x100100c49f8008
其次,我可以将虚拟地址(VA)转换为PA彻底的linux内核模块,例如,我可以将VA: 0x400000000000000000000008转换为PA: 0x100100100c49f8008
Third, function read_phy_mem
can get memory data in PA:0x100100c49f8008
,code at the final.
第三,PA函数read_phy_mem可以内存数据:0 x100100c49f8008,代码在最后。
Problem: My problem is when I read text segment
PA memory, everything is OK, but if I read data segment
PA memory, *((long *)mapAddr)
in line 243 will cause system to go down. Also, I tried
问题:我的问题是当我读取文本段PA内存时,一切正常,但是如果我读取数据段PA内存,第243行中的*(长*)mapAddr)将导致系统崩溃。我也试过
memcpy( &data, (void *)mapAddr, sizeof(long) )
but it still make the system go down.
但它仍然使系统下降。
other info: my computer is IA64, OS is Linux 2.6.18, when system is down, I can get output Info from console like this, then system will restart.
其他信息:我的电脑是IA64, OS是Linux 2.6.18,当系统宕机时,我可以从这样的控制台获得输出信息,然后系统重启。
Entered OS MCA handler. PSP=20010000fff21320 cpu=0 monarch=1
cpu 0, MCA occurred in user space, original stack not modified
All OS MCA slaves have reached rendezvous
MCA: global MCA
mlogbuf_finish: printing switched to urgent mode, MCA/INIT might be dodgy or fail.
Delaying for 5 seconds...
code of function read_phy_mem
代码的函数read_phy_mem
/*
* pa: physical address
* data: memory data in pa
*
* return int: success or failed
*/
188 int read_phy_mem(unsigned long pa,long *data)
189 {
190 int memfd;
191 int pageSize;
192 int shift;
193 int do_mlock;
194 void volatile *mapStart;
195 void volatile *mapAddr;
196 unsigned long pa_base;
197 unsigned long pa_offset;
198
199 memfd = open("/dev/mem", O_RDWR | O_SYNC);
200 if(memfd == -1)
201 {
202 perror("Failed to open /dev/mem");
203 return FAIL;
204 }
205
206 shift = 0;
207 pageSize = PAGE_SIZE; //#define PAGE_SIZE 16384
208 while(pageSize > 0)
209 {
210 pageSize = pageSize >> 1;
211 shift ++;
212 }
213 shift --;
214 pa_base = (pa >> shift) << shift;
215 pa_offset = pa - pa_base;
224 mapStart = (void volatile *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_LOCKED, memfd, pa_base);
226 if(mapStart == MAP_FAILED)
227 {
228 perror("Failed to mmap /dev/mem");
229 close(memfd);
230 return FAIL;
231 }
232 if(mlock((void *)mapStart, PAGE_SIZE) == -1)
233 {
234 perror("Failed to mlock mmaped space");
235 do_mlock = 0;
236 }
237 do_mlock = 1;
238
239 mapAddr = (void volatile *)((unsigned long)mapStart + pa_offset);
243 printf("mapAddr %p %d\n", mapAddr, *((long *)mapAddr));
256 if(munmap((void *)mapStart, PAGE_SIZE) != 0)
257 {
258 perror("Failed to munmap /dev/mem");
259 }
260 close(memfd);
269 return OK;
270 }
Can anyone understand why text segment works well but data segment does not?
有人能理解为什么文本段很好,而数据段却不行吗?
1 个解决方案
#1
1
I guess, its happening because code-section remain in memory while process executes(if not a DLL code), Whereas data section leave in & out continuously.
Try with stack-Segment. And check if its working?
Write your own test program and allocate memory dynamically in KBs and keep that memory in use within a loop. Than try it with your code to read memory segments of test program. I think it will work.
I have done similar work in windows to replace BIOS address from IVT.
Should be root user.
我猜,这是因为在进程执行时(如果不是DLL代码的话),代码段仍然保留在内存中,而数据段则不断地进出。尝试与堆栈段。检查一下它是否有效?编写自己的测试程序,在KBs中动态分配内存,并在循环中使用这些内存。不要使用代码来读取测试程序的内存段。我想这行得通。我在windows中做过类似的工作,以替换来自IVT的BIOS地址。应该是根用户。
#1
1
I guess, its happening because code-section remain in memory while process executes(if not a DLL code), Whereas data section leave in & out continuously.
Try with stack-Segment. And check if its working?
Write your own test program and allocate memory dynamically in KBs and keep that memory in use within a loop. Than try it with your code to read memory segments of test program. I think it will work.
I have done similar work in windows to replace BIOS address from IVT.
Should be root user.
我猜,这是因为在进程执行时(如果不是DLL代码的话),代码段仍然保留在内存中,而数据段则不断地进出。尝试与堆栈段。检查一下它是否有效?编写自己的测试程序,在KBs中动态分配内存,并在循环中使用这些内存。不要使用代码来读取测试程序的内存段。我想这行得通。我在windows中做过类似的工作,以替换来自IVT的BIOS地址。应该是根用户。