PG2 BYPASS源码阅读 学习x64解密定时器、特征码定位
来源:互联网 发布:电子地图数据规范 编辑:程序博客网 时间:2024/04/29 10:37
以前没有接触过x64内核编程,借这份代码来学习一下,源码 http://www.codeproject.com/Articles/28318/Bypassing-PatchGuard-3
之前说到过PG3的一些机制,下面根据源码回顾一下
PG可能会queue一些dpc来触发syscheck,其中dpc context传入的是非传统地址,从而触发异常,转到异常处理去执行PG。
所以要判断dpc context
BOOLEAN CheckSubValue(ULONGLONG InValue){ULONGi;ULONGResult;UCHAR*Chars = (UCHAR*)&InValue;// random values will have a result around 120...Result = 0;for(i = 0; i < 8; i++){Result += ((Chars[i] & 0xF0) >> 4) + (Chars[i] & 0x0F);}// the maximum value is 240, so this should be safe...if(Result < 70)return TRUE;return FALSE;}BOOLEAN PgIsPatchGuardContext(void* Ptr){ULONGLONGValue = (ULONGLONG)Ptr;UCHAR*Chars = (UCHAR*)&Value;LONGi;// this is a requirement for a canonical pointer...//合法地址if((Value & 0xFFFF000000000000) == 0xFFFF000000000000)return FALSE;//0 也不是非法的if((Value & 0xFFFF000000000000) == 0)return FALSE;// sieve out other common values...//检测随机数?if(CheckSubValue(Value) || CheckSubValue(~Value))return FALSE;if(Ptr == NULL)return FALSE;//This must be the last check and filters latin-char UTF16 strings...//检测字符串for(i = 7; i >= 0; i -= 2){if(Chars[i] != 0)return TRUE;}// this should only return true if the pointer is a unicode string!!!return FALSE;}
这个检测还是考虑了不少情况,接下来是获得dpc加密key的方法
NTSTATUS PgInitialize(){void*SymbolArray[MAX_SYMBOL_COUNT];void*ValidationArray[MAX_SYMBOL_COUNT];void*IntersectionArray[MAX_SYMBOL_COUNT];ULONGiSymbol;ULONGIndex;ULONGMatchCount;KTIMERTestTimer;KDPCTestTimerDpc;LARGE_INTEGERTimerDueTime = {0};ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);/*Extract and validate methods...搜索同步用的未导出api,还是很谨慎的,用KeCancelTimer和KeSetTimerEx对比进行定位*/if(!ExtractSymbolAddresses((void*)KeCancelTimer, FALSE, 0xE8, OUT SymbolArray) ||!ExtractSymbolAddresses((void*)KeSetTimerEx, FALSE, 0xE8, OUT ValidationArray))return STATUS_NOT_SUPPORTED;if(IntersectSymbolAddresses(SymbolArray, ValidationArray, OUT IntersectionArray) != 5)return STATUS_NOT_SUPPORTED;KiAcquireDispatcherLockRaiseToSynch = IntersectionArray[0];KeAcquireQueuedSpinLockAtDpcLevel = IntersectionArray[1];KeReleaseQueuedSpinLockFromDpcLevel = IntersectionArray[2];KiReleaseDispatcherLockFromSynchLevel = IntersectionArray[3];KiExitDispatcher = IntersectionArray[4];/*Extract KiTimerTableListHead...*/if(!ExtractSymbolAddresses((void*)KeCancelTimer, TRUE, 0x8D48, OUT SymbolArray))return STATUS_NOT_SUPPORTED;if(!ExtractSymbolAddresses((void*)KeSetTimerEx, TRUE, 0x8D48, OUT ValidationArray))return STATUS_NOT_SUPPORTED;MatchCount = IntersectSymbolAddresses(SymbolArray, ValidationArray, OUT IntersectionArray);for(iSymbol = 0; iSymbol < MatchCount; iSymbol++){if(ValidateTimerTable(IntersectionArray[iSymbol])){// check if we found ambiguous symbol referencesKiTimerTableListHead = IntersectionArray[iSymbol];break;}}if(KiTimerTableListHead == NULL)return STATUS_NOT_SUPPORTED;/*Create test timer...We use a well known, probably unique DeferredContext for later identification...*/KeInitializeTimer(&TestTimer);KeInitializeDpc(&TestTimerDpc, OnTestTimerInvokation, (void*)PgInitialize);__try{KeSetTimerEx(&TestTimer, TimerDueTime, 10000, &TestTimerDpc);/*Extract KiWaitAlways and KiWaitNever一个特征码找到这两个值,然后验证*/if(!ExtractSymbolAddresses((void*)KeSetTimerEx, TRUE, 0x8B48, OUT SymbolArray))return STATUS_NOT_SUPPORTED;for(iSymbol = 0; iSymbol < MAX_SYMBOL_COUNT; iSymbol++){if(SymbolArray[iSymbol] == NULL)break;for(Index = 0; Index < MAX_SYMBOL_COUNT; Index++){if(SymbolArray[Index] == NULL)break;if(iSymbol == Index)continue;if(!ProbeAndSetKeys(&TestTimer,(ULONGLONG*)SymbolArray[iSymbol],(ULONGLONG*)SymbolArray[Index]))continue;return STATUS_SUCCESS;}}return STATUS_NOT_SUPPORTED;}__finally{// cleanup resourcesKeCancelTimer(&TestTimer);}}
PG2非常简单,直接摘掉dpc了事
BOOLEAN PgDisablePatchGuard(PDEVICE_OBJECT InDevice){KIRQLOldIrql;ULONGIndex;PKSPIN_LOCK_QUEUELockQueue;PKTIMER_TABLE_ENTRYTimerListHead;PLIST_ENTRYTimerList;PKTIMERTimer;PKDPCTimerDpc;/*Lock the dispatcher database and loop through the timer list...We will cancel all timers that have a non-canonical DeferredContext.*/OldIrql = KiAcquireDispatcherLockRaiseToSynch();for(Index = 0; Index < TIMER_TABLE_SIZE; Index++){LockQueue = KeTimerIndexToLockQueue((UCHAR)(Index & 0xFF));KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);// now we can work with the timer list...TimerListHead = &KiTimerTableListHead[Index];TimerList = TimerListHead->Entry.Flink;while(TimerList != (PLIST_ENTRY)TimerListHead){// is DPC patched?Timer = CONTAINING_RECORD(TimerList, KTIMER, TimerListEntry);TimerList = TimerList->Flink;TimerDpc = PgDeobfuscateTimerDpc(Timer);if(TimerDpc == NULL)continue;if(PgIsPatchGuardContext(TimerDpc->DeferredContext) && KeContainsSymbol(TimerDpc->DeferredRoutine)){// this will cancel the timer...Timer->Header.Inserted = FALSE;if(RemoveEntryList(&Timer->TimerListEntry))TimerListHead->Time.HighPart = 0xFFFFFFFF;}}KeReleaseQueuedSpinLockFromDpcLevel(LockQueue);}KiReleaseDispatcherLockFromSynchLevel();KiExitDispatcher(OldIrql);return TRUE;}
- PG2 BYPASS源码阅读 学习x64解密定时器、特征码定位
- pg3 bypass源码阅读 —— 学习x64内核hook跳板技术
- 易语言特征码定位工具源码
- MyCCL特征码定位原理学习
- MyCCL特征码定位原理学习
- C++特征码定位
- train_cascade 源码阅读之LBP特征
- train_cascade 源码阅读之Haar特征
- train _cascade 源码阅读之HOG特征
- train_cascade 源码阅读之Haar特征
- train_cascade 源码阅读之LBP特征
- train _cascade 源码阅读之HOG特征
- skynet底层源码阅读(6)-定时器
- bypass csp学习
- Spring源码阅读-- IOC容器资源定位
- spring 源码阅读学习
- nginx源码阅读(十二).定时器及超时事件的管理
- 百度地图定位源码学习
- 利用QT中Qpainter画点,直线,弧线等简单图形
- 浅谈 sencha 2.0 中image和carousel的图片自适应大小的应用
- CuteFTP XP 5.0.2 简体中文版序列号破解
- JNI— 让C++和Java相互调用
- 暑假学习计划
- PG2 BYPASS源码阅读 学习x64解密定时器、特征码定位
- poj-3159很神奇的一题-差分约束+spfa
- linux ntpd
- 综合整理了自己收藏的php几类常用函数
- IOS视频压缩
- 顺时针打印矩阵 (JAVA实现)
- ORA-00257: 归档程序错误。在释放之前仅限于内部连接
- 高尔夫球场难度Course rating 和斜度slope rating
- Git学习笔记4 找出最懒的程序员