日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Win7x64系统过TP的一些尝试和目前遇到的问题

發布時間:2023/12/15 windows 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Win7x64系统过TP的一些尝试和目前遇到的问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
其實渣新學內核編程不過半個月時間,帖中難免有幼稚的想法和錯誤,遇到的問題我會用藍色文字表述,還請各位前輩指正,感激不盡!

我把自己目前的進展和遇到的問題一起說說吧:
x64系統過TP大概分兩步,首先要過雙機調試,然后要過應用層調試。

1、過雙機調試,這里也分兩步
(1)首先要保證debug模式下啟動游戲不藍屏。

我也是第一次研究TP,對這之前的保護不了解,不過看網上所說這個啟動藍屏似乎是最近幾個月新加的。
要過這個需要對內核調試引擎有一定的了解,不過還好我們是站在巨♂人♀的肩膀上,在看雪找到了篇帖子,比較詳細的分析了系統啟動時內核調試引擎初始化的幾個標志。
TP只是檢測了其中一個(待定), KdEnteredDebugger ,它通過MDL映射來判斷這個標志是不是True,如果是就藍屏,解決方法我照抄了那篇帖子,直接在Hook一下IoAllocateMdl,
把判斷的地址改到一個恒為False的地方這樣就可以繞過了
[C++]?純文本查看?復制代碼 ?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 PMDL newIoAllocateMdl( ????????__in_opt PVOID? VirtualAddress, ????????__in ULONG? Length, ????????__in BOOLEAN? SecondaryBuffer, ????????__in BOOLEAN? ChargeQuota, ????????__inout_opt PIRP? Irp? OPTIONAL) { ????????if (VirtualAddress == KdEnteredDebugger) ????????{ ????????????????//DbgPrint("[KdEnteredDebugger] address: %p\n", KdEnteredDebugger); ????????????????VirtualAddress = (PUCHAR)KdEnteredDebugger + 0x30;? //據觀察,+0x30 的位置恒為0 ????????} ????????return oldIoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp); }

不過這樣做帶來一個問題,藍屏是不藍屏了,TP的驅動模塊也能加載,但只能啟動登陸客戶端Client.exe,在登陸后啟動DNF.exe時TP會再進行一次檢測,
這次就會造成虛擬機卡死,估計還是和調試模式的檢測有關。


我用了個折中的解決辦法,就是用戶態調試的時候不進入Debug模式,這樣就能啟動DNF.exe了,不過實在是不方便

(2)使雙機調試能下斷點
關于雙機調試中斷點原理和異常的處理流程,我是看了《軟件調試》這本書和http://www.xfocus.net/articles/200412/765.html這片帖子,有了些了解。
對于TP來說,他是不斷調用KdDisableDebuger()這個函數來清零KdDebuggerEnabled ,調試引擎就是在KeUpdateSystemTime()這個函數里不斷檢測這個標志來確定異常處理的流程

解決方法,一開始我是直接HooK KdDisableDebuger(),開頭
[Asm]?純文本查看?復制代碼 ?
1 2 xor rax, rax ret
直接STATUS_SUCCESS然后返回,不讓它做其他處理, 但是毫無效果,還是下不了斷點,不知道是怎么回事……

后來想了個辦法,直接修改KeUpdateSystemTime()里面檢測的地方,和上面一樣,讓它檢測其它地址……
[C++]?純文本查看?復制代碼 ?
01 02 03 04 05 06 07 08 09 10 //替換KeUpdateSystemTime函數中兩個KdDebuggerEnabled變量地址為DummyKdDebuggerEnabled KUSTPatchAddr1 = SearchAddressBySig((PUCHAR)KeUpdateSystemTimeAddr + 0x100, 0x100, UPSig1, sizeof(UPSig1)) ; if (KUSTPatchAddr1 != NULL) { ????KUSTPatchAddr1 += sizeof(UPSig1); ????//64位匯編,變量均為相對rip地址,下同 ????DisableWriteProtect64(); ????*(PULONG)KUSTPatchAddr1 = (PUCHAR)pDummyKdDebuggerEnabled - ((PUCHAR)KUSTPatchAddr1 - 2) - 6; //指令長度為6 ????EnableWriteProtect64(); }

要改的地方有3處,我只貼了一處的代碼。這樣就能下各種斷點了。

2、雙機調試之后就是用戶態調試了
x64系統上TP目前做的保護還不是特別多,這也是我選x64入手的原因之一
TP修改了
DebugObject中 ValIDAccessMask一項,這個就是調試權限,代碼中我們恢復下就可以了。

windbg下輸入以下命令就可以定位到
ValidAccessMask,下硬件斷點就能找到 ValidAccessMask清零的地方。
至于如何在自己的代碼中定位這個變量,我是通過SSDT表查找NtCreateDebugObject這個內核函數地址,里面定位
DbgkDebugObjectType
再根據下面的結構體加幾個偏移地址(
+0x040 +? 0x01c)來找到 ValidAccessMask。應該有更好的定位方法……

[Asm]?純文本查看?復制代碼 ?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 dq DbgkDebugObjectType dt _OBJECT_TYPE fffffa80`24e33250 清零前: 1: kd> dt _OBJECT_TYPE_INITIALIZER fffffa80`24e33250+0x040 nt!_OBJECT_TYPE_INITIALIZER ???+0x000 Length?????????? : 0x70 ???+0x002 ObjectTypeFlags? : 0x8 '' ???+0x002 CaseInsensitive? : 0y0 ???+0x002 UnnamedObjectsOnly : 0y0 ???+0x002 UseDefaultObject : 0y0 ???+0x002 SecurityRequired : 0y1 ???+0x002 MaintainHandleCount : 0y0 ???+0x002 MaintainTypeList : 0y0 ???+0x002 SupportsObjectCallbacks : 0y0 ???+0x004 ObjectTypeCode?? : 0 ???+0x008 InvalidAttributes : 0 ???+0x00c GenericMapping?? : _GENERIC_MAPPING ???+0x01c ValidAccessMask? : 0x1f000f ???+0x020 RetainAccess???? : 0 ???+0x024 PoolType???????? : 0 ( NonPagedPool ) ???+0x028 DefaultPagedPoolCharge : 0 ???+0x02c DefaultNonPagedPoolCharge : 0x58 ???+0x030 DumpProcedure??? : (null) ???+0x038 OpenProcedure??? : (null) ???+0x040 CloseProcedure?? : 0xfffff800`01f0ddb0???? void? nt!DbgkpCloseObject+0 ???+0x048 DeleteProcedure? : 0xfffff800`01d66fe0???? void? nt!CmpConfigureProcessors+0 ???+0x050 ParseProcedure?? : (null) ???+0x058 SecurityProcedure : 0xfffff800`01dd25f0???? long? nt!SeDefaultObjectMethod+0 ???+0x060 QueryNameProcedure : (null) ???+0x068 OkayToCloseProcedure : (null) 清零后: 0: kd> dt _OBJECT_TYPE_INITIALIZER fffffa80`24e51250+0x040 nt!_OBJECT_TYPE_INITIALIZER ???+0x000 Length?????????? : 0x70 ???+0x002 ObjectTypeFlags? : 0x8 '' ???+0x002 CaseInsensitive? : 0y0 ???+0x002 UnnamedObjectsOnly : 0y0 ???+0x002 UseDefaultObject : 0y0 ???+0x002 SecurityRequired : 0y1 ???+0x002 MaintainHandleCount : 0y0 ???+0x002 MaintainTypeList : 0y0 ???+0x002 SupportsObjectCallbacks : 0y0 ???+0x004 ObjectTypeCode?? : 0 ???+0x008 InvalidAttributes : 0 ???+0x00c GenericMapping?? : _GENERIC_MAPPING ???+0x01c ValidAccessMask? : 0 ???+0x020 RetainAccess???? : 0 ???+0x024 PoolType???????? : 0 ( NonPagedPool ) ???+0x028 DefaultPagedPoolCharge : 0 ???+0x02c DefaultNonPagedPoolCharge : 0x58 ???+0x030 DumpProcedure??? : (null) ???+0x038 OpenProcedure??? : (null) ???+0x040 CloseProcedure?? : 0xfffff800`01eb5db0???? void? nt!DbgkpCloseObject+0 ???+0x048 DeleteProcedure? : 0xfffff800`01d0efe0???? void? nt!CmpConfigureProcessors+0 ???+0x050 ParseProcedure?? : (null) ???+0x058 SecurityProcedure : 0xfffff800`01d7a5f0???? long? nt!SeDefaultObjectMethod+0 ???+0x060 QueryNameProcedure : (null) ???+0x068 OkayToCloseProcedure : (null) 清零代碼: fffff880`0bcdc4cc 54????????????? push??? rsp fffff880`0bcdc4cd 33c0??????????? xor???? eax,eax fffff880`0bcdc4cf 87434c????????? xchg??? eax,dword ptr [rbx+4Ch] fffff880`0bcdc4d2 33c0??????????? xor???? eax,eax fffff880`0bcdc4d4 874350????????? xchg??? eax,dword ptr [rbx+50h] fffff880`0bcdc4d7 33c0??????????? xor???? eax,eax fffff880`0bcdc4d9 87435c????????? xchg??? eax,dword ptr [rbx+5Ch] // ValidAccessMask? fffff880`0bcdc4dc 833d9585000000? cmp???? dword ptr [fffff880`0bce4a78],0 fffff880`0bcdc4e3 0f8544feffff??? jne???? fffff880`0bcdc32d fffff880`0bcdc4e9 33c9??????????? xor???? ecx,ecx fffff880`0bcdc4eb ff15df6b0000??? call??? qword ptr [fffff880`0bce30d0] fffff880`0bcdc4f1 488b4c2440????? mov???? rcx,qword ptr [rsp+40h] fffff880`0bcdc4f6 4833cc????????? xor???? rcx,rsp fffff880`0bcdc4f9 e822570000????? call??? fffff880`0bce1c20 fffff880`0bcdc4fe 488b5c2468????? mov???? rbx,qword ptr [rsp+68h] fffff880`0bcdc503 4883c450??????? add???? rsp,50h fffff880`0bcdc507 5f????????????? pop???? rdi fffff880`0bcdc508 c3????????????? ret


從清零代碼那里的windbg信息來看,沒有地址標號的提示(TesSafe+xxxx),這代碼似乎不是在一個驅動模塊里?
關于恢復的方法,大體上能想到3種:
1、開一個IoTimer或者DpcTimer或者干脆開個線程,不斷對 ValidAccessMask地址寫入它原來的值
2、自己代碼內利用調試寄存器下硬件斷點,然后hook IDT 1號中斷服務子程,在里面恢復
ValidAccessMask
3、
自己代碼內利用調試寄存器下硬件斷點,定位到上面的清零代碼,nop之(我在windbg里直接nop掉是可以的,沒有模塊自校驗)
目前我嘗試了第一種方法,開了個IoTimer,雖說1s一次會造成一些概率問題,但測試而已,簡單粗暴就好。
[C++]?純文本查看?復制代碼 ?
1 2 3 4 5 6 VOID OnTimer(DEVICE_OBJECT? *DeviceObject, PVOID? Context) { ????????DisableWriteProtect64(); ????????*g_pValidAccessMask = 0x1f000f; ????????EnableWriteProtect64(); }

至于為什么會有后兩種想法,是因為我覺得其作用不僅僅在于次,通過調試寄存器和1號中斷應該還可以作很多事情,不僅僅是寫個0x1f000f而已……
不過雖說想法很好,我還沒開始實踐……這中間似乎涉及到多核CPU還有用戶棧內核棧切換的許多知識……

好了,現在可以開OD附加了,那么問題來了,學挖掘……哦不…………
還是先請前輩們看看效果圖:
這是開另一個任意程序調試的OD,一切正常:
?
這是附加了DNF.exe,反匯編窗口基本全是0,右鍵看不到模塊信息……
這個就是傳說中的DebugPort清零嗎?如果是的話,我在自己研究下恢復,如果不是,哪是什么問題造成了這種現象?

?
另外從圖上游戲界面可以看到,DNF檢測到了非法模塊,這個不知道會有什么影響……

總結

以上是生活随笔為你收集整理的Win7x64系统过TP的一些尝试和目前遇到的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。