切换CR3跨进程读写内存

环境:XPx32、Win7x32

项目历时三天,最终在朋友的帮助下,搞成功了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include<ntifs.h>
#include <minwindef.h>

#define DEVICE_NAME L"\\Device\\ReadDrv"
#define SYM_LINK_NAME L"\\??\\ReadDrv"

#define _WIN7

NTSTATUS GetProcessDirBase(IN DWORD dwPID, OUT ULONG* pDirBase)
{
PEPROCESS Process;
PEPROCESS CurProcess;
CHAR* pszImageName;
DWORD dwCurPID;

__try
{
__asm
{
//ETHREAD
mov eax, fs: [124h]
//Current EPROCESS
#ifdef _XP
mov eax, [eax + 44h]
#endif
#ifdef _WIN7
mov eax, [eax + 50h]
#endif

mov Process, eax
}

CurProcess = Process;

//traversing EPROCESS
do
{
#ifdef _XP
pszImageName = (char*)CurProcess + 0x174;
#endif
#ifdef _WIN7
pszImageName = (char*)CurProcess + 0x16C;
#endif
#ifdef _XP
dwCurPID = (*(ULONG*)((char*)CurProcess + 0x084));
#endif
#ifdef _WIN7
dwCurPID = (*(ULONG*)((char*)CurProcess + 0x0B4));
#endif
if (dwCurPID == dwPID)
{
*pDirBase = (*(ULONG*)((char*)CurProcess + 0x018));
return STATUS_SUCCESS;
}
#ifdef _XP
CurProcess = (PEPROCESS)((*(ULONG*)((char*)CurProcess + 0x0B8)) - 0xB8);
#endif
#ifdef _WIN7
CurProcess = (PEPROCESS)((*(ULONG*)((char*)CurProcess + 0x0B8)) - 0xB8);
#endif

} while (CurProcess != Process);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("[-] GetProcessDirBase __except \r\n");
}

return STATUS_INVALID_DEVICE_REQUEST;
}

NTSTATUS KeReadProcessMemory(ULONG Pid, ULONG* VirtualAddress, ULONG* pBuffer, ULONG Size)
{
_asm
{
//int 3
}

ULONG OldDirBase = 0;
ULONG DirBase = 0;
//DWORD dwBufSize = 0x1000;
BOOL bIsRead = FALSE;
KIRQL oldIrql = KeRaiseIrqlToDpcLevel();

NTSTATUS ntStatus = GetProcessDirBase(Pid, &DirBase);
if (ntStatus < 0)
{
DbgPrint("[-] GetProcessDirBase Fail,Status = 0x%x\n", ntStatus);
return ntStatus;
}
DbgPrint("[*] Target Cr3 = 0x%x\n", DirBase);

__asm
{
//Shielding interrupt
cli
//close memory protect
mov eax, cr0
and eax, not 10000h
mov cr0, eax
mov eax, cr3
mov OldDirBase, eax
//swap CR3
mov eax, DirBase
mov cr3, eax
}

//Alloc ring0 Buff
//char* szRing0Buf = (char*)MmAllocateNonCachedMemory(Size);
//check address invalid
if (MmIsAddressValid(VirtualAddress))
{
__try
{
RtlCopyMemory(pBuffer, VirtualAddress, Size);
bIsRead = TRUE;
}
__except (1)
{
DbgPrint("[-] RtlCopyMemory Fail\n");
}
}

__asm
{
mov eax, OldDirBase
mov cr3, eax
//Reset memory protect
mov eax, cr0
or eax, 10000h
mov cr0, eax
//Restore interrupt
sti
}

KeLowerIrql(oldIrql);

return ntStatus;
}

NTSTATUS DriverUnload(PDRIVER_OBJECT pDrvObj)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
DbgPrint("[+] Unload Success\n");
return ntStatus;
}


NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
//PDEVICE_OBJECT pDeviceObject = NULL;
UNICODE_STRING uDeviceName = { 0 };
UNICODE_STRING uSymlinkName = { 0 };
RtlInitUnicodeString(&uDeviceName, DEVICE_NAME);
RtlInitUnicodeString(&uSymlinkName, SYM_LINK_NAME);
DbgPrint("[+] Driver Installed\n");

VOID* pBuffer = ExAllocatePoolZero(NonPagedPool, 0x1000, 0);
if (!pBuffer)
{
return STATUS_UNSUCCESSFUL;
}

KeReadProcessMemory(0xE58, (ULONG*)0x0018F76C,pBuffer,0x1000);
DbgPrint("[*] 0x%x\n", *(ULONG*)pBuffer);
//DbgPrint("[*] %ws\n", pBuffer);

ExFreePool(pBuffer);

pDrvObj->DriverUnload = DriverUnload;
return ntStatus;
}

3545dc446def0d8bf8bdd01040b7df37.png

f66374dfaa53dcaea475999a992c9028.png

ReadDrv.zip


切换CR3跨进程读写内存
https://rogxo.github.io/2022/01/03/2022-01-03-切换CR3跨进程读写内存/
作者
Rogxo
发布于
2022年1月3日
许可协议
CC BY-NC-SA 4.0