//.......花了几天时间 只是粗略调试分析,patchguard实在时太大了,
贫道无能 ,水平有限可能有不实之处。。
//..有时间应该还会继续调试 研究把
//此处感谢 大表哥 有人么的无私帮助。
//ed nt!Kd_SXS_Mask 0
//ed nt!Kd_FUSION_Mask 0
//.......
//Win10PG 负责解密PG执行的代码如果改了直接109
//PG context里面会清理Dr寄存器
//
sidt fword ptr [rbp+4E0h]
INITKDBG:00000001402DC129 lidt fword ptr [rbp+378h]
INITKDBG:00000001402DC130 mov dr7, rax
INITKDBG:00000001402DC133 lidt fword ptr [rbp+4E0h]
//
sidt fword ptr [rbp+4E0h]
INITKDBG:00000001402DC129 lidt fword ptr [rbp+378h]
INITKDBG:00000001402DC130 mov dr7, rax
INITKDBG:00000001402DC133 lidt fword ptr [rbp+4E0h]
//调试pgcontext用VT禁用Noimage内存写入DR和调用lidt指令 ,然后用硬件断点寄存器 来调试
//pg里面有些地方跟踪很容易挂掉 暂且不提
//关于自效验如下 :
算法有很多 贴一个 大概都是这种
mov rax, [r9] ; Vu=*ULONG_PTR *Pg[0]
INITKDBG:00000001402DC29C mov ecx, r11d ; 可能计算的范围?
INITKDBG:00000001402DC29F xor rax, r8 ; Vu=^
Vu2
INITKDBG:00000001402DC2A2 mov r8, [r9+8] ; Vu2=*ULONG_PTR *Pg[1]
INITKDBG:00000001402DC2A6 rol rax, cl ; rol(Vu,cl)
INITKDBG:00000001402DC2A9 add r9, 10h ; p=+0x10
INITKDBG:00000001402DC2AD xor r8, rax ;
Vu2
^count
INITKDBG:00000001402DC2B0 rol r8, cl ;
rol(
Vu2
,cl)
INITKDBG:00000001402DC2B3 sub rdx, r12 ; 是否计算完毕?
INITKDBG:00000001402DC2B6 jnz short cpg ; Vu=*ULONG_PTR *Pg[0]
mov rax, [r9] ; Vu=*ULONG_PTR *Pg[0]
INITKDBG:00000001402DC29C mov ecx, r11d ; 可能计算的范围?
INITKDBG:00000001402DC29F xor rax, r8 ; Vu=^
Vu2
INITKDBG:00000001402DC2A2 mov r8, [r9+8] ; Vu2=*ULONG_PTR *Pg[1]
INITKDBG:00000001402DC2A6 rol rax, cl ; rol(Vu,cl)
INITKDBG:00000001402DC2A9 add r9, 10h ; p=+0x10
INITKDBG:00000001402DC2AD xor r8, rax ;
Vu2
^count
INITKDBG:00000001402DC2B0 rol r8, cl ;
rol(
Vu2
,cl)
INITKDBG:00000001402DC2B3 sub rdx, r12 ; 是否计算完毕?
INITKDBG:00000001402DC2B6 jnz short cpg ; Vu=*ULONG_PTR *Pg[0]
r8最终=sign
//我只跟到4处 sign
// 第一 pg解密调用处 此处在pg执行体头部 进行效验 计算得出的key与PatchGuard_CmpAppendDllSectionSign对比 如果失败 开头就会进入蓝屏流程了
//第二处是 效验pg_Exec上方逆效验 也会对比sign 失败进行奇葩操作(658h)
//第三处 是正向计算pg_exec 下方效验 也会对比sign 失败进行奇葩操作(8B8h)
//第四处 具体没看 存在奇葩(828h)
//Pg 17134 1804 自效验pgcontext偏移:828h(101) 8B8h(109) 658h(101)
// 还有一处效验没有跟 它会调用KiDispatchCallout 暂时的解决办法是 写 c3 (C0000005)
像这种运行时 自效验 pgcontext里面非常的多。
//效验 一 PgEntry:
算法在上方 很多 不贴了
mov [rdi+0C4h], esi
INITKDBG:00000001402F246A cmp [rdi+8B8h], r8 ; //对比 sign 正确跳走 不正常给把错误码赋值
INITKDBG:00000001402F2471 jz short loc_1402F24DD
INITKDBG:00000001402F2473 mov rax, [rdi+588h]
INITKDBG:00000001402F247A mov ecx, [rdi+684h]
INITKDBG:00000001402F2480 mov [rax], rdi
INITKDBG:00000001402F2483 mov [rax+10h], ecx
INITKDBG:00000001402F2486 mov eax, [rdi+790h]
INITKDBG:00000001402F248C mov rdx, [rdi+8B8h]
INITKDBG:00000001402F2493 test eax, eax
INITKDBG:00000001402F2495 jnz short loc_1402F24DD ; 进入蓝屏流程
INITKDBG:00000001402F2497 mov rax, [rdi+588h]
INITKDBG:00000001402F249E mov rcx, r8
INITKDBG:00000001402F24A1 xor rcx, rdx
INITKDBG:00000001402F24A4 mov [rax+18h], rcx
INITKDBG:00000001402F24A8 mov eax, [rdi+790h]
INITKDBG:00000001402F24AE test eax, eax
INITKDBG:00000001402F24B0 jnz short loc_1402F24DD ; //进入蓝屏流程
INITKDBG:00000001402F24B2 lea rax, [rdi+r9]
INITKDBG:00000001402F24B6 mov [rdi+7A0h], r15
INITKDBG:00000001402F24BD mov [rdi+798h], rax
INITKDBG:00000001402F24C4 mov qword ptr [rdi+7A8h], 109h
INITKDBG:00000001402F24CF mov [rdi+7B0h], r8
INITKDBG:00000001402F24D6 mov [rdi+790h], r12d
mov [rdi+0C4h], esi
INITKDBG:00000001402F246A cmp [rdi+8B8h], r8 ; //对比 sign 正确跳走 不正常给把错误码赋值
INITKDBG:00000001402F2471 jz short loc_1402F24DD
INITKDBG:00000001402F2473 mov rax, [rdi+588h]
INITKDBG:00000001402F247A mov ecx, [rdi+684h]
INITKDBG:00000001402F2480 mov [rax], rdi
INITKDBG:00000001402F2483 mov [rax+10h], ecx
INITKDBG:00000001402F2486 mov eax, [rdi+790h]
INITKDBG:00000001402F248C mov rdx, [rdi+8B8h]
INITKDBG:00000001402F2493 test eax, eax
INITKDBG:00000001402F2495 jnz short loc_1402F24DD ; 进入蓝屏流程
INITKDBG:00000001402F2497 mov rax, [rdi+588h]
INITKDBG:00000001402F249E mov rcx, r8
INITKDBG:00000001402F24A1 xor rcx, rdx
INITKDBG:00000001402F24A4 mov [rax+18h], rcx
INITKDBG:00000001402F24A8 mov eax, [rdi+790h]
INITKDBG:00000001402F24AE test eax, eax
INITKDBG:00000001402F24B0 jnz short loc_1402F24DD ; //进入蓝屏流程
INITKDBG:00000001402F24B2 lea rax, [rdi+r9]
INITKDBG:00000001402F24B6 mov [rdi+7A0h], r15
INITKDBG:00000001402F24BD mov [rdi+798h], rax
INITKDBG:00000001402F24C4 mov qword ptr [rdi+7A8h], 109h
INITKDBG:00000001402F24CF mov [rdi+7B0h], r8
INITKDBG:00000001402F24D6 mov [rdi+790h], r12d
//////这里判断是否存在蓝屏代码
INITKDBG:00000001402F2853 CheCkKdebugCode: ; CODE XREF: INITKDBG:00000001402F2508j
INITKDBG:00000001402F2853 cmp [rdi+790h], r15d ; //是否在蓝屏代码
INITKDBG:00000001402F285A jz loc_1402F2B37
最后会运行运行到《
//这里贴点1804的代码
》这里
INITKDBG:00000001402F2853 CheCkKdebugCode: ; CODE XREF: INITKDBG:00000001402F2508j
INITKDBG:00000001402F2853 cmp [rdi+790h], r15d ; //是否在蓝屏代码
INITKDBG:00000001402F285A jz loc_1402F2B37
最后会运行运行到《
//这里贴点1804的代码
》这里
//第一个效验 ,不通过写入一个蓝屏代码109 后面判断是否存在蓝屏代码 然后就开始了善后工作.会清理一堆不知所谓的东西 。
//然后关闭写保护 给dbgprin写c3在恢复 最后的 imcall处无实际意义 最终调用 Sdbpcheck->清栈->KeBugCheckEx.
//sdbpcheck不能Fuck jmp得封装层 无法返回原有上下文 ret法也不行 回来没有正常得可执行代码了 。
//14393到是可以返回 但是依然要修改返回后的 int3 和下面跟的一个imcall 。实际情况还并不明朗。结论:至少 1804 fuck sdbpcheckdll已死
//这里贴点1804的代码
mov rax, [rdi+218h]
INITKDBG:00000001402F2A6E mov byte ptr [rax], 0C3h ; //把dbgprint写c3 恢复写保护位
INITKDBG:00000001402F2A71 mov cr0, r12
INITKDBG:00000001402F2A75 mov r12, [rbp+40h]
INITKDBG:00000001402F2A79
INITKDBG:00000001402F2A79 loc_1402F2A79: ; CODE XREF: INITKDBG:00000001402F28EBj
INITKDBG:00000001402F2A79 mov ecx, [rdi+7C0h]
INITKDBG:00000001402F2A7F test ecx, ecx ; //跳走了
INITKDBG:00000001402F2A81 jz FirstCodeVildCheck ; //sdbpcheck蓝屏
INITKDBG:00000001402F2A87 mov rax, cr8
INITKDBG:00000001402F2A8B cmp al, r11b
INITKDBG:00000001402F2A8E jnb short loc_1402F2A9E
INITKDBG:00000001402F2A90 mov rax, cr8
INITKDBG:00000001402F2A94 mov cr8, r11
INITKDBG:00000001402F2A98 mov ecx, [rdi+7C0h]
INITKDBG:00000001402F2A9E
INITKDBG:00000001402F2A9E loc_1402F2A9E: ; CODE XREF: INITKDBG:00000001402F2A8Ej
INITKDBG:00000001402F2A9E test ecx, ecx
INITKDBG:00000001402F2AA0 jz FirstCodeVildCheck ; //sdbpcheck蓝屏
INITKDBG:00000001402F2AA6 sub ecx, 1
INITKDBG:00000001402F2AA9 jz FirstCodeVildCheck3
INITKDBG:00000001402F2AAF sub ecx, 1
////
//FirstCodeVildCheck: ; CODE XREF: INITKDBG:00000001402F2A81j
INITKDBG:00000001402F2CDE ; INITKDBG:00000001402F2AA0j ...
INITKDBG:00000001402F2CDE and qword ptr [r15+610h], 0 ; //sdbpcheck蓝屏
INITKDBG:00000001402F2CE6 and qword ptr [r15+690h], 0
INITKDBG:00000001402F2CEE mov rcx, [rdi+158h]
INITKDBG:00000001402F2CF5 call KeGuardCheckICall
INITKDBG:00000001402F2CFA mov rax, [rdi+158h]
INITKDBG:00000001402F2D01 mov r9, rbx
INITKDBG:00000001402F2D04 mov [rsp+30h], r14
INITKDBG:00000001402F2D09 mov r8, rsi
INITKDBG:00000001402F2D0C mov [rsp+28h], rax
INITKDBG:00000001402F2D11 mov rdx, r12
INITKDBG:00000001402F2D14 mov ecx, 109h
INITKDBG:00000001402F2D19 mov [rsp+20h], r13
INITKDBG:00000001402F2D1E call SdbpCheckDll
INITKDBG:00000001402F2D1E ; ---------------------------------------------------------------------------
INITKDBG:00000001402F2D23 db 0Dh dup(0CCh)
INITKDBG:00000001402F2D30 qword_1402F2D30 dq 5541544157565340h, 70EC834857415641h, 8E8898B48D98B48h
//关于 FsRtlMdlReadCompleteDevEx:
这个里面的效验处有很多
想到了个不知道是否可行的Patch 自效验方法:我贴一点代码 =就是撸掉 蓝屏代码赋值的地方 把flag这些都Nop掉
入口处效验和蓝屏
14393
lea rax, [rdi+r8] ; //赋值
INITKDBG:0000000140249923 mov [rdi+658h], rsi ; 蓝屏参数
INITKDBG:000000014024992A mov [rdi+650h], rax ; //蓝屏参数
INITKDBG:0000000140249931 mov qword ptr [rdi+660h], 109h ; //蓝屏代码
INITKDBG:000000014024993C mov [rdi+668h], rdx ; //效验和
INITKDBG:0000000140249943 mov dword ptr [rdi+648h], 1 ; //是否启用了?
1804
lea rax, [rdi+r9]
INITKDBG:00000001402F24B6 mov [rdi+7A0h], r15
INITKDBG:00000001402F24BD mov [rdi+798h], rax
INITKDBG:00000001402F24C4 mov qword ptr [rdi+7A8h], 109h
INITKDBG:00000001402F24CF mov [rdi+7B0h], r8
INITKDBG:00000001402F24D6 mov [rdi+790h], r12d
第二处效验FsRtlMdlReadCompleteDevEx效验和蓝屏
14393
lea rax, [r12+rsi]
INITKDBG:0000000140239303 mov [r12+650h], rax
INITKDBG:000000014023930B xor eax, eax
INITKDBG:000000014023930D mov [r12+658h], rax
INITKDBG:0000000140239315 mov qword ptr [r12+660h], 101h
INITKDBG:0000000140239321 mov [r12+668h], rdx
INITKDBG:0000000140239329 mov [r12+648h], r13d
1804
//算法
loc_1402DC311: ; CODE XREF: INITKDBG:00000001402DC325j
INITKDBG:00000001402DC311 xor r8, [r9]
INITKDBG:00000001402DC314 mov ecx, r11d
INITKDBG:00000001402DC317 rol r8, cl
INITKDBG:00000001402DC31A add r9, 8
INITKDBG:00000001402DC31E add r10d, 0FFFFFFF8h
INITKDBG:00000001402DC322 sub rdx, rsi
INITKDBG:00000001402DC325 jnz short loc_1402DC311
INITKDBG:00000001402DC327
INITKDBG:00000001402DC327 loc_1402DC327: ; CODE XREF: INITKDBG:00000001402DC308j
INITKDBG:00000001402DC327 test r10d, r10d
INITKDBG:00000001402DC32A jz short loc_1402DC342
INITKDBG:00000001402DC32C
INITKDBG:00000001402DC32C loc_1402DC32C: ; CODE XREF: INITKDBG:00000001402DC340j
INITKDBG:00000001402DC32C movzx eax, byte ptr [r9]
INITKDBG:00000001402DC330 mov ecx, r11d
INITKDBG:00000001402DC333 xor r8, rax
INITKDBG:00000001402DC336 add r9, rsi
INITKDBG:00000001402DC339 rol r8, cl
INITKDBG:00000001402DC33C add r10d, 0FFFFFFFFh
INITKDBG:00000001402DC340 jnz short loc_1402DC32C
INITKDBG:00000001402DC342
INITKDBG:00000001402DC342 loc_1402DC342: ; CODE XREF: INITKDBG:00000001402DC32Aj
INITKDBG:00000001402DC342 mov [r12+658h], r14
INITKDBG:00000001402DC34A lea rcx, [rbp+0AB0h]
INITKDBG:00000001402DC351 mov edx, r13d
INITKDBG:00000001402DC354 mov r9, r15
INITKDBG:00000001402DC357 mov r11d, 0FFFFFFF8h
loc_1402DC311: ; CODE XREF: INITKDBG:00000001402DC325j
INITKDBG:00000001402DC311 xor r8, [r9]
INITKDBG:00000001402DC314 mov ecx, r11d
INITKDBG:00000001402DC317 rol r8, cl
INITKDBG:00000001402DC31A add r9, 8
INITKDBG:00000001402DC31E add r10d, 0FFFFFFF8h
INITKDBG:00000001402DC322 sub rdx, rsi
INITKDBG:00000001402DC325 jnz short loc_1402DC311
INITKDBG:00000001402DC327
INITKDBG:00000001402DC327 loc_1402DC327: ; CODE XREF: INITKDBG:00000001402DC308j
INITKDBG:00000001402DC327 test r10d, r10d
INITKDBG:00000001402DC32A jz short loc_1402DC342
INITKDBG:00000001402DC32C
INITKDBG:00000001402DC32C loc_1402DC32C: ; CODE XREF: INITKDBG:00000001402DC340j
INITKDBG:00000001402DC32C movzx eax, byte ptr [r9]
INITKDBG:00000001402DC330 mov ecx, r11d
INITKDBG:00000001402DC333 xor r8, rax
INITKDBG:00000001402DC336 add r9, rsi
INITKDBG:00000001402DC339 rol r8, cl
INITKDBG:00000001402DC33C add r10d, 0FFFFFFFFh
INITKDBG:00000001402DC340 jnz short loc_1402DC32C
INITKDBG:00000001402DC342
INITKDBG:00000001402DC342 loc_1402DC342: ; CODE XREF: INITKDBG:00000001402DC32Aj
INITKDBG:00000001402DC342 mov [r12+658h], r14
INITKDBG:00000001402DC34A lea rcx, [rbp+0AB0h]
INITKDBG:00000001402DC351 mov edx, r13d
INITKDBG:00000001402DC354 mov r9, r15
INITKDBG:00000001402DC357 mov r11d, 0FFFFFFF8h
//
cmp [r12+658h], r8 ; //658是否是pg的sign 这个位置 从pg 刚刚解密 还未执行时 就和现在是一样的
INITKDBG:00000001402DC38E jz loc_1402DC414 ; //正常流程肯定会跳下去
INITKDBG:00000001402DC394 mov rax, [r12+588h] ; //TriageImagePageSize
INITKDBG:00000001402DC39C mov ecx, [r12+684h] ; //这个00070989 不知道是什么
INITKDBG:00000001402DC3A4 mov [rax], r12
INITKDBG:00000001402DC3A7 mov [rax+10h], ecx
INITKDBG:00000001402DC3AA mov eax, [r12+790h] ; //这里是0
INITKDBG:00000001402DC3B2 mov rcx, [r12+658h] ; //或许是sign
INITKDBG:00000001402DC3BA test eax, eax
INITKDBG:00000001402DC3BC jnz short loc_1402DC414
INITKDBG:00000001402DC3BE mov rax, [r12+588h]
INITKDBG:00000001402DC3C6 xor rcx, r8
INITKDBG:00000001402DC3C9 mov [rax+18h], rcx ; //不知所谓
INITKDBG:00000001402DC3CD mov eax, [r12+790h]
INITKDBG:00000001402DC3D5 test eax, eax
INITKDBG:00000001402DC3D7 jnz short loc_1402DC414
INITKDBG:00000001402DC3D9 mov rax, 0A3A03F5891C8B4E8h
INITKDBG:00000001402DC3E3 add rax, r12
INITKDBG:00000001402DC3E6 mov [r12+798h], rax ; //蓝屏参数
INITKDBG:00000001402DC3EE xor eax, eax
INITKDBG:00000001402DC3F0 mov [r12+7A0h], rax ; //清空低4byte 蓝屏代码
INITKDBG:00000001402DC3F8 mov qword ptr [r12+7A8h], 101h ; //蓝屏代码
INITKDBG:00000001402DC404 mov [r12+7B0h], r8 ; //效验和
INITKDBG:00000001402DC40C mov [r12+790h], esi ; //esi为1
INITKDBG:00000001402DC414
cmp [r12+658h], r8 ; //658是否是pg的sign 这个位置 从pg 刚刚解密 还未执行时 就和现在是一样的
INITKDBG:00000001402DC38E jz loc_1402DC414 ; //正常流程肯定会跳下去
INITKDBG:00000001402DC394 mov rax, [r12+588h] ; //TriageImagePageSize
INITKDBG:00000001402DC39C mov ecx, [r12+684h] ; //这个00070989 不知道是什么
INITKDBG:00000001402DC3A4 mov [rax], r12
INITKDBG:00000001402DC3A7 mov [rax+10h], ecx
INITKDBG:00000001402DC3AA mov eax, [r12+790h] ; //这里是0
INITKDBG:00000001402DC3B2 mov rcx, [r12+658h] ; //或许是sign
INITKDBG:00000001402DC3BA test eax, eax
INITKDBG:00000001402DC3BC jnz short loc_1402DC414
INITKDBG:00000001402DC3BE mov rax, [r12+588h]
INITKDBG:00000001402DC3C6 xor rcx, r8
INITKDBG:00000001402DC3C9 mov [rax+18h], rcx ; //不知所谓
INITKDBG:00000001402DC3CD mov eax, [r12+790h]
INITKDBG:00000001402DC3D5 test eax, eax
INITKDBG:00000001402DC3D7 jnz short loc_1402DC414
INITKDBG:00000001402DC3D9 mov rax, 0A3A03F5891C8B4E8h
INITKDBG:00000001402DC3E3 add rax, r12
INITKDBG:00000001402DC3E6 mov [r12+798h], rax ; //蓝屏参数
INITKDBG:00000001402DC3EE xor eax, eax
INITKDBG:00000001402DC3F0 mov [r12+7A0h], rax ; //清空低4byte 蓝屏代码
INITKDBG:00000001402DC3F8 mov qword ptr [r12+7A8h], 101h ; //蓝屏代码
INITKDBG:00000001402DC404 mov [r12+7B0h], r8 ; //效验和
INITKDBG:00000001402DC40C mov [r12+790h], esi ; //esi为1
INITKDBG:00000001402DC414
第三处:
14393
懒得找了
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2018-9-8 14:00
被落笔飞花编辑
,原因: