[原创][win内核学习笔记]过写拷贝实现所有进程API HOOK----shellcode实现
2022-11-7 16:42:0 Author: bbs.pediy.com(查看原文) 阅读量:19 收藏

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

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

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

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

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;

}

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

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;

}


文章来源: https://bbs.pediy.com/thread-275027.htm
如有侵权请联系:admin#unsafe.sh