将ShellCode写入到0地址,通过函数指针指向NULL,来实现调用
主要是为了理解共享内存。
扣硬编码
代码:
char Shell[] ={
0x6A,0,
0x6A,0,
0x6A,0,
0x6A,0,
0xb8,0,0,0,0,
0xff,0xd0,
0xc3
};
int main()
{
PVOID mem = VirtualAlloc(0,0x100,MEM_COMMIT,PAGE_EXECUTE_READWRITE); //向0申请空间,第一个参数是0,使用0会导致随机地址。这里不需要管
printf("%x\n",mem); //打印一下,方便通过WinDbg查看PDE/PTE
char user32[] = {'u','s','e','r','3','2','.','d','l','l',0};
char MessageBoxAA[]={"MessageBoxA"};
HMODULE hModule = LoadLibraryA(user32);
ULONG Meg = (ULONG)GetProcAddress(hModule,MessageBoxAA); //获取MessageBox的地址
*(PULONG)&Shell[9] = Meg; //写入ShellCode
memcpy(mem,Shell,sizeof(Shell));
system("pause"); //暂停一下,方便验证
typedef void (*xxxxfunc)(); //定义函数指针
xxxxfunc func = NULL; //将指针指向0地址,(NULL ==0)
func(); //调用
return 0;
}
这里得到了VirtualAlloc函数申请的空间
拆分: 0x00 0x3b0 0x00
通过WinDbg挂0地址
1、找到CR3
2、获取PDE
3、获取PTE
拿到了PTE,将其挂到0地址
成功调用。
共享内存:A进程创建远程线程 实现B进程0地址挂物理页实现调用ShellCode。
实现步骤:
1、创建一个B进程,弹出一个框,来加载User32.dll的MessageBox函数。也可是使用LoadLibaray加载。我这里直接调用一个MessageBox。
2、在A进程中,使用VirtualAlloc申请一块内存,然后将ShellCode写入到该内存,然后拿到A进程的物理页,然后将该物理页挂到B进程的0地址。
3、ShellCode需要注意的是,创建远程线程(CreateRemoteThread)有一个回调函数,其返回值是一个退出码(4字节)。
ShllCode{
0x6A,0,
0x6A,0,
0x6A,0,
0x6A,0,
0xb8,0,0,0,0,
0xff,0xd0,
0xc2,4,0
}
B进程代码:
#include<Windows.h>
int main()
{
MessageBox(NULL,NULL,NULL,NULL);
system("pause");
return 0;
}
A进程代码:
分别看到了A、B进程的CR3
1)通过WinDbg获取A进程的PTE
A进程的PTE 是036a9067 ,然后查看B进程
可以看到将A进程的物理页挂到B进程的物理页。
实验成功。
标签:保护模式,ShellCode,PTE,0x6A,地址,进程,NULL,番外篇 From: https://www.cnblogs.com/zhongyongzixue/p/18093275