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

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

2022-11-7 16:42
16686

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

替换MessageBoxA的第二个参数

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

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

测试程序:

运行主程序:
图片描述

运行测试程序:
图片描述

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

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

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

R3

R0

__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 :
__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 :
int     0//0替换成步骤3的中断门
nop
mov     eax, 0DEADBEEFh//地址替换成shellcode的地址
call    eax
nop
nop
int     0//0替换成步骤3的中断门
nop
mov     eax, 0DEADBEEFh//地址替换成shellcode的地址
call    eax
nop
nop
int main()
{
    MessageBoxA(0, "123", "456", 0);
    return 0;
}
int main()
{
    MessageBoxA(0, "123", "456", 0);
    return 0;
}
 
 
 
 
//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;
}
//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;
}
//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);
};
//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);
};
//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;
}
//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;
}
//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;
}
//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)
{

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

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