首页
社区
课程
招聘
[原创][win内核学习笔记]过写拷贝实现所有进程API HOOK----shellcode实现
2022-11-7 16:42 15258

[原创][win内核学习笔记]过写拷贝实现所有进程API HOOK----shellcode实现

2022-11-7 16:42
15258

0x01 环境

windows xp
wdk7600
2-9-9-12分页

0x02 实现功能

替换MessageBoxA的第二个参数

0x03 流程

1.在R0层申请一块内存,用来放置shellcode
2.R3修改shellcode的页属性+us、+rw,写入shellcode,shellcode末尾的代码需要还原MessageBoxA的指令

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
__shellcode:
    //int 3
    mov eax, __end
    mov[esp + 0xc], eax
    pop eax
 
    /*
    .text:77D507EA 8B FF                                           mov     edi, edi
    .text:77D507EC 55                                              push    ebp
    .text:77D507ED 8B EC                                           mov     ebp, esp
    .text:77D507EF 83 3D BC 14 D7 77 00                            cmp     _gfEMIEnable, 0
    */
    _emit 0x8B
    _emit 0xFF
    _emit 0x55
    _emit 0x8B
    _emit 0xEC
    _emit 0x83
    _emit 0x3D
    _emit 0xBC
    _emit 0x14
    _emit 0xD7
    _emit 0x77
    _emit 0x00
    jmp eax
__end :

3.创建中断门,负责在调用shellcode之前提权修改shellcode页属性+us,-NX
4.R3修改MessageBoxA的页属性+us、+rw
5.R3对MessageBoxA进行inlineHook
图片描述
替换4条指令(12个字节):

1
2
3
4
5
6
int     0//0替换成步骤3的中断门
nop
mov     eax, 0DEADBEEFh//地址替换成shellcode的地址
call    eax
nop
nop

0x04 实现效果

测试程序:

1
2
3
4
5
int main()
{
    MessageBoxA(0, "123", "456", 0);
    return 0;
}

运行主程序:
图片描述

 

运行测试程序:
图片描述

 

调试测试程序看看指令:
其中 CD 20 是 int 20h
图片描述
图片描述

 

继续运行主程序,取消hook:
图片描述

 

运行测试程序:
图片描述
看到代码已还原:
图片描述

0x05 源代码

R3

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
//main.cpp
#include "Driver.h"
#include <stdio.h>
#include <windows.h>
 
int main(int argc, char* argv[])
{
    Driver d;
    if (!d.loadDriver())
    {
        system("pause");
        return 0;
    }
    printf("loadDriver suc\n");
 
    int a = *(int*)MessageBoxA;
    printf("MessageBoxA: %08x\n", a);
 
    auto pShellCode = d.AllocMemory();
    if (NULL == pShellCode)
    {
        printf("AllocMemory error\n");
        system("pause");
        return 0;
    }
    printf("pMem:0x%08x\n", pShellCode);
    d.ChangeMemoryAttr(pShellCode);
    printf("pMem: %s\n", pShellCode);
    char* pShellCodeBegin = NULL;
    char* pShellCodeEnd = NULL;
 
    _asm
    {
        mov eax, __shellcode
        mov pShellCodeBegin, eax
        mov eax, __end
        mov pShellCodeEnd, eax
        jmp __end
    __shellcode:
        //int 3
        mov eax, __end
        mov[esp + 0xc], eax
        pop eax
 
        /*
        .text:77D507EA 8B FF                                           mov     edi, edi
        .text:77D507EC 55                                              push    ebp
        .text:77D507ED 8B EC                                           mov     ebp, esp
        .text:77D507EF 83 3D BC 14 D7 77 00                            cmp     _gfEMIEnable, 0
        */
        _emit 0x8B
        _emit 0xFF
        _emit 0x55
        _emit 0x8B
        _emit 0xEC
        _emit 0x83
        _emit 0x3D
        _emit 0xBC
        _emit 0x14
        _emit 0xD7
        _emit 0x77
        _emit 0x00
        jmp eax
    __end :
    }
    memcpy(pShellCode, pShellCodeBegin, pShellCodeEnd - pShellCodeBegin);
 
    memcpy(pShellCode, pShellCodeBegin, pShellCodeEnd - pShellCodeBegin);
    char* str_pos = pShellCode + (pShellCodeEnd - pShellCodeBegin);
    memcpy(str_pos, "hack", 5);
    memcpy(pShellCode + 1, &str_pos, 4);
 
    char intGate = d.CreateIntGate();
    printf("intGate:%d\n", intGate);
    d.ChangeMemoryAttr(MessageBoxA);
    char hook[] = { "\xCD\x00\x90\xB8\xEF\xBE\xAD\xDE\xFF\xD0\x90\x90" };
    hook[1] = intGate;
    memcpy(MessageBoxA, hook, 12);
    memcpy((char*)MessageBoxA + 4, &pShellCode, 4);
 
    //__debugbreak();
    system("pause");
 
    char MsgBox_old[] = {"\x8B\xFF\x55\x8B\xEC\x83\x3D\xBC\x14\xD7\x77\x00"};
    memcpy(MessageBoxA, MsgBox_old, 12);
    printf("已还原\n");
    system("pause");
 
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Driver.h
#pragma once
#include "../xpDrv1/SysDefine.h"
 
class Driver
{
public:
    bool loadDriver();
    ~Driver();
    short CreateCallGate(CREATE_CALL_GATE* data);
 
    char CreateIntGate();
    char* AllocMemory();
    bool ChangeMemoryAttr(const void* data);
};
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//Driver.cpp
#include "Driver.h"
#include <Windows.h>
#include <stdio.h>
 
bool Driver::loadDriver()
{
    auto h = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (NULL == h)
    {
        printf("OpenSCManagerA error:%d\n", GetLastError());
        return false;
    }
 
    char path[260] = { 0 };
    GetFullPathNameA("main.sys", 260, path, NULL);
    printf("sys path:%s\n", path);
    auto service = CreateServiceA(
        h, "12345", "678910", SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
        SERVICE_ERROR_IGNORE, path, NULL, NULL, NULL, NULL, NULL);
    if (NULL == service)
    {
        CloseServiceHandle(h);
        DeleteService(service);
        printf("CreateServiceA error:%d\n", GetLastError());
        return false;
    }
 
    if (!StartService(service, NULL, NULL))
    {
        DWORD dwErr = GetLastError();
        if (dwErr != ERROR_SERVICE_ALREADY_RUNNING)
        {
            printf("运行驱动服务失败, %d\n", dwErr);
            return false;
        }
    }
    CloseServiceHandle(service);
    CloseServiceHandle(h);
    return true;
}
 
Driver::~Driver()
{
    SC_HANDLE hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    SC_HANDLE hServiceDDK = OpenServiceA(hServiceMgr, "12345", SERVICE_ALL_ACCESS);
    SERVICE_STATUS SvrStatus;
    ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrStatus);
    DeleteService(hServiceDDK);
    if (hServiceDDK)
    {
        CloseServiceHandle(hServiceDDK);
    }
    if (hServiceMgr)
    {
        CloseServiceHandle(hServiceMgr);
    }
}
 
short Driver::CreateCallGate(CREATE_CALL_GATE* data)
{
    HANDLE hDevice = CreateFileW(
        DRIVER_LINK,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
        printf("CreateFileW error  %d\n", GetLastError());
        return 0;
    }
 
 
    USHORT CallGateDescriptor = 0; // 调用门选择子
    DWORD dwRetBytes; // 返回的字节数
    if (!DeviceIoControl(
        hDevice,
        IOCTL_CREATE_CALL_GATE,
        data,
        sizeof(CREATE_CALL_GATE),
        &CallGateDescriptor,
        sizeof(USHORT),
        &dwRetBytes,
        NULL))
    {
        printf("DeviceIoControl error  %d\n", GetLastError());
    }
    CloseHandle(hDevice);
    if (dwRetBytes != 2 || CallGateDescriptor == 0)
    {
        printf("构造调用门失败.\n");
        return 0;
    }
    return CallGateDescriptor;
}
 
char Driver::CreateIntGate()
{
    HANDLE hDevice = CreateFileW(
        DRIVER_LINK,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
        printf("CreateFileW error  %d\n", GetLastError());
        return NULL;
    }
 
    char Ret = 0;
    DWORD dwRetBytes; // 返回的字节数
    if (!DeviceIoControl(
        hDevice,
        IOCTL_CREATE_INT_GATE,
        NULL,
        0,
        &Ret,
        sizeof(Ret),
        &dwRetBytes,
        NULL))
    {
        printf("DeviceIoControl error  %d\n", GetLastError());
        CloseHandle(hDevice);
        return NULL;
    }
    CloseHandle(hDevice);
    return Ret;
}
 
char* Driver::AllocMemory()
{
    HANDLE hDevice = CreateFileW(
        DRIVER_LINK,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
        printf("CreateFileW error  %d\n", GetLastError());
        return NULL;
    }
 
    char* pRet = NULL;
    DWORD dwRetBytes; // 返回的字节数
    if (!DeviceIoControl(
        hDevice,
        IOCTL_AllOC_SHELLCODE_MEMORY,
        NULL,
        0,
        &pRet,
        sizeof(pRet),
        &dwRetBytes,
        NULL))
    {
        printf("DeviceIoControl error  %d\n", GetLastError());
        CloseHandle(hDevice);
        return NULL;
    }
    CloseHandle(hDevice);
    return pRet;
}
 
bool Driver::ChangeMemoryAttr(const void* data)
{
    HANDLE hDevice = CreateFileW(
        DRIVER_LINK,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
        printf("CreateFileW error  %d\n", GetLastError());
        return false;
    }
 
 
    DWORD dwRetBytes; // 返回的字节数
    if(!DeviceIoControl(
        hDevice,
        IOCTL_CHANGE_MEMORY_ATTR,
        &data,
        sizeof(data),
        NULL,
        0,
        &dwRetBytes,
        NULL))
    {
        printf("DeviceIoControl error  %d\n", GetLastError());
        CloseHandle(hDevice);
        return false;
    }
    CloseHandle(hDevice);
    return true;
}

R0

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
//driverMain.cpp
#include <ntddk.h>
#include "SysDefine.h"
#include "DriverDebugPrinter.h"
 
PDEVICE_OBJECT pDeviceObj = NULL; // 设备对象指针
PVOID pShellCodeBuffer = NULL;
SHORT idt_index = 0;
 
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
    UNREFERENCED_PARAMETER(pDriver);
    DIRVER_PRINT_DEBUG_STRING("DriverUnload\n");
 
    ExFreePool(pShellCodeBuffer);
 
    UNICODE_STRING SymbolicLinkName; // 符号链接名,3环用
    RtlInitUnicodeString(&SymbolicLinkName, DRIVER_LINKD);
    IoDeleteSymbolicLink(&SymbolicLinkName);
    IoDeleteDevice(pDeviceObj);
}
 
typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID      DllBase;
    PVOID      EntryPoint;
    LONG       SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
 
 
NTSTATUS OnCreateCallGate(char* data, ULONG inSize, ULONG_PTR* outSize)
{
    CREATE_CALL_GATE arg;
    RtlCopyMemory(&arg, data, inSize);
 
    DIRVER_PRINT_DEBUG_STRING("OnCreateCallGate pFunc[0x%x], argc[%d]\n", arg.pFunc, arg.argc);
 
    *outSize = 0;
    char gdt[6];
    _asm
    {
        sgdt gdt
    }
 
    PLONG lpgdt = *(PLONG*)(gdt + 2);
    SHORT len = *(PSHORT)gdt;
    DIRVER_PRINT_DEBUG_STRING("gdt addr[0x%x] limit[0x%x]\n", lpgdt, len);
    if (NULL == lpgdt)
    {
        return -1;
    }
 
    for (SHORT i = 2; i < len; i += 2)
    {
        if (0 == (lpgdt[i + 1] & 0x8000))
        {
            LONG hData = (LONG)arg.pFunc & 0xffff0000;
            hData |= 0xec00 | arg.argc;
 
            LONG lData = 0x80000 | ((LONG)arg.pFunc & 0x0000ffff);
 
            lpgdt[i] = lData;
            lpgdt[i + 1] = hData;
 
            SHORT selector = (i / 2) << 3;
 
 
            DIRVER_PRINT_DEBUG_STRING("创建门 gdt[%d] selector[%d]  %08x`%08x\n", i / 2, selector, hData, lData);
            RtlCopyMemory(data, &selector, inSize);
            *outSize = 2;
            return STATUS_SUCCESS;
        }
    }
    return -2;
}
 
void OnAddShellCodePage2()
{
    ULONG p = (ULONG)pShellCodeBuffer & 0xfffff000;
 
    ULONG PDPTI = p >> 30;
    ULONG PDI = (p >> 21) & 0x1ff;
    ULONG PTI = (p >> 12) & 0x1ff;
    ULONG offset = p & 0xfff;
 
    DIRVER_PRINT_DEBUG_STRING(
        "p = 0x%08x\n"
        "PDPTI = 0x%x\n"
        "PDI = 0x%x\n"
        "PTI = 0x%x\n"
        "offset = 0x%x\n",
        p, PDPTI, PDI, PTI, offset
    );
 
 
    //公式:
    //pPDE = 0xc0600000 + (PDPTI * 4KB) + (PDI * 8)
    //pPTE = 0xc0000000 + (PDPTI * 2MB) + (PDI * 4KB) + (PTI * 8)
 
    //更高效的公式(MmIsAddressValid是这么干的)
    //pPDE = 0xc0600000 + ((addr >> 18) & 0x3ff8)
    //pPTE = 0xc0000000 + ((addr >> 9) & 0x7ffff8)
    PULONG pPDE = (PULONG)(0xC0600000 + PDPTI * 0x1000 + PDI * 8);
    DIRVER_PRINT_DEBUG_STRING("PDE: %08x`%08x\n", pPDE[1], pPDE[0]);
    pPDE[1] = pPDE[1] & 0x7fffffff;//NX置0
    pPDE[0] = pPDE[0] & 0xfffffffb;
    pPDE[0] = pPDE[0] | 0x4;//us位置1
    DIRVER_PRINT_DEBUG_STRING("PDE: %08x`%08x\n", pPDE[1], pPDE[0]);
    if (0x80 == (pPDE[0] & 0x80))
    {
        DIRVER_PRINT_DEBUG_STRING("Large page\n");
    }
    else
    {
        PULONG pPTE = (PULONG)(0xc0000000 + PDPTI * 0x200000 + PDI * 0x1000 + PTI * 8);
        DIRVER_PRINT_DEBUG_STRING("pPTE: %08x`%08x\n", pPTE[1], pPTE[0]);
        pPTE[1] = pPTE[1] & 0x7fffffff;//NX置0
        pPTE[0] = pPTE[0] & 0xfffffffb;
        pPTE[0] = pPTE[0] | 0x4;//us位置1
        DIRVER_PRINT_DEBUG_STRING("pPTE: %08x`%08x\n", pPTE[1], pPTE[0]);
    }
}
void  __declspec(naked)OnAddShellCodePage()
{
    __asm
    {
        pushad;
        pushfd;
        push fs;
    }
 
    OnAddShellCodePage2();
    __asm
    {
        pop fs;
        popfd;
        popad;
        iretd;
    }
}
 
 
NTSTATUS OnCreateIntGate(char* data, ULONG inSize, ULONG_PTR* outSize)
{
    *outSize = 0;
 
    if (0 != idt_index)
    {
        *outSize = 1;
        RtlCopyMemory(data, &idt_index, *outSize);
        return STATUS_SUCCESS;
    }
 
    char idt[6];
    _asm
    {
        sidt idt
    }
 
    PLONG lpidt = *(PLONG*)(idt + 2);
    SHORT len = *(PSHORT)idt;
    DIRVER_PRINT_DEBUG_STRING("gdt addr[0x%x] limit[0x%x]\n", lpidt, len);
    if (NULL == lpidt)
    {
        return -1;
    }
 
    LONG hData = (LONG)OnAddShellCodePage & 0xffff0000;
    hData |= 0xee00;
 
    LONG lData = 0x80000 | ((LONG)OnAddShellCodePage & 0x0000ffff);
 
    lpidt[32 * 2] = lData;
    lpidt[32 * 2 + 1] = hData;
 
    idt_index = 32;
 
    DIRVER_PRINT_DEBUG_STRING("创建中断门 index[%d]  %08x`%08x\n", idt_index, hData, lData);
    *outSize = 1;
    RtlCopyMemory(data, &idt_index, *outSize);
    return STATUS_SUCCESS;
}
 
NTSTATUS OnAllocShellCodeMemory(char* data, ULONG inSize, ULONG_PTR* outSize)
{
    DIRVER_PRINT_DEBUG_STRING("OnAllocMemory\n");
    *outSize = 0;
    if (NULL == pShellCodeBuffer)
    {
        pShellCodeBuffer = ExAllocatePoolWithTag(NonPagedPool, 0x1000, 'ABCD');
        if (NULL == pShellCodeBuffer)
        {
            DIRVER_PRINT_DEBUG_STRING("ExAllocatePoolWithTag error\n");
            return -1;
        }
 
        RtlCopyMemory(pShellCodeBuffer, "1234deadbeef", 13);
    }
    *outSize = sizeof(pShellCodeBuffer);
    RtlCopyMemory(data, &pShellCodeBuffer, *outSize);
 
    DIRVER_PRINT_DEBUG_STRING("pbuffer:0x%08x    data:%08x\n", pShellCodeBuffer, data);
    return STATUS_SUCCESS;
}
 
NTSTATUS OnChangeMemoryAttr(char* data, ULONG inSize, ULONG_PTR* outSize)
{
    *outSize = 0;
 
    ULONG p = NULL;
    RtlCopyMemory(&p, data, sizeof(p));
 
    if (NULL == p)
    {
        DIRVER_PRINT_DEBUG_STRING("NULL == p\n");
        return -1;
    }
 
 
    p &= 0xfffff000;
 
    ULONG PDPTI = p >> 30;
    ULONG PDI = (p >> 21) & 0x1ff;
    ULONG PTI = (p >> 12) & 0x1ff;
    ULONG offset = p & 0xfff;
 
    DIRVER_PRINT_DEBUG_STRING(
        "p = 0x%08x\n"
        "PDPTI = 0x%x\n"
        "PDI = 0x%x\n"
        "PTI = 0x%x\n"
        "offset = 0x%x\n",
        p, PDPTI, PDI, PTI, offset
    );
 
 
    //公式:
    //pPDE = 0xc0600000 + (PDPTI * 4KB) + (PDI * 8)
    //pPTE = 0xc0000000 + (PDPTI * 2MB) + (PDI * 4KB) + (PTI * 8)
 
    //更高效的公式(MmIsAddressValid是这么干的)
    //pPDE = 0xc0600000 + ((addr >> 18) & 0x3ff8)
    //pPTE = 0xc0000000 + ((addr >> 9) & 0x7ffff8)
    PULONG pPDE = (PULONG)(0xC0600000 + PDPTI * 0x1000 + PDI * 8);
    DIRVER_PRINT_DEBUG_STRING("PDE: %08x`%08x\n", pPDE[1], pPDE[0]);
    pPDE[1] = pPDE[1] & 0x7fffffff;//NX置0
    pPDE[0] = pPDE[0] & 0xfffffffb;
    pPDE[0] = pPDE[0] | 0x6;//us,rw位置1
    DIRVER_PRINT_DEBUG_STRING("PDE: %08x`%08x\n", pPDE[1], pPDE[0]);
    if (0x80 == (pPDE[0] & 0x80))
    {
        DIRVER_PRINT_DEBUG_STRING("Large page\n");
    }
    else
    {
        PULONG pPTE = (PULONG)(0xc0000000 + PDPTI * 0x200000 + PDI * 0x1000 + PTI * 8);
        DIRVER_PRINT_DEBUG_STRING("pPTE: %08x`%08x\n", pPTE[1], pPTE[0]);
        pPTE[1] = pPTE[1] & 0x7fffffff;
        pPTE[0] = pPTE[0] & 0xfffffffb;
        pPTE[0] = pPTE[0] | 0x6;//us,rw位置1
        DIRVER_PRINT_DEBUG_STRING("pPTE: %08x`%08x\n", pPTE[1], pPTE[0]);
    }
 
 
    return STATUS_SUCCESS;
}
 
NTSTATUS OnMessage(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    UNREFERENCED_PARAMETER(DeviceObject);
    STATUS_SUCCESS;
 
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
 
    if (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction)
    {
        static struct
        {
            ULONG id;
            NTSTATUS(*callback)(char* pData, ULONG lenth, ULONG_PTR*);
        }CallBackMap[] =
        {
            {IOCTL_CREATE_CALL_GATE, OnCreateCallGate},
            {IOCTL_AllOC_SHELLCODE_MEMORY, OnAllocShellCodeMemory},
            {IOCTL_CHANGE_MEMORY_ATTR, OnChangeMemoryAttr},
            {IOCTL_CREATE_INT_GATE, OnCreateIntGate},
        };
 
        for (int i = 0; i < sizeof(CallBackMap) / sizeof(CallBackMap[0]); ++i)
        {
            if (CallBackMap[i].id == irpStack->Parameters.DeviceIoControl.IoControlCode)
            {
                Irp->IoStatus.Status = CallBackMap[i].callback(
                    (char*)Irp->AssociatedIrp.SystemBuffer,
                    irpStack->Parameters.DeviceIoControl.InputBufferLength,
                    &Irp->IoStatus.Information);
                break;
            }
        }
    }
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}
 
// IRP_MJ_CREATE 处理函数
NTSTATUS IrpCreateProc(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
    //DbgPrint("应用层连接设备.\n");
    // 返回状态如果不设置,Ring3返回值是失败
    pIrp->IoStatus.Status = STATUS_SUCCESS;
    pIrp->IoStatus.Information = 0;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}
 
// IRP_MJ_CLOSE 处理函数
NTSTATUS IrpCloseProc(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
    //DbgPrint("应用层断开连接设备.\n");
    // 返回状态如果不设置,Ring3返回值是失败
    pIrp->IoStatus.Status = STATUS_SUCCESS;
    pIrp->IoStatus.Information = 0;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}
 
extern"C"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath)
{
    UNREFERENCED_PARAMETER(pRegPath);
 
    pDriver->DriverUnload = DriverUnload;
    pDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OnMessage;
    pDriver->MajorFunction[IRP_MJ_CREATE] = IrpCreateProc;
    pDriver->MajorFunction[IRP_MJ_CLOSE] = IrpCloseProc;
 
    DIRVER_PRINT_DEBUG_STRING("pDriver: 0x%08x\n", pDriver);
 
    UNICODE_STRING DeviceName; // 设备名,0环用
    RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
    auto status = IoCreateDevice(pDriver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObj);
    if (status != STATUS_SUCCESS)
    {
        IoDeleteDevice(pDeviceObj);
        DIRVER_PRINT_DEBUG_STRING("创建设备失败 0x%08x.\n", status);
        return status;
    }
 
    UNICODE_STRING SymbolicLinkName; // 符号链接名,3环用
    RtlInitUnicodeString(&SymbolicLinkName, DRIVER_LINKD);
 
    status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
    if (!NT_SUCCESS(status))
    {
        DIRVER_PRINT_DEBUG_STRING("创建符号失败 0x%08x.\n", status);
    }
 
    return STATUS_SUCCESS;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//SysDefine.h
#pragma once
 
#define FILE_DEVICE_LY    0xD431
 
#define IOCTL_CREATE_CALL_GATE            (ULONG)CTL_CODE(FILE_DEVICE_LY, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AllOC_SHELLCODE_MEMORY    (ULONG)CTL_CODE(FILE_DEVICE_LY, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_CHANGE_MEMORY_ATTR        (ULONG)CTL_CODE(FILE_DEVICE_LY, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_CREATE_INT_GATE            (ULONG)CTL_CODE(FILE_DEVICE_LY, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
#define DEVICE_NAME L"\\Device\\lalalasssssss"
#define DRIVER_LINKD L"\\??\\lalala"
#define DRIVER_LINK L"\\\\.\\lalala"
 
struct CREATE_CALL_GATE
{
    void* pFunc;
    int argc;
};

[培训]《安卓高级研修班(网课)》月薪三万计划

最后于 2022-11-8 14:33 被洋洋不得意编辑 ,原因: 过写拷贝
收藏
点赞3
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回