-
-
通过切换cr3 读取指定进程(普通程序)的内存
-
发表于:
2020-11-7 21:09
4977
-
环境:
- win7sp1
- vs 2008
- eq 80b99400 + (0x20 * 8) 0040EE00`0008100A (中断门)
- gdt 找一块地址写入shellcode
流程:
- 找到目标进程的CR3
- 通过mov cr3,eax; 切换CR3
- 切换回自身CR3,程序正常运行
注意:
- 当成功切换cr3 的时候, 此时堆栈和寄存器都已经是目标进程的了, 想通过全局变量取值什么的不可能了, 只能把要操作的值存到高地址当中.
- 返回的时候直接修复cr3 然后堆栈被系统切换回来 直接返回 (cr3 需要在切换前保存在高地址当中)
- 里面坑确实很多还是自己做一遍感受下更好
代码:
#include#includeint tempFunc;
int targerAddr;
int TargetCr3;
int virtualAddress;
int myCr3;
int a;
void __declspec(naked) INT20()
{
_asm{
pushad;
pushfd;
push fs;
mov ax,0x30;
mov fs,ax;
}
for(int i = 0; i < 200;i++){
*(char*)targerAddr = *(char*)tempFunc;
(char)targerAddr++;
(char)tempFunc++;
}
__asm{
mov eax,cr3;
mov ebx,0x80b99c20+212; //保存自己的Cr3 ,一会切换到别的进程之后访问的地址都是人家程序的 嘿嘿
mov [ebx],eax;
mov eax,virtualAddress; //存要读取的线性地址
mov ebx,0x80b99c20+216;
mov [ebx],eax;
//ReadMemory
mov eax,0x80b99c20;
call eax;
mov ebx,0x80b99c20+216;//取读出目标进程的值
mov eax,[ebx];
mov a,eax;
}
_asm{
pop fs;
popfd;
popad;
iretd
}
}
void __declspec(naked)ReadMemory()
{
__asm{
mov eax,TargetCr3;
mov cr3,eax;
mov ebx,0x80b99c20+216;
mov eax,[ebx]; //0x12ff
mov eax,[eax];
mov [ebx],eax;
mov ebx,0x80b99c20+212; //自身cr3
mov eax,[ebx];
mov cr3,eax;
ret;
}
}
int main(void)
{
targerAddr = 0x80b99c20;
tempFunc = (int)ReadMemory;
TargetCr3 = 0x3e81f3e0; //目标进程的cr3
virtualAddress = 0x12ff28;//目标进程的线性地址
myCr3 = 0;
a = 0;
printf("%x\n",INT20);
system("pause");
__asm{
push fs;
int 0x20;
pop fs;
}
printf("%x\n",a);
system("pause");
return 0;
}
目标进程代码
#include#includeint main(void)
{
int a = 0x666;
printf("%x\n",&a);
system("pause");
return 0;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)