前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >windows内核提权,又一突破游戏进程保护的方法

windows内核提权,又一突破游戏进程保护的方法

作者头像
IBinary
发布2023-07-24 21:54:57
1K0
发布2023-07-24 21:54:57
举报
文章被收录于专栏:逆向技术逆向技术

windows内核提权,又一突破游戏保护的方式。

一丶 句柄表

1.1 介绍

当一个进程被保护的时候 比如无法获取其进程句柄权限 (OpenProcess) 或者无法获取内存读写访问权限的时候,则可以使用此方法来进行提权。

前置知识,了解windows系统句柄表的构成

可查看本博客链接:

x64windows内核句柄表PspCidTable原理与解析 - iBinary - 博客园 (cnblogs.com)

1.2 原理

句柄表项结构 HANDLE_TABLE_ENTRY 里面有一个成员记录了 当前句柄所需要得访问权限。

结构如下:

代码语言:javascript
复制
//0x8 bytes (sizeof)
union _HANDLE_TABLE_ENTRY
{
    volatile LONG VolatileLowValue;                                         //0x0
    LONG LowValue;                                                          //0x0
    struct
    {
        struct _HANDLE_TABLE_ENTRY_INFO* volatile InfoTable;                //0x0
    LONG HighValue;                                                         //0x4
    union _HANDLE_TABLE_ENTRY* NextFreeHandleEntry;                         //0x4
        struct _EXHANDLE LeafHandleValue;                                   //0x4
    };
    ULONG Unlocked:1;                                                       //0x0
    ULONG Attributes:2;                                                     //0x0
    struct
    {
        ULONG ObjectPointerBits:29;                                         //0x0
    LONG RefCountField;                                                     //0x4
    ULONG GrantedAccessBits:25;                                             //0x4
    ULONG ProtectFromClose:1;                                               //0x4
    ULONG NoRightsUpgrade:1;                                                //0x4
    };
    ULONG RefCnt:5;                                                         //0x4
}; 

其中他大部分是联合体组成,其核心字段则是 GrantedAccessBits

所以我们的做法是 首先拿到被降权的句柄,然后将此句柄的 权限修改为

完整权限,也就是 0x1fffff 。修改完成之后再用提权的句柄进行我们的操作。

二丶代码演示

2.1 核心提权驱动代码

核心驱动代码很简单。

如下:

代码语言:javascript
复制
#include <ntifs.h>
#include <ntddk.h>

typedef union _EXHANDLE
{
    struct
    {
        int TagBits : 2;
        int Index : 30;
    } u;
    void* GenericHandleOverlay;
    ULONG_PTR Value;
} EXHANDLE, *PEXHANDLE;

typedef struct _HANDLE_TABLE_ENTRY // Size=16
{
    union
    {
        ULONG_PTR VolatileLowValue; // Size=8 Offset=0
        ULONG_PTR LowValue; // Size=8 Offset=0
        struct _HANDLE_TABLE_ENTRY_INFO* InfoTable; // Size=8 Offset=0
        struct
        {
            ULONG_PTR Unlocked : 1; // Size=8 Offset=0 BitOffset=0 BitCount=1
            ULONG_PTR RefCnt : 16; // Size=8 Offset=0 BitOffset=1 BitCount=16
            ULONG_PTR Attributes : 3; // Size=8 Offset=0 BitOffset=17 BitCount=3
            ULONG_PTR ObjectPointerBits : 44; // Size=8 Offset=0 BitOffset=20 BitCount=44
        };
    };
    union
    {
        ULONG_PTR HighValue; // Size=8 Offset=8
        struct _HANDLE_TABLE_ENTRY* NextFreeHandleEntry; // Size=8 Offset=8
        union _EXHANDLE LeafHandleValue; // Size=8 Offset=8
        struct
        {
            ULONG GrantedAccessBits : 25; // Size=4 Offset=8 BitOffset=0 BitCount=25
            ULONG NoRightsUpgrade : 1; // Size=4 Offset=8 BitOffset=25 BitCount=1
            ULONG Spare : 6; // Size=4 Offset=8 BitOffset=26 BitCount=6
        };
    };
    ULONG TypeInfo; // Size=4 Offset=12
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;

typedef struct _HANDLE_TABLE
{
    ULONG NextHandleNeedingPool;
    long ExtraInfoPages;
    LONG_PTR TableCode;
    PEPROCESS QuotaProcess;
    LIST_ENTRY HandleTableList;
    ULONG UniqueProcessId;
    ULONG Flags;
    EX_PUSH_LOCK HandleContentionEvent;
    EX_PUSH_LOCK HandleTableLock;
    // More fields here...
} HANDLE_TABLE, *PHANDLE_TABLE;

typedef BOOLEAN(*EX_ENUMERATE_HANDLE_ROUTINE)(
    IN PHANDLE_TABLE HandleTable,
    IN PHANDLE_TABLE_ENTRY HandleTableEntry,
    IN HANDLE Handle,
    IN PVOID EnumParameter
    );

#ifdef __cplusplus
extern "C"
{
#endif

    BOOLEAN NTAPI ExEnumHandleTable(
        IN PHANDLE_TABLE HandleTable,
        IN EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
        IN PVOID EnumParameter,
        OUT PHANDLE Handle);

    VOID FASTCALL ExfUnblockPushLock(
        IN OUT PEX_PUSH_LOCK PushLock,
        IN OUT PVOID WaitBlock
    );

#ifdef __cplusplus
}
#endif

typedef struct _HANDLE_INFO
{
    unsigned long process_id;
    unsigned long access;
    unsigned long long handle;
}HANDLE_INFO, *PHANDLE_INFO;



unsigned char callback(
    PHANDLE_TABLE pHandleTableAddress,
    PHANDLE_TABLE_ENTRY pHandleTableEntryInfo,
    HANDLE Handle,
    PVOID pContext)
{
#define ExpIsValidObjectEntry(Entry) ( (Entry) && (Entry->LowValue != 0) && (Entry->HighValue != -2) )

    unsigned char result = 0;
    if (MmIsAddressValid(pContext))
    {
        PHANDLE_INFO info = (PHANDLE_INFO)pContext;
        if (info->handle == (unsigned long long)Handle
            && MmIsAddressValid(pHandleTableEntryInfo)
            && ExpIsValidObjectEntry(pHandleTableEntryInfo)
            && pHandleTableEntryInfo->GrantedAccessBits != info->access)
        {
            pHandleTableEntryInfo->GrantedAccessBits = info->access;
            result = 1;
        }
    }

    if (pHandleTableEntryInfo) _InterlockedExchangeAdd8((char*)&pHandleTableEntryInfo->VolatileLowValue, 1);
    if (pHandleTableAddress && pHandleTableAddress->HandleContentionEvent) ExfUnblockPushLock(&pHandleTableAddress->HandleContentionEvent, NULL);

    return result;
}

void handleUpdateAccess(HANDLE_INFO info)
{
    PEPROCESS process{ 0 };
    NTSTATUS status = PsLookupProcessByProcessId((HANDLE)info.process_id, &process);
    if (NT_SUCCESS(status))
    {
        //dt _EPROCESS find ObjectTable  offset replace ox418 of offset
        PHANDLE_TABLE table_ptr = *(PHANDLE_TABLE*)((PUCHAR)process + 0x418);
        if (MmIsAddressValid(table_ptr)) ExEnumHandleTable(table_ptr, &callback, &info, NULL);

        ObDereferenceObject(process);
    }
}






VOID DriverUnload(PDRIVER_OBJECT)
{

}

EXTERN_C
NTSTATUS
DriverEntry(
    PDRIVER_OBJECT driver,
    PUNICODE_STRING)
{
    driver->DriverUnload = DriverUnload;

    HANDLE_INFO info{ 0 };
    info.process_id = 6288; //需要被提权的进程PID
    info.access = 0x1fffff; //设置为所有权限
    info.handle = 0xA4;     //提权进程拿到权限的句柄

    handleUpdateAccess(info);
    return STATUS_SUCCESS;
}

2.2 用户程序以及使用说明例子

用户层面演示例子:

代码语言:javascript
复制
// ShutDownProtectProcess.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <windows.h>
#include <iostream>

using namespace std;


int main()
{
    //可以拿到一个较低等级的权限  例如:PROCESS_QUERY_INFORMATION
    HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, 7652);
    BOOL bRet = FALSE;
    cout << "HANDLE = " << hex << hProcess << endl;
    cout << "Start Terminate Process " << endl;
    bRet =  TerminateProcess(hProcess,0);
    if (bRet == FALSE)
    {
        cout << "TerminateProcess Error try two Terminate" << endl;
        system("pause"); //等待安装好内核文件,来进行权限提升,在按任意键继续
        bRet = TerminateProcess(hProcess, 0);
        if (bRet == FALSE)
        {
            cout << "Two TerminateProcess Error " << endl;
            system("pause");
            return 0;
        }
        {
            cout << "Two TerminateProcess Success " << endl;
            system("pause");
            return 0;
        }

    }

    else
    {
        cout << "one TerminateProcess Success " << endl;
        system("pause");
        return 0;
    }

    system("pause");
    return 0;

}

因为我没有封装内核通信。所以运行USER程序之后会等待用户自己手动安装驱动。

驱动里面的PID要改成USER程序的,也要把用户获取的HANDLE打印出来修改到驱动中。

然后重新编译驱动,进行安装。 安装之后句柄就会被提权的。 此时用户程序继续运行即可结束被保护的notepad程序。

2.3 进程保护驱动Demo源码

代码语言:javascript
复制
#include <ntifs.h>
#include <ntstrsafe.h>
#define PROCESS_TERMINATE         (0x0001)  // winnt
#define PROCESS_CREATE_THREAD     (0x0002)  // winnt
#define PROCESS_SET_SESSIONID     (0x0004)  // winnt
#define PROCESS_VM_OPERATION      (0x0008)  // winnt
#define PROCESS_VM_READ           (0x0010)  // winnt
#define PROCESS_VM_WRITE          (0x0020)  // winnt
// begin_ntddk begin_wdm begin_ntifs
#define PROCESS_DUP_HANDLE        (0x0040)  // winnt
// end_ntddk end_wdm end_ntifs
#define PROCESS_CREATE_PROCESS    (0x0080)  // winnt
#define PROCESS_SET_QUOTA         (0x0100)  // winnt
#define PROCESS_SET_INFORMATION   (0x0200)  // winnt
#define PROCESS_QUERY_INFORMATION (0x0400)  // winnt
#define PROCESS_SET_PORT          (0x0800)
#define PROCESS_SUSPEND_RESUME    (0x0800)  // winnt
PVOID g_ObjHandle;


extern "C" NTKERNELAPI
UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);

OB_PREOP_CALLBACK_STATUS MyObjectCallBack(
    PVOID RegistrationContext,
    POB_PRE_OPERATION_INFORMATION OperationInformation
)
{
    UNREFERENCED_PARAMETER(RegistrationContext);
    PEPROCESS pProcess = NULL;
    CHAR *pszName = NULL;

    pProcess = (PEPROCESS)OperationInformation->Object;
    pszName = (CHAR*)PsGetProcessImageFileName(pProcess);

    //判断标志是否要打开进程
    if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
    {
        //获取名字匹配
        if (strstr(pszName, (CHAR*)"notepad"))
        {
            KdPrint(("%s \r\n", pszName));
            //判断是不是结束
            if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess
                & PROCESS_TERMINATE) == 1)
            {
                //如果是我们的.则设置DesiredAccess权限.去掉结束权限.
                OperationInformation->Parameters->CreateHandleInformation.DesiredAccess
                    = (ULONG)~PROCESS_TERMINATE;
                return OB_PREOP_SUCCESS;
            }
        }
    }


    return OB_PREOP_SUCCESS;

}
VOID InitHook()
{
    //进行HOOK 回调钩子写法. 
    OB_OPERATION_REGISTRATION oper; //你的回调函数以及类型都放在这个结构体中,可以是结构体数组.
    OB_CALLBACK_REGISTRATION CallbackRegistration;
    CallbackRegistration.Version = OB_FLT_REGISTRATION_VERSION; //版本号
    CallbackRegistration.OperationRegistrationCount = 1;//下几个钩子,也就是结构体数组个数
    RtlUnicodeStringInit(&CallbackRegistration.Altitude, L"600000");//给个UNICODEstring表明您是干啥的
    CallbackRegistration.RegistrationContext = NULL;         //当你的回调函数到的时候参数是什么.由这里给出
    CallbackRegistration.OperationRegistration = &oper; //钩子结构体类型设置.
    //为钩子结构体赋值
    oper.ObjectType = PsProcessType; //进程操作的类型.当进程操作回来. PsThreadType则是线程操作
    oper.Operations = OB_OPERATION_HANDLE_CREATE; //操作的类型是将要打开.以及将要重复
    oper.PreOperation = MyObjectCallBack; //有两个指针,前指针跟后指针.意思分别是 进程创建之前通知你还是之后
    oper.PostOperation = NULL;
    ObRegisterCallbacks(&CallbackRegistration, &g_ObjHandle);
}

VOID UnHook()
{
    ObUnRegisterCallbacks(g_ObjHandle);
}





VOID
DriverUnLoad(
    _In_ struct _DRIVER_OBJECT *DriverObject
)
{
    UNREFERENCED_PARAMETER(DriverObject);
    UnHook();
}

typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY64    InLoadOrderLinks;
    LIST_ENTRY64    InMemoryOrderLinks;
    LIST_ENTRY64    InInitializationOrderLinks;
    PVOID            DllBase;
    PVOID            EntryPoint;
    ULONG            SizeOfImage;
    UNICODE_STRING    FullDllName;
    UNICODE_STRING     BaseDllName;
    ULONG            Flags;
    USHORT            LoadCount;
    USHORT            TlsIndex;
    PVOID            SectionPointer;
    ULONG            CheckSum;
    PVOID            LoadedImports;
    PVOID            EntryPointActivationContext;
    PVOID            PatchInformation;
    LIST_ENTRY64    ForwarderLinks;
    LIST_ENTRY64    ServiceTagLinks;
    LIST_ENTRY64    StaticLinks;
    PVOID            ContextInformation;
    ULONG            OriginalBase;
    LARGE_INTEGER    LoadTime;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;


extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
{
    UNREFERENCED_PARAMETER(pRegPath);
    PLDR_DATA_TABLE_ENTRY ldr;
    ldr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
    ldr->Flags |= 0x20;

    pDriverObj->DriverUnload = DriverUnLoad;

    InitHook();
    return STATUS_SUCCESS;
}

//比较完善的代码

代码语言:javascript
复制
#define PROCESS_TERMINATE (0x0001)
#define PROCESS_CREATE_THREAD (0x0002)
#define PROCESS_SET_SESSIONID (0x0004)
#define PROCESS_VM_OPERATION (0x0008)
#define PROCESS_VM_READ (0x0010)
#define PROCESS_VM_WRITE (0x0020)
#define PROCESS_DUP_HANDLE (0x0040)
#define PROCESS_CREATE_PROCESS (0x0080)
#define PROCESS_SET_QUOTA (0x0100)
#define PROCESS_SET_INFORMATION (0x0200)
#define PROCESS_QUERY_INFORMATION (0x0400)
#define PROCESS_SUSPEND_RESUME (0x0800)
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
#define PROCESS_SET_LIMITED_INFORMATION (0x2000)

注意卸载:ObUnRegisterCallbacks(obHandle);
NTSTATUS ProtectProcess()
{
	OB_CALLBACK_REGISTRATION obReg;
	OB_OPERATION_REGISTRATION opReg;
	memset(&obReg, 0, sizeof(obReg));
	obReg.Version = ObGetFilterVersion();
	obReg.OperationRegistrationCount = 1;
	obReg.RegistrationContext = NULL;
	RtlInitUnicodeString(&obReg.Altitude, L"321000");
	memset(&opReg, 0, sizeof(opReg));
	opReg.ObjectType = PsProcessType;
	opReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
	opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&preCall;
	obReg.OperationRegistration = &opReg;
	return ObRegisterCallbacks(&obReg, &obHandle);
}
OB_PREOP_CALLBACK_STATUS preCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pOperationInformation)
{
	HANDLE pid = PsGetProcessId((PEPROCESS)pOperationInformation->Object);
	if (pid == PID)
	{
		if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
		{
			if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_TERMINATE)
				pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_TERMINATE);
			if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_VM_OPERATION)
				pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_VM_OPERATION);
			if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_VM_READ)
				pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_VM_READ);
			if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_VM_WRITE)
				pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_VM_WRITE);
			if (pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess & PROCESS_SUSPEND_RESUME)
				pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= (~PROCESS_SUSPEND_RESUME);
		}
		if (pOperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)
		{
			if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_TERMINATE)
				pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_TERMINATE);
			if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_VM_OPERATION)
				pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_VM_OPERATION);
			if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_VM_READ)
				pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_VM_READ);
			if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_VM_WRITE)
				pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_VM_WRITE);
			if (pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess & PROCESS_SUSPEND_RESUME)
				pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= (~PROCESS_SUSPEND_RESUME);
		}
	}
	return OB_PREOP_SUCCESS;
}

三丶BlockBone代码实现

其实这个代码在BlockBone中已经实现了。

代码如下:

首先定义需要的结构

代码语言:javascript
复制
#define EX_ADDITIONAL_INFO_SIGNATURE (ULONG_PTR)(-2)
typedef union _EXHANDLE
{
    struct
    {
        int TagBits : 2;
        int Index : 30;
    } u;
    void * GenericHandleOverlay;
    ULONG_PTR Value;
} EXHANDLE, *PEXHANDLE;

typedef struct _HANDLE_TABLE
{
    ULONG NextHandleNeedingPool;
    long ExtraInfoPages;
    LONG_PTR TableCode;
    PEPROCESS QuotaProcess;
    LIST_ENTRY HandleTableList;
    ULONG UniqueProcessId;
    ULONG Flags;
    EX_PUSH_LOCK HandleContentionEvent;
    EX_PUSH_LOCK HandleTableLock;
    // More fields here...
} HANDLE_TABLE, *PHANDLE_TABLE;

typedef struct _HANDLE_TABLE_ENTRY // Size=16
{
    union
    {
        ULONG_PTR VolatileLowValue; // Size=8 Offset=0
        ULONG_PTR LowValue; // Size=8 Offset=0
        struct _HANDLE_TABLE_ENTRY_INFO * InfoTable; // Size=8 Offset=0
        struct
        {
            ULONG_PTR Unlocked : 1; // Size=8 Offset=0 BitOffset=0 BitCount=1
            ULONG_PTR RefCnt : 16; // Size=8 Offset=0 BitOffset=1 BitCount=16
            ULONG_PTR Attributes : 3; // Size=8 Offset=0 BitOffset=17 BitCount=3
            ULONG_PTR ObjectPointerBits : 44; // Size=8 Offset=0 BitOffset=20 BitCount=44
        };
    };
    union
    {
        ULONG_PTR HighValue; // Size=8 Offset=8
        struct _HANDLE_TABLE_ENTRY * NextFreeHandleEntry; // Size=8 Offset=8
        union _EXHANDLE LeafHandleValue; // Size=8 Offset=8
        struct
        {
            ULONG GrantedAccessBits : 25; // Size=4 Offset=8 BitOffset=0 BitCount=25
            ULONG NoRightsUpgrade : 1; // Size=4 Offset=8 BitOffset=25 BitCount=1
            ULONG Spare : 6; // Size=4 Offset=8 BitOffset=26 BitCount=6
        };
    };
    ULONG TypeInfo; // Size=4 Offset=12
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;


/// <summary>
/// Input for IOCTL_BLACKBONE_GRANT_ACCESS
/// </summary>
typedef struct _HANDLE_GRANT_ACCESS
{
    ULONGLONG  handle;      // Handle to modify
    ULONG      pid;         // Process ID
    ULONG      access;      // Access flags to grant
} HANDLE_GRANT_ACCESS, *PHANDLE_GRANT_ACCESS;

#define IOCTL_BLACKBONE_GRANT_ACCESS   (ULONG)CTL_CODE(FILE_DEVICE_BLACKBONE, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define STATUS_WAIT_0                           ((NTSTATUS)0x00000000L) // winnt

typedef BOOLEAN(*EX_ENUMERATE_HANDLE_ROUTINE)(
#if !defined(_WIN7_)
    IN PHANDLE_TABLE HandleTable,
#endif
    IN PHANDLE_TABLE_ENTRY HandleTableEntry,
    IN HANDLE Handle,
    IN PVOID EnumParameter
    );

extern "C" NTKERNELAPI
BOOLEAN
ExEnumHandleTable(
    IN PHANDLE_TABLE HandleTable,
    IN EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
    IN PVOID EnumParameter,
    OUT PHANDLE Handle
);

extern "C" NTKERNELAPI
VOID
FASTCALL
ExfUnblockPushLock(
    IN OUT PEX_PUSH_LOCK PushLock,
    IN OUT PVOID WaitBlock
);

#define ExpIsValidObjectEntry(Entry) \
    ( (Entry != NULL) && (Entry->LowValue != 0) && (Entry->HighValue != EX_ADDITIONAL_INFO_SIGNATURE) )

核心代码如下:

代码语言:javascript
复制
/// <summary>
/// Check if process is terminating
/// </summary>
/// <param name="imageBase">Process</param>
/// <returns>If TRUE - terminating</returns>
BOOLEAN BBCheckProcessTermination(PEPROCESS pProcess)
{
    LARGE_INTEGER zeroTime = { 0 };
    return KeWaitForSingleObject(pProcess, Executive, KernelMode, FALSE, &zeroTime) == STATUS_WAIT_0;
}


/// <summary>
/// Handle enumeration callback
/// </summary>
/// <param name="HandleTable">Process handle table</param>
/// <param name="HandleTableEntry">Handle entry</param>
/// <param name="Handle">Handle value</param>
/// <param name="EnumParameter">User context</param>
/// <returns>TRUE when desired handle is found</returns>
BOOLEAN BBHandleCallback(
#if !defined(_WIN7_)
    IN PHANDLE_TABLE HandleTable,
#endif
    IN PHANDLE_TABLE_ENTRY HandleTableEntry,
    IN HANDLE Handle,
    IN PVOID EnumParameter
)
{

    BOOLEAN result = FALSE;
    ASSERT(EnumParameter);

    if (EnumParameter != NULL)
    {
        PHANDLE_GRANT_ACCESS pAccess = (PHANDLE_GRANT_ACCESS)EnumParameter;
        if (Handle == (HANDLE)pAccess->handle)
        {
            if (ExpIsValidObjectEntry(HandleTableEntry))
            {
                // Update access
                HandleTableEntry->GrantedAccessBits = pAccess->access;
                result = TRUE;
            }
            else
            {

            }
        }
    }

#if !defined(_WIN7_)
    // Release implicit locks
    _InterlockedExchangeAdd8((char*)&HandleTableEntry->VolatileLowValue, 1);  // Set Unlocked flag to 1
    if (HandleTable != NULL && HandleTable->HandleContentionEvent)
        ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL);
#endif

    return result;
}

/// <summary>
/// Change handle granted access
/// </summary>
/// <param name="pAccess">Request params</param>
/// <returns>Status code</returns>
NTSTATUS BBGrantAccess(IN PHANDLE_GRANT_ACCESS pAccess)
{
    NTSTATUS status = STATUS_SUCCESS;
    PEPROCESS pProcess = NULL;


    status = PsLookupProcessByProcessId((HANDLE)pAccess->pid, &pProcess);
    if (NT_SUCCESS(status) && BBCheckProcessTermination(pProcess))
        status = STATUS_PROCESS_IS_TERMINATING;

    if (NT_SUCCESS(status))
    {
        PHANDLE_TABLE pTable = *(PHANDLE_TABLE*)((PUCHAR)pProcess + 0x418);/*自己根据系统寻找每个EPROCESS的OBJECTTABLE偏移*/
        BOOLEAN found = ExEnumHandleTable(pTable, &BBHandleCallback, pAccess, NULL);
        if (found == FALSE)
            status = STATUS_NOT_FOUND;
    }
    else
    {

    }

    if (pProcess)
        ObDereferenceObject(pProcess);

    return status;
}

使用方式同上。可以指定进程,然后指定这个进程的一个句柄,将这个句柄提权。

四丶效果图

可以看到 首先打印的HANDLE 然后进行首次关闭notepad. 因为保护驱动加载了,所以首次结束notepad是失败的。

然后尝试进行第二次结束notepad,此时会提示用户按任意键继续,在等待用户按任意键的时候先把提权驱动加载上,此时返回用户程序按任意键继续。

继续之后就会结束被保护的进程。

五 丶 突破游戏保护

本文以常规方式进行演示的,知道原理了那么自己突破应该明白了吧。(注入没有Open的权限Write的权限Virtual的权限,那么可以提权再用有权的句柄进行操作。。)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • windows内核提权,又一突破游戏保护的方式。
    • 一丶 句柄表
      • 1.1 介绍
      • 1.2 原理
    • 二丶代码演示
      • 2.1 核心提权驱动代码
      • 2.2 用户程序以及使用说明例子
      • 2.3 进程保护驱动Demo源码
    • 三丶BlockBone代码实现
      • 四丶效果图
        • 五 丶 突破游戏保护
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档