windows内核提权,又一突破游戏进程保护的方法
windows内核提权,又一突破游戏保护的方式。
一丶 句柄表
1.1 介绍
当一个进程被保护
的时候 比如无法获取其进程句柄权限
(OpenProcess
) 或者无法获取内存读写访问权限的时候,则可以使用此方法来进行提权。
前置知识,了解windows系统句柄表的构成
。
可查看本博客链接:
x64windows内核句柄表PspCidTable原理与解析 - iBinary - 博客园 (cnblogs.com)
1.2 原理
句柄表项结构 HANDLE_TABLE_ENTRY
里面有一个成员记录了 当前句柄所需要得访问权限。
结构如下:
//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 核心提权驱动代码
核心驱动代码很简单。
如下:
#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 用户程序以及使用说明例子
用户层面演示例子:
// 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源码
#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; }
//比较完善的代码
#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中已经实现了。
代码如下:
首先定义需要的结构
#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) )
核心代码如下:
/// <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的权限,那么可以提权再用有权的句柄进行操作。。)
坚持两字,简单,轻便,但是真正的执行起来确实需要很长很长时间.当你把坚持两字当做你要走的路,那么你总会成功. 想学习,有问题请加群.群号:725864912(收费)群名称: 逆向学习小分队 群里有大量学习资源. 以及定期直播答疑.有一个良好的学习氛围. 涉及到外挂反外挂病毒 司法取证加解密 驱动过保护 VT 等技术,期待你的进入。
详情请点击链接查看置顶博客 https://www.cnblogs.com/iBinary/p/7572603.html
本文来自博客园,作者:iBinary,未经允许禁止转载 转载前可联系本人.对于爬虫人员来说如果发现保留起诉权力.https://www.cnblogs.com/iBinary/p/16284728.html
欢迎大家关注我的微信公众号.不定期的更新文章.更新技术. 关注公众号后请大家养成 不白嫖的习惯.欢迎大家赞赏. 也希望在看完公众号文章之后 不忘 点击 收藏 转发 以及点击在看功能. QQ群:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 欧阳的2024年终总结,迷茫,重生与失业
· 在 .NET 中使用 Tesseract 识别图片文字
· Bolt.new 30秒做了一个网站,还能自动部署,难道要吊打 Cursor?
· 史上最全的Cursor IDE教程
· 关于产品设计的思考