Windows X64 Patch Guard

先简单介绍下PatchGuard ,摘自百度百科

PatchGuard就是Windows Vista的内核保护系统,防止任何非授权软件试图“修改”Windows内核,也就是说,Vista内核的新型金钟罩。

PatchGuard为Windows Vista加入一个新安全操作层,此前我们为您介绍过的ASLR(Address Space Layout Randomization)亦在这个安全层之下。

PatchGuard能够有效防止内核驱动模式改动或替换Windows内核的任何内容,第三方软件将无法再给Windows Vista内核添加任何“补丁”。

就是微软从x64结构体系开始加的一层保护技术,对内核关键位置进行检测,如果发现内核关键位置被修改就直接蓝屏,而且在x64下还引入了DES,即驱动的加载需要数字签名。我们在x64下就无法在像x86下那样"为所欲为"了。比如x86下玩的超级Happy的重载内核在x64下基本不可能了,SSDT不能hook了,DebugPort不能清零了等等。但是在Win7 x64出来没多久 国外的大牛FYYRE就放出了内核破解工具,这里给出链接 http://fyyre.ivory-tower.de/   随后就有大牛公布了源代码,我也只是学习大牛的源代码,记录自己的学习历程。

先贴上FYYRE的原文

//Disable PatchGuard - the easy/lazy way.
//for Vista SP2 & Windows 7 (X64)
//
//by Fyyre (thank you Roxaz for helping me to test)
//http://fyyre.l2-fashion.de/
//http://twitter.com/Fyyre

last update: 19/03/2011

This txt file provides a general overview/outline for bypassing signature validation of critical system files (ntoskrnl, mainly) during
the Vista/Win 7 boot phase.  It is documentation of the steps taken from start to finish, to reach the desired goal of removing
kernel patch protection "PatchGuard" without use of a driver.  We will call this the ‘lazy/easy‘ way to kill PatchGuard.

We cannot modify ntoskrnl without winload taking up issue...

winload.exe is the Windows loader for Vista & Windows 7.  Along with this, he makes some verification of digital signatures and
checking to make sure the files have not been modified.  If modification of ntoskrnl is detected, the result is winload *refusing*
to boot Windows and launching a WinPE looking "Recovery Mode".

PART I { additional }: new way for patch of winload.exe

Function ImgpValidateImageHash - signature we locate: 8B C3 49 8B 5B 20 49 8B 73 28 49 8B 7B 30 4D 8B -- you may play with this one to make him smaller.  as for this
patching, use of dUP2... size of not a concern.  First bytes replaced with xor eax, eax (STATUS_SUCCESS) .. all validations successful.

PART I: disassembly and modification of winload.exe

Starting from OslpMain, after loading the System registry hives(registry)... occurs a call to OslInitializeCodeIntegrity:

.text:00000000004016C3                 call    OslpLoadSystemHive
.text:00000000004016C3
.text:00000000004016C8                 cmp     eax, ebx
.text:00000000004016CA                 mov     edi, eax
.text:00000000004016CC                 jl      loc_401A08
.text:00000000004016CC
.text:00000000004016D2                 mov     ecx, ebp
.text:00000000004016D4                 call    OslInitializeCodeIntegrity <<-- =(

.text:00000000004057E8 OslInitializeCodeIntegrity proc near

original code -->>

We will replace four bytes here:

48 8B C4 53
.text:00000000004057E8                 mov     rax, rsp
.text:00000000004057EB                 push    rbx
.text:00000000004057EC                 push    rbp

with: 0B0h, 01h, 0C3h, 090h ... which produce:

mov al, 1
ret
nop

Save as winload.exe as osloader.exe (or whatever..) & correct PE checksum (LordPE and/or CFF_Explorer will do).  Copy osloader.exe to \Windows\System32

PART II - new BCD entry:

bcdedit /copy {current} /d "PatchGuard Disabled"

"The entry was successfully copied to {01234567-89ab-cdef-00ff-fff000ffffff}" <<-- GUID of new entry.  each is different!

bcdedit /timeout 10 <<-- number of seconds to show boot menu.

bcdedit /set {01234567-89ab-cdef-00ff-fff000ffffff} nointegritychecks 1 <<-- no validation of winload

bcdedit /set {01234567-89ab-cdef-00ff-fff000ffffff} recoveryenabled 0 <<-- optional... i dislike this feature, therefore disable.

bcdedit /set {01234567-89ab-cdef-00ff-fff000ffffff} path \Windows\system32\osloader.exe

bcdedit /set {01234567-89ab-cdef-00ff-fff000ffffff} kernel ntkrnlmp.exe (name of modified ntos... =))

Part III: Skip Initialization of PatchGuard - - (driver not required)

As for this .txt, and PatchGuard... we are concerned with one function KiInitializePatchGuard(*1) which is called by KiFilterFiberContext.
KiInitializePatchGuard is a very large function located in the INIT section of ntoskrnl, you can easily locate him via two calls from
KiFilterFiberContext, by examination xrefs to exported dword InitSafeBootMode, searching for db 20h dup(90h) + db 044h ... or 48 81 EC 58 0F 00 00 to
name a few...

PatchGuard does not initialize if we boot into safe mode.  So to disable we just patch one conditional jxx

KiInitializePatchGuard:

original code -->>
INIT:000000014055D359 sub     rsp, 0F58h
INIT:000000014055D360 xor     edi, edi
INIT:000000014055D362 cmp     cs:InitSafeBootMode, edi
INIT:000000014055D368 jz      short loc_14055D371
INIT:000000014055D368
INIT:000000014055D36A mov     al, 1
INIT:000000014055D36C jmp     loc_1405600D9

modified code -->>
INIT:000000014055D359                 sub     rsp, 0F58h
INIT:000000014055D360                 xor     edi, edi
INIT:000000014055D362                 cmp     cs:InitSafeBootMode, edi
INIT:000000014055D368                 nop
INIT:000000014055D369                 nop
INIT:000000014055D36A                 mov     al, 1
INIT:000000014055D36C                 jmp     loc_1405600D9 <<-- to end of KiInitializePatchGuard

and back to KiFilterFiberContext... and important detail:

The first jxx in KiInitializePatchGuard must not be taken & al == 1.  When we return to KiFilterFiberContext, the jxx must be taken,
and EBX must not be xor‘d ... (unless enjoy BSOD).

INIT:0000000140567110 loc_140567110:
INIT:0000000140567110                 test    al, al
INIT:0000000140567112                 jnz     short loc_140567116
INIT:0000000140567112
INIT:0000000140567114
INIT:0000000140567114 loc_140567114:
INIT:0000000140567114                 xor     ebx, ebx <<-- bad
INIT:0000000140567114

Anyways... nop the first jxx in KiInitializePatchGuard... save modified ntoskrnl.exe with a different name (i.e. ntkrnlmp.exe) ... fix checksum (PE header).
Then copy your modified kernel to \Windows\system32 -- with bcdedit -->>

bcdedit /set {guid-of-new-entry} kernel ntkrnlmp.exe

When you reboot the system, loading your modified kernel should be a success... He will load without PatchGuard initializing, which will allow you to
once again play in kernel mode without receiving BSOD as result...

This could be worked into mbr bootkit code as well... this is beyond the scope of our intention.

-Fyyre

references:
*1: Bypassing PatchGuard on Windows x64, by Skywing 12/1/2005

根据文章我们先将winload.exe放入ida中,根据文章中定位到OslpMain函数(这里我已经导入了winload.exe的符号表)

.text:00000000004016BE 4C 8B C6          mov     r8, rsi
.text:00000000004016C1 8B CD             mov     ecx, ebp
.text:00000000004016C3 E8 94 04 00 00    call    OslpLoadSystemHive      //加载注册表单元
.text:00000000004016C8 3B C3             cmp     eax, ebx
.text:00000000004016CA 8B F8             mov     edi, eax
.text:00000000004016CC 0F 8C 36 03 00 00 jl      loc_401A08
.text:00000000004016D2 8B CD             mov     ecx, ebp
.text:00000000004016D4 E8 03 41 00 00    call    OslInitializeCodeIntegrity

发现加载了注册表单元之后调用了OslInitializeCodeIntegrity函数,我们继续跟进

原来的代码

.text:00000000004057DC                   OslInitializeCodeIntegrity proc near
.text:00000000004057DC 48 8B C4          mov     rax, rsp
.text:00000000004057DF 53                push    rbx
.text:00000000004057E0 55                push    rbp
.text:00000000004057E1 57                push    rdi
.text:00000000004057E2 41 54             push    r12

我们要做的就是替换掉最开始的一个字节,让整个函数不再向下执行,因为在接下来会调用BlImgQueryCodeIntegrityBootOptions,因为BlImgQueryCodeIntegrityBootOptioins会校验Ntoskrnl.exe的数字签名的有效性,如果非法的话就拒绝加载Ntoskrnl.exe,我们需要绕过这个函数

.text:00000000004057FB 48 8D 50 10       lea     rdx, [rax+10h]
.text:00000000004057FF 4C 89 68 20       mov     [rax+20h], r13
.text:0000000000405803 49 8B FD          mov     rdi, r13
.text:0000000000405806 4C 89 68 C8       mov     [rax-38h], r13
.text:000000000040580A E8 21 B6 02 00    call    BlImgQueryCodeIntegrityBootOptions

所以在OllInitializeCodeIntegrity 函数开始部分就直接返回,跳过BlImgQueryCodeIntegrityBootOptioins

将          48 8B C4          mov     rax, rsp 

替换成       B0 01             mov al , 1
            C3                ret 

接下来就是Ntoskrnl.exe了

根据文章中的说明,定位到KiFilterFiberContext函数,发现对KiInitializePatchGuard的调用

INIT:0000000140577106 8B D1             mov     edx, ecx
INIT:0000000140577108 41 8B C9          mov     ecx, r9d
INIT:000000014057710B E8 30 62 FF FF    call    KiInitializePatchGuard     //这里是我自己重命名了,本来的只是一个地址,符号表中没有

在KiInitializePathcGuard函数开始的地方就对启动模式进行了检测

NIT:000000014056D360 33 FF             xor     edi, edi
INIT:000000014056D362 39 3D 88 21 D1 FF cmp     cs:InitSafeBootMode, edi   //检测是否以安全模式启动,如果以安全模式启动PatchGuard就不会被初始化
INIT:000000014056D368 74 07             jz      short loc_14056D371        //这里的跳转才是对PatchGuard就行正在初始化,我们将其nop掉
INIT:000000014056D36A B0 01             mov     al, 1INIT:000000014056D36C E9 68 2D 00 00    jmp     loc_1405700D9              //直接跳转到KiInitilizePatchGuard函数的结尾,不初始化

然后就是保存,然后在启动项中添加我们自己的“内核”。

时间: 2024-11-10 15:14:13

Windows X64 Patch Guard的相关文章

Bypassing PatchGuard on Windows x64

[说明] 1.  本文是意译,加之本人英文水平有限.windows底层技术属菜鸟级别,本文与原文存在一定误差,请多包涵. 2.  由于内容较多,从word拷贝过来排版就乱了.故你也可以下载附件. 3.  如有不明白的地方,各位雪友可通过附件中的联系方式联系我,同时建议各位参照原文阅读...... [64位windows系统的PatchGuard] 原文:Bypassing PatchGuard on Windows x64.pdf 关于windows x64上的PatchGuard是干什么用的,

Gitlab客户端安装(for windows x64)

Gitlab客户端安装(for windows x64),下载附件

[转]判断程序是否运行在 Windows x64 系统下

以下功能代码判断是否运行在 Windows x64 下.本例使用 Windows API 函数 IsWow64Process,具体请参考MSDN文档:http://msdn.microsoft.com/en-us/library/ms684139(VS.85).aspx /** *   This program test if this application is a x64 program or *   is a x86 program running under Windows x64.

Oracle Fusion Applications (11.1.8) Media Pack and Oracle Application Development Framework 11g (11.1.1.7.2) for Microsoft Windows x64 (64-bit)

Oracle Fusion Applications (11.1.8) Media Pack for Microsoft Windows x64 (64-bit) 重新搜索   常见问题    提示      查看自述文件可帮助确定需要下载的文件. 请打印包含可下载文件列表的页面.该页面包含部件号列表,以及在安装过程中可能需要参考的相应说明. endv 您好!单击下载按钮即表示您同意使用此门户 上的软件所适用的 Oracle 条款和条件.不是 endv?请勿下载此软件并 使用您的帐户登录.END

深入理解Windows X64调试

随着64位操作系统的普及,都开始大力进军x64,X64下的调试机制也发生了改变,与x86相比,添加了许多自己的新特性,之前学习了Windows x64的调试机制,这里本着“拿来主义”的原则与大家分享. 本文属于译文,英文原文链接:http://www.codemachine.com/article_x64deepdive.html 翻译原文地址:深入Windows X64 调试 在正式开始这篇译文之前,译者先定义下面两个关于栈帧的翻译: frame pointer:栈帧寄存器.栈帧指针,在X86

关于安装oracle 11G R2 for Windows X64问题

下载地址: http://www.oracle.com/technetwork/cn/articles/112010-win64soft-094461.html #*特殊说明* #关于下载工具的使用:千万千万不要使用迅雷下载,至少我使用QQ旋风下载两个压缩包内的文件夹合并时不会出现需要替换的问题,如果出现需要替换,说明没有下载成功,并且如果你做了替换,在oracle创建数据库时,会出现报错. #关于两个压缩包的文件夹合并,将2of2内的database\stage\Components文件夹里面

win下编译ffmpeg库,Compile and build ffmpeg library and dll on Windows x64( 正版)

转载请注明:来自EricKing,thanks 从没想到编一个library这么坑爹,再次提醒各位百度的东西只能参考,想节约时间还是要到官网上去查看docum.不废话了,开始详细过程: ——>1.搭建Win下的GCC编译环境(因为win下vs不支持ffmpeg的compile 和build,官网上也有说这一点) ——>2.下载latest ffmpeg source(后面附官网地址),想办法将编译后的文件做成dll,这是win下编程调试的核心 (这里就用到vs下的一个vc的bash文件叫vcv

Windows X64汇编入门(1)

Windows X64汇编入门(1) tankaiha 最近断断续续接触了些64位汇编的知识,这里小结一下,一是阶段学习的回顾,二是希望对64位汇编新手有所帮助.我也是刚接触这方面知识,文中肯定有错误之处,大家多指正. 文章的标题包含了本文的四方面主要内容: (1)Windows:本文是在windows环境下的汇编程序设计,调试环境为Windows Vista 64位版,调用的均为windows API. (2)X64:本文讨论的是x64汇编,这里的x64表示AMD64和Intel的EM64T,

windows开启Zend Guard Loader证书配置

关于Zend Guard Loader也是很烦人的东西,安装的PHP自带有Zend,但是可能会没有Zend Guard Loader这个东西,你可以在自己的phpinfo中搜索guard看有没有zend guard这个东西,没有的话就需要重新安装了. 下载地址: http://www.zend.com/en/products/loader/downloads#Windows 下载的文件中包含: ZendLoader.dll.php_opcache.dll :同样放到 C:\wybsofts\ph