|
发表于 2020-7-16 11:25:17
|
查看: 6667 |
回复: 2
1. 给定一个线性地址,和长度,读取内容;
int ReadMemory(OUT BYTE* buffer,IN DWORD dwAddr,IN DWORD dwLeght)
要求:
1) 可以自己指定分页方式。
2) 页不存在,要提示,不能报错。
3) 可以正确读取数据。
#include <windows.h>
#include <stdio.h>
//eq 8003f090 0040EC05`000810
DWORD PTE;
DWORD PDE;
DWORD DwAddr;
DWORD DwLeght;
BYTE* Buff;
BOOL _MAXPage = 0;
BOOL _TockPage = 0;
BOOL _P_Flafge = 0;
BOOL _PAT_Flage = 0;
VOID _declspec(naked) Start()
{
//获取参数
__asm
{
lea eax, dword ptr ds : [esp+0x8]
mov esi, dword ptr ds : [eax+0*4]
mov dword ptr ds : [Buff],esi
mov esi, dword ptr ds : [eax+1*4]
mov dword ptr ds : [DwLeght],esi
mov esi, dword ptr ds : [eax+2*4]
mov dword ptr ds : [DwAddr],esi
mov esi, dword ptr ds : [eax+3*4]
mov dword ptr ds : [PTE],esi
mov esi, dword ptr ds : [eax+4*4]
mov dword ptr ds : [PDE],esi
}
__asm
{
mov eax, dword ptr ds : [PDE]
mov ecx, dword ptr ds : [eax]
//检测PDE P位
test cl,0x1
jz Pflage_Nop
//检测PDE PS位
test cl,0x80
jz Nops
//检测是否跨页
mov dword ptr ds : [_MAXPage], 0x1
mov eax, dword ptr ds:[DwAddr]
and eax,0x00000FFF
mov ecx, dword ptr ds : [DwLeght]
add eax,ecx
cmp eax,0x00001000
jns steppage
jmp nosteppage
Nops: //小页
mov eax, dword ptr ds : [PTE]
mov ecx, dword ptr ds : [eax]
//检测PTE P位
test cl,0x1
jz Pflage_Nop
//检测PTE PAT位
test cl,0x80
jnz PatFlage_Code
//检测是否跨页
mov eax, dword ptr ds : [DwAddr]
and eax, 0x00000FFF
mov ecx, dword ptr ds : [DwLeght]
add eax, ecx
cmp eax, 0x00001000
jns steppage
jmp nosteppage
}
steppage: //读取的内存地址跨页执行代码
__asm
{
//每读取1字节就检测P位,防止跨页的线性地址没有物理页导致CPU报错 -- 根据大页还是小页检测
//大页:读取时只检测PDE P位
mov eax, dword ptr ds : [_MAXPage]
test al,0x1
jz Small_Page_Code
push ebp
mov ebp, esp
sub esp, 0x20
mov dword ptr ss : [ebp - 0x4], 0x0
JMP while_b_F
while_a_F :
mov eax, dword ptr ds : [DwAddr]
mov esi, dword ptr ds : [ebp - 0x4]
mov edi,eax
add edi,esi
mov ecx,edi
shr ecx,0x12
and ecx,0X3FF8
sub ecx,0X3FA00000
mov dword ptr ss : [ebp-0x8],ecx
mov ecx,edi
shr ecx,0x9
and ecx,0x7FFFF8
sub ecx,0x40000000
mov dword ptr ss : [ebp-0xC],ecx
mov ecx, dword ptr ds : [ebp-0x8]
mov ecx, dword ptr ds : [ecx]
test cl,0x1 //检测PDE P位
jz _FL
mov eax, dword ptr ds : [DwAddr]
mov esi, dword ptr ds : [ebp - 0x4]
xor ecx,ecx
mov cl, byte ptr ds : [eax + esi]
mov eax, dword ptr ds : [Buff]
mov byte ptr ds : [eax + esi], cl
mov ecx, dword ptr ds : [ebp - 0x4]
add ecx, 0x1
mov dword ptr ds : [ebp - 0x4], ecx
while_b_F :
mov eax, dword ptr ds : [DwLeght]
mov ecx, dword ptr ds : [ebp - 0x4]
cmp ecx, eax
js while_a_F
jmp _FL
//小页:读取时检测PDE和PTE P位
Small_Page_Code:
push ebp
mov ebp, esp
sub esp, 0x20
mov dword ptr ss : [ebp - 0x4], 0x0
JMP while_b_T
while_a_T :
mov eax, dword ptr ds : [DwAddr]
mov esi, dword ptr ds : [ebp - 0x4]
mov edi, eax
add edi, esi
mov ecx, edi
shr ecx, 0x12
and ecx, 0X3FF8
sub ecx, 0X3FA00000
mov dword ptr ss : [ebp - 0x8], ecx
mov ecx, edi
shr ecx, 0x9
and ecx, 0x7FFFF8
sub ecx, 0x40000000
mov dword ptr ss : [ebp - 0xC], ecx
mov ecx, dword ptr ds : [ebp - 0x8]
mov ecx, dword ptr ds : [ecx]
test cl, 0x1 //检测PDE P位
jz _FL
mov ecx, dword ptr ds : [ebp-0xC]
mov ecx, dword ptr ds : [ecx]
test cl,0x1 //检测PTE P位
jz _FL
xor ecx,ecx
mov eax, dword ptr ds : [DwAddr]
mov esi, dword ptr ds : [ebp - 0x4]
mov cl, byte ptr ds : [eax + esi]
mov eax, dword ptr ds : [Buff]
mov byte ptr ds : [eax + esi], cl
mov ecx, dword ptr ds : [ebp - 0x4]
add ecx, 0x1
mov dword ptr ds : [ebp - 0x4], ecx
while_b_T :
mov eax, dword ptr ds : [DwLeght]
mov ecx, dword ptr ds : [ebp - 0x4]
cmp ecx, eax
js while_a_T
_FL:
mov dword ptr ds : [_TockPage], 0x1
mov eax, dword ptr ds : [ebp - 0x4]
leave
jmp _Retf
}
nosteppage://读取的内存地址无需跨页执行代码
__asm
{
//直接读取DwLeght个字节到缓冲区
push ebp
mov ebp, esp
sub esp, 0x20
mov dword ptr ss : [ebp - 0x4], 0x0
JMP while_b
while_a :
mov eax, dword ptr ds : [DwAddr]
mov esi, dword ptr ds : [ebp - 0x4]
mov cl, byte ptr ds : [eax + esi]
mov eax, dword ptr ds : [Buff]
mov byte ptr ds : [eax + esi], cl
mov ecx, dword ptr ds : [ebp - 0x4]
add ecx, 0x1
mov dword ptr ds : [ebp - 0x4], ecx
while_b :
mov eax, dword ptr ds : [DwLeght]
mov ecx, dword ptr ds : [ebp - 0x4]
cmp ecx, eax
js while_a
mov eax, dword ptr ds : [ebp - 0x4]
leave
JMP _Retf
}
Pflage_Nop: //P位无效
__asm
{
mov dword ptr ds : [_P_Flafge],0x1
xor eax,eax
jmp _Retf
}
PatFlage_Code: //PAT位为1执行代码
__asm
{
mov dword ptr ds : [_PAT_Flage],0x1
xor eax, eax
jmp _Retf
}
_Retf:
__asm
{
retf 0x14
}
}
DWORD MyReadMemory(OUT BYTE* Buff, IN DWORD DwAddr, IN DWORD DwLeght)
{
unsigned int PDE = DwAddr >> 0X12;
PDE &= 0X3FF8;
PDE -= 0X3FA00000;
unsigned int PTE = DwAddr >> 0x9;
PTE &= 0x7FFFF8;
PTE -= 0X40000000;
BYTE RunCode[6] = { 0 };
RunCode[4] = 0x93;
BOOL RetCode;
__asm
{
push PDE
push PTE
push DwAddr
push DwLeght
push Buff
call fword ptr ds : [RunCode]
mov dword ptr ds : [RetCode],eax
}
return RetCode;
}
VOID main()
{
BYTE Buff[20] = { 0 };
CHAR* Str = "Hello 你好?";
DWORD _ReadSize = MyReadMemory(Buff, 0x8003fffe, 4);
printf("是否大页:%X -- 是否跨段:%X -- P位:%X PAT位:%X\r\n", _MAXPage, _TockPage, _P_Flafge, _PAT_Flage);
if (_ReadSize)
{
printf("%X -- %d\r\n", *(DWORD*)Buff,_ReadSize);
}
else
{
printf("读取失败\r\n");
}
getchar();
}
2. 申请长度为100的DWORD的数组,且每项用该项的地址初始化;
把这个数组所在的物理页挂到0x1000的地址上;
定义一个指针,指向0x1000这个页里的数组所在的地址,用0x1000这个页的线性地址打印出这数组的值;
要求:
数组所在的物理页,是同一个页;
#include <windows.h>
#include <stdio.h>
VOID _declspec(naked) Start()
{
DWORD Address_1;
DWORD Address_2;
unsigned int _Address_1_PTE;
unsigned int _Address_2_PTE;
__asm
{
mov eax, dword ptr ds : [esp+0x8]
mov dword ptr ds : [Address_1], eax
}
Address_2 = 0x1000;
_Address_1_PTE = Address_1 >> 0x9;
_Address_1_PTE &= 0x7FFFF8;
_Address_1_PTE -= 0x40000000;
_Address_2_PTE = Address_2 >> 0x9;
_Address_2_PTE &= 0x7FFFF8;
_Address_2_PTE -= 0x40000000;
__asm
{
mov eax,dword ptr ds : [_Address_1_PTE]
mov ecx, dword ptr ds : [eax]
mov edx, dword ptr ds : [_Address_2_PTE]
mov dword ptr ds : [edx],ecx
}
__asm
{
retf 0x4
}
}
//eq 8003f090 0040EC01`00081000
VOID main()
{
DWORD Address = (DWORD)VirtualAlloc(NULL, 400, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
BYTE RunCode[6] = {0};
RunCode[4] = 0x93;
if ((Address & 0x00000FFF) > 0x0)
{
printf("申请内存失败\r\n");
}
else
{
DWORD* Address_p = (DWORD*)Address;
for (DWORD _index = 0; _index < 100; _index++)
{
*(Address_p+_index) = _index;
}
__asm
{
push Address;
call fword ptr ds : [RunCode]
}
DWORD* P = (DWORD*)0X1000;
for (DWORD _index = 0; _index < 100; _index++)
{
printf("%X\r\n",*(P + _index));
}
}
VirtualFree((LPVOID)Address, 400, MEM_DECOMMIT);
getchar();
}
|
温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【 投诉建议】板块发帖举报。
|