Windows内核实验:跨进程内存读写
一个进程访问的虚拟内存都是靠页的各种表来管理的嘛,他的根源就是cr3寄存器,所以理论上我们把某个进程的cr3换过来就可以实现读写这个进程
打开一个notepad

用ce找到他的字符串内存地址为0xaab30
| kd> !process 0 0 notepad.exeFailed to get VadRoot
 PROCESS 8165f350  SessionId: 0  Cid: 0688    Peb: 7ffd8000  ParentCid: 04a4
 DirBase: 08bd0240  ObjectTable: e14bcae8  HandleCount:  46.
 Image: notepad.exe
 
 | 
我们很自然的就会写出这样的代码
| #include <stdio.h>#include <stdlib.h>
 #include <windows.h>
 void __declspec(naked) IdtEntry() {
 __asm {
 mov eax,cr3
 mov ds:[0x8003f130],eax
 mov eax,0x8bd0240
 mov cr3,eax
 mov eax,0x12345678
 mov ds:[0xaab30],eax
 mov eax,ds:[0x8003f130]
 mov cr3,eax
 iretd
 }
 }
 void interrupt() {
 __asm {
 int 0x20
 }
 }
 int main() {
 if (0x401040 != IdtEntry) {
 printf("IdtRntry address wrong");
 system("pause");
 exit(-1);
 }
 
 interrupt();
 system("pause");
 }
 
 | 
但是其实mov cr3,eax 后面的指令压根不会执行,切换cr3后,我eip去取指令,但是现在已经是notepad的cr3了,自然不会取到我们程序的eip处指令,而是notepad的eip处指令,所以这段指令应该放到内核中每个进程都相同的地方,依旧选取gdt表里的空闲位置0x8003f140
| #include <stdio.h>#include <stdlib.h>
 #include <windows.h>
 char* Address = (char *)0x8003f140;
 size_t i;
 void EditNotepad();
 void __declspec(naked) IdtEntry() {
 for ( i = 0; i < 0x40; i++) {
 Address[i] = ((char*)EditNotepad)[i];
 }
 __asm {
 push 0x8003f140
 ret
 }
 }
 void __declspec(naked) EditNotepad() {
 __asm {
 mov eax, cr3
 mov ds : [0x8003f130] , eax
 mov eax, 0x8bd0240
 mov cr3, eax
 mov eax, 0x12345678
 mov ds : [0xaab30] , eax
 mov eax, ds : [0x8003f130]
 mov cr3, eax
 iretd
 }
 }
 void interrupt() {
 __asm {
 int 0x20
 }
 }
 int main() {
 if (0x401040 != IdtEntry) {
 printf("IdtRntry address wrong");
 system("pause");
 exit(-1);
 }
 
 interrupt();
 system("pause");
 }
 
 | 

还可以用我们之前的做系统调用的方法去实现一个系统调用或中断来做