-
-
[原创]X64 REMOVE PSPCIDTABLE
-
发表于: 2015-8-26 21:07 6067
-
不废话 直接防码
补充代码有网了:【分享】x64 antidebug 不触发PG http://bbs.pediy.com/showthread.php?p=1385028#post1385028
有个BUG 如果 移出的目标有线程退出 那么 我的 系统线程就挂了 目测是枚举函数的 问题
这个 我就 不解决了 退出不蓝屏
因为 有 了新的 解决办法 这个 就扔掉了
#include "ntddk.h"
#include "commonfunc.h"
#define IMAGE_FILENAME_OFFSET 0x2e0
VOID startthread();
VOID stopthread();
KEVENT event;
HANDLE systemthreadhandle;
KTIMER cleartimer= { 0 };
KDPC cleardpc = { 0 };
BOOLEAN REMOVING = FALSE;
typedef struct _HANDLE_TABLE_ENTRY{
union{
VOID* Object;
ULONG32 ObAttributes;
PVOID64 InfoTable;
ULONG64 Value;
};
union{
ULONG32 GrantedAccess;
struct{
UINT16 GrantedAccessIndex;
UINT16 CreatorBackTraceIndex;
UINT8 _PADDING[0x4];
};
ULONG32 NextFreeTableEntry;
};
}HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
typedef struct _save_handlentry{
struct _save_handlentry*head;
PVOID id;
char processname[17];
ULONG64 value;
ULONG32 GrantedAccess;
struct HANDLE_TABLE_ENTRY*address;
struct _save_handlentry*next;
}_save_handlentry, *p_save_handlentry;
ULONG64 SreachFunctionAddress(ULONG64 uAddress, UCHAR *Signature, ULONG addopcodelength, ULONG addopcodedatasize);
p_save_handlentry createlist(char*processname){
ULONG i;
p_save_handlentry phead = (p_save_handlentry) ExAllocatePool(NonPagedPool,sizeof(_save_handlentry));
p_save_handlentry ptail = phead;
ptail->next = NULL;
p_save_handlentry pnew = (p_save_handlentry)ExAllocatePool(NonPagedPool, sizeof(_save_handlentry));
memcpy(&pnew->processname, processname, 16);
pnew->address = 0;
pnew->id = 0;
pnew->value = 0;
pnew->GrantedAccess = 0;
pnew->head = NULL;
ptail->next = pnew;
pnew->next = NULL;
ptail->head = NULL;
return phead;
}
// 插入链表
p_save_handlentry insertlist(char*processname, ULONG GrantedAccess, ULONG64 value, PVOID id, PHANDLE_TABLE_ENTRY adress, p_save_handlentry phead){
p_save_handlentry p = phead->next;
while (p != NULL)
{
if (p->next == NULL){
break;
}
p = p->next;
}
p_save_handlentry pnew = (p_save_handlentry)ExAllocatePool(NonPagedPool, sizeof(_save_handlentry));
memcpy(&pnew->processname, processname, 16);
pnew->GrantedAccess = GrantedAccess;
pnew->id = id;
pnew->value = value;
pnew->address = adress;
p->next = pnew;
pnew->next = NULL;
pnew->head = p;
return pnew;
}
p_save_handlentry querylist(p_save_handlentry phead, ULONG64 id){
p_save_handlentry p = phead->next;
while (p != NULL)
{
if (p->id == id){
return p;
}
p = p->next;
}
return NULL;
}
//删除节点
void deletelist(p_save_handlentry pclid){
p_save_handlentry p, pp;
if (pclid->head != NULL){//头部
p = pclid->head;
pp = pclid->next;
if (pp == NULL){//最后节点
p->next = NULL;
ExFreePool(pclid);
return;
}
p->next = pp;//不是最后节点
pp->head = p;
ExFreePool(pclid);
return;
}
}
typedef NTSTATUS(__fastcall * pfnEnumObjectTable)(PVOID64 HANDLETABLE, PVOID CALLback, ULONG64 unKonw);
NTKERNELAPI CHAR* PsGetProcessImageFileName(PEPROCESS Process);
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
NTKERNELAPI NTSTATUS PsLookupThreadByThreadId(HANDLE Id, PETHREAD *Thread);
NTKERNELAPI PEPROCESS IoThreadToProcess(PETHREAD Thread);
pfnEnumObjectTable EnumObjectTablex = 0;;
PVOID64 PspCidTable=0;
NTSTATUS getenumhandletablefunc()
{
UCHAR opcode[5] = { 0x89, 0x6c, 0x24, 0x30, 0xe8 };
UCHAR opcode1[5] = { 0xdc, 0x48, 0x8b, 0xd1, 0x48 };
UNICODE_STRING64 ObFindHandleForObjectsign;
ULONG64 temp64 = 0;
NTSTATUS state = STATUS_SUCCESS;
RtlInitUnicodeString(&ObFindHandleForObjectsign, L"ObFindHandleForObject");//ObFindHandleForObject PAGE 0000000140319DB0 000000B4 00000048 00000028 R . . . . . .
temp64 = (ULONG64)MmGetSystemRoutineAddress(&ObFindHandleForObjectsign);
if (!MmIsAddressValid(temp64))
return state;
EnumObjectTablex = (pfnEnumObjectTable)SreachFunctionAddress(temp64, opcode,1,5);
PspCidTable = (PVOID64)SreachFunctionAddress(&PsLookupProcessByProcessId, opcode1, 3, 7);
PspCidTable = *(PVOID64*)PspCidTable;
if (!MmIsAddressValid(EnumObjectTablex) || !MmIsAddressValid(PspCidTable)){
DbgPrint("cant get EnumObjectTablex or PspCidTable \n");
}
DbgPrint("Super game protect start~\n");
}
p_save_handlentry mainphead = NULL;
PVOID64 psidprocessobject = 0;
PVOID64 pscidkthreadbject = 0;
ULONG64 passmaska = TRUE;
#define de_o -10
#define de_s de_o*1000
LARGE_INTEGER myxx;
VOID clearDEBUGTOOL(){
myxx.QuadPart = de_s;
myxx.QuadPart *= 2000;
while (passmaska==TRUE)
{
KeDelayExecutionThread(KernelMode, 0, &myxx);
if (REMOVING)
continue;
enumtable(2);
if (psidprocessobject!=0 ){
DbgPrint("clear psidprocessobject %p", *(ULONG64*)psidprocessobject);
*(ULONG64*)psidprocessobject = 0;
DbgPrint("clear psidprocessobject %p", *(ULONG64*)psidprocessobject);
psidprocessobject = 0;
}
DbgPrint("clearing...");
if (pscidkthreadbject != 0){
DbgPrint("clear pscidkthreadbject %p", *(ULONG64*)pscidkthreadbject);
*(ULONG64*)pscidkthreadbject = 0;
DbgPrint("clear pscidkthreadbject %p", *(ULONG64*)pscidkthreadbject);
pscidkthreadbject = 0;
}
continue;
}
DbgPrint("ending...");
KeSetEvent(&event, 0, TRUE);
}
BOOLEAN removdebugtoolhandle(PHANDLE_TABLE_ENTRY object, PHANDLE handle, ULONG64 Unkonw){
ULONG64 Pobject;
ULONG64 object_header;
ULONG32 object_type;
p_save_handlentry paddress;
Pobject = (object->Value)&~7;
object_header = Pobject - 0x30;//getobjectheader
object_type = (ULONG32)*(UINT8*)(object_header + 0x18);//pspcidtable object_header
if (!MmIsAddressValid(Pobject))
{
return FALSE;//is true
}
if ( object_type == 7 ){
if (strstr(PsGetProcessImageFileName(Pobject), "天网系统") != NULL || strstr(PsGetProcessImageFileName(Pobject), "cheatengine") != NULL || strstr(PsGetProcessImageFileName(Pobject), "ollyice") != NULL){
paddress = insertlist(Pobject + IMAGE_FILENAME_OFFSET, object->GrantedAccess, object->Value, handle, &object->Value, mainphead);
DbgPrint("process is look~");
psidprocessobject = &object->Value;
}
return FALSE;
}
if ( object_type == 8 ){
ULONG64 tempprocess;
tempprocess = IoThreadToProcess(Pobject);
if (strstr(PsGetProcessImageFileName(tempprocess), "天网系统") != NULL || strstr(PsGetProcessImageFileName(tempprocess), "cheatengine") != NULL || strstr(PsGetProcessImageFileName(tempprocess), "ollyice") != NULL ){
DbgPrint("thread is look~");
paddress = insertlist(Pobject + IMAGE_FILENAME_OFFSET, object->GrantedAccess, object->Value, handle, &object->Value, mainphead);
pscidkthreadbject = &object->Value;
}
return FALSE;
}
return FALSE;
}
BOOLEAN removepspcidtabl(HANDLE p){
if (PspCidTable == 0 || EnumObjectTablex == 0){
getenumhandletablefunc();
}
if (mainphead==NULL){
mainphead = createlist("system");
}
EnumObjectTablex(PspCidTable, removdebugtoolhandle, p);
}
PCREATE_PROCESS_NOTIFY_ROUTINE callback(HANDLE prid, HANDLE pid, BOOLEAN create){
ULONG64 EPROCESS;
PHANDLE_TABLE_ENTRY phdt;
p_save_handlentry tempsave;
EPROCESS = IoGetCurrentProcess();
if (!create && (strstr(PsGetProcessImageFileName(EPROCESS), "天网系统") != NULL || strstr(PsGetProcessImageFileName(EPROCESS), "cheatengine") != NULL || strstr(PsGetProcessImageFileName(EPROCESS), "ollyice") != NULL)){
REMOVING = TRUE;
tempsave = querylist(mainphead, pid);
if (tempsave != 0){
phdt = tempsave->address;
//phdt->GrantedAccess = tempsave->GrantedAccess;
phdt->Value = tempsave->value;
DbgPrint("pid %d pt:%p phdt:%p", tempsave->id, tempsave->address, phdt->Object);
//deletelist(tempsave);
stopthread();
startthread();
}
// ObDereferenceObject(leprocess);
REMOVING = FALSE;
}
}
PCREATE_THREAD_NOTIFY_ROUTINE callback2(HANDLE processid, HANDLE threadid, BOOLEAN create){
ULONG64 EPROCESS;
PHANDLE_TABLE_ENTRY phdt;
p_save_handlentry tempsave;
EPROCESS = IoGetCurrentProcess();
if(!create && (strstr(PsGetProcessImageFileName(EPROCESS), "天网系统") != NULL || strstr(PsGetProcessImageFileName(EPROCESS), "cheatengine") != NULL || strstr(PsGetProcessImageFileName(EPROCESS), "ollyice") != NULL)){
REMOVING = TRUE;
tempsave = querylist(mainphead, threadid);
if (tempsave != 0){
phdt = tempsave->address;
//phdt->GrantedAccess = tempsave->GrantedAccess;
phdt->Value = tempsave->value;
DbgPrint("tid %d pt:%p phdt:%p", tempsave->id, tempsave->address, phdt->Object);
// deletelist(tempsave);
stopthread();
startthread();
}
REMOVING = FALSE;
}
}
VOID startthread(){
KeInitializeEvent(
&event,
SynchronizationEvent,//SynchronizationEvent为同步事件
FALSE// 当是TRUE 时初始化事件是有信号状态.,当是FALSE时初始化事件是没信号状态,如果此处为TRUE,则为有信号状态,KeWaitForSingleObject会直接通过,此时需要调用KeResetEvent来设置为无信号
);
PsCreateSystemThread(&systemthreadhandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, clearDEBUGTOOL, NULL);
}
VOID stopthread(){
ZwClose(systemthreadhandle);
}
/////////////////////////////////////
VOID clearprocessinformationRoutine(
_In_ struct _KDPC *Dpc,
_In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2
)
{
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(DeferredContext);
UNREFERENCED_PARAMETER(SystemArgument1);
UNREFERENCED_PARAMETER(SystemArgument2);
LARGE_INTEGER lTime = { 0 };
ULONG ulMicroSecond = 0;
KIRQL irql;
//将定时器的时间设置为500ms
ulMicroSecond = 5000000;
//将32位整数转化成64位整数
lTime = RtlConvertLongToLargeInteger(-10 * ulMicroSecond);
enumtable(2);
KeSetTimer(&cleartimer, lTime, &cleardpc);
}
BOOLEAN bTimerStart = FALSE;
VOID startdpc(){
// DPC定时器是否开启标志
LARGE_INTEGER lTime = { 0 };
ULONG ulMicroSecond = 0;
// 初始化定时器
KeInitializeTimer(&cleartimer);
// 初始化DPC
KeInitializeDpc(&cleardpc, clearprocessinformationRoutine, NULL);
// 开始定时器
//将定时器的时间设置为500ms
ulMicroSecond = 5000000;
//将32位整数转化成64位整数
lTime = RtlConvertLongToLargeInteger(-10 * ulMicroSecond);
bTimerStart = KeSetTimer(&cleartimer, lTime, &cleardpc);
if (bTimerStart)
{
DbgPrint("定时器开启成功\n");
}
}
VOID stopdpc(){
if (bTimerStart)
KeCancelTimer(&cleartimer);
}
//////////////////////////////////////////
void protectprocessforpspcidtable(){
if (mainphead==NULL)
{
mainphead = createlist("system");
}
PsSetCreateProcessNotifyRoutine(callback, FALSE);
PsSetCreateThreadNotifyRoutine(callback2);
// startdpc();
startthread();
}
void unprotectprocessforpspcidtable(){
passmaska = FALSE;
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
PsSetCreateProcessNotifyRoutine(callback, TRUE);
PsRemoveCreateThreadNotifyRoutine(callback2);
//stopdpc();
stopthread();
}
void enumtable(PHANDLE handle){
if (PspCidTable == 0 || EnumObjectTablex == 0){
getenumhandletablefunc();
}
if (mainphead == NULL){
mainphead = createlist("system");
}
EnumObjectTablex(PspCidTable, removdebugtoolhandle, handle);
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [原创]PatchGuard自效验粗略分析 18055
- [讨论]PUBG 2018.3.9更新的代码页防止更改 19527
- [原创]VT调试器 X64 66632