TA的每日心情  | 奋斗 2023-6-30 13:25 | 
|---|
 
  签到天数: 104 天 [LV.6]常住居民II  
 | 
 
 
环境 VT的相关问题可以到网站了解下,我们是业内领域专业的平台,您如果有需要可以咨询,相信可以帮到您,值得您的信赖! 
客户机:VMW+W76364,4核,8G 
 
 
宿主机:W 
 
 
 
 
 
单步调试异常 
启动应用,EAC驱动加载,首先会主动触发一个单步调试异常。 
 
 
S-800000() 
F 
T 
EAC+2: 
800`589 
1:800`5 
EAC+: 
800`545 
800`5488, 
800`5, 
800`53489 
800`5559 
800`564881, 
800`5948,8;置EFLAGS:TF标志位 
800`550 
800`5489 
800`5 
800`589 
800`54EAC+8(800`58)B 
 
EAC+8: 
800`5882, 
800`54885, 
800`55 
800`53 
反调试很常见的一种调试器检测方法,调试器忽略此次异常即可()。 
 
 
KED异常 
以后,系统卡死反应并且法中断到调试器。挂起系统,使用2转储(VMW下载2)。 
 
 
 
 
 
使用WDBG加载,查看系统挂起原因。 
 
 
3:~0 
0: 
#C-SPRACS 
0`466868`4444!KCS+ 
8`46686`4432!KFTE+8 
8`46686`44647!KCFFE+ 
8`46686`44!KPNMI+7 
8`466863`443!KNI+2 
8`466867`44397!KNI+ 
8`466747`437!PIGE+ 
8`466747`437!PIET+ 
8`466740`44452!PI+3 
8`466746000000000`00000000!KIL+ 
0:~1 
1: 
#C-SPRACS 
0780`638`4444!KCS+ 
9780`63`4432!KFTE+8 
9780`63`44647!KCFFE+ 
9780`63`44!KPNMI+7 
9780`633`443!KNI+2 
9780`637`44397!KNI+ 
88`97`437!PIGE+ 
88`97`437!PIET+ 
88`90`44452!PI+3 
88`96000000000`00000000!KIL+ 
1:~2 
2: 
#C-SPRACS 
0780`7988`4444!KCS+ 
9780`798`4432!KFTE+8 
9780`798`44647!KCFFE+ 
9780`798`44!KPNMI+7 
9780`7983`443!KNI+2 
9780`7987`44397!KNI+ 
88`77`437!PIGE+ 
88`77`437!PIET+ 
88`70`44452!PI+3 
88`76000000000`00000000!KIL+ 
2:~3 
3: 
#C-SPRACS 
0780``44386!KTTASL+ 
9780`1`44734!KFE+ 
9780`1`44951!KED+4 
9780``4477665!KR+1 
9780``43!KT+4 
9780`1`435!KT+ 
9780`1`4442!KDE+35 
9780`9`44988!KED+ 
9780`7`44737!KDTOF+8 
9780``44951!KED+3 
780``4477665!KR+1 
780``43!KT+4 
780`1`435!KT+ 
780``4442!KDE+35 
780``44988!KED+ 
780`9`44737!KDTOF+8 
80`2`44951!KED+3 
9780`5`4477665!KR+1 
9780`9`43!KT+4 
9780``435!KT+ 
 
CPU0-2未见异常,CPU3看起来进入了死循环,继续查看: 
 
 
3: 
#C-SPRA:AC:CS 
0780``44386:00000000`00780`0000000000`0000000000000000`00000000:!KTTASL+ 
9780`1`44734:00000000`0000000000000000`000000780`80`70:!KFE+ 
9780`1`44951:9780`80`80`00000000`00000000:!KED+4 
9780``4477665:9780`80`80`00000000`00000000:!KR+1 
9780``43:9780`89780`0780`80`:!KT+4 
9780`1`435:9780`89780`80`00000000`00000000:!KT+ 
9780`1`4442:8`0000000000`0000000000000000`0000000000000000`00000000:!KDE+35 
9780`9`44988:00000000`0000000000000000`0000000000000000`0000000000000000`00000000:!KED+ 
9780`7`44737:00000000`0000000000000000`000000780`780`90:!KDTOF+8(TF@9780`70) 
9780``44951:9780`780`80`000000000`00000000:!KED+3 
780``4477665:9780`780`80`000000000`00000000:!KR+1 
780``43:9780`89780`780`780`:!KT+4 
780`1`435:9780`89780`80`000000000`00000000:!KT+ 
780``4442:9780`8`0000000000000000`0000000780`8:!KDE+35 
780``44988:9780`88`0000000000000000`0000000780`8:!KED+ 
780`9`44737:00000000`0000000000000000`000000780`5780`:!KDTOF+8(TF@9780`90) 
 
 
3:9780`70 
3: 
!KED+0: 
8`4473889[], 
8`44733,[!KDNP(8`442)] 
8`4473388,1 
8`44733,2 
8`44733838,1 
8`4473488941[+8], 
8`447345440[!KDEC(8`448)] 
8`4473446, 
8`44734387[!KPL(8`443780)], 
8`447354488638,[+38] 
8`4473594887440,[+40] 
8`4473543 
8`447363540[!KDEWL(8`44)], 
8`4473674885,[+] 
8`44736488748,[+48] 
8`447378500000[!KED(8`4400)],1;触发调试异常(KDTOF) 
当有调试事件发生需要中断到调试器时需要调用!KED函数,函数内部如果触发了异常,则会产生限递归,资源耗尽后会触发KBCE调用。为了正常中断到调试器,可以先把8`447371处指令NOP掉。 
 
 
 
 
 
重新尝试,重启虚拟机,内核附加调试,NOP8`447371(!KED+)处指令: 
 
 
0:!KED+ 
!KED+: 
8`778500000[!KED(8`7900)],1 
8`7748834, 
8`774 
8`78 
8`78 
8`7833 
8`7843 
8`7853 
0:!KED+ 
0:!KED+ 
!KED+: 
8`770 
8`770 
8`77390 
8`77490 
8`77590 
8`77690 
8`77790 
8`77890 
8`77990 
8`7790 
8`7748834, 
8`774 
8`78 
0: 
启动应用,调试器可以正常中断了: 
 
 
0: 
S-800000() 
F 
T 
EAC+2: 
8`75689 
2: 
B-800000() 
EAC+2: 
8`756;主动触发断点异常 
2:0,1,2,3 
0=8790=874=000000000000000=0000000000000000 
需要注意此时EAC已经设置!KED(7900)和!KBCE(740)两个硬件断点。 
 
 
检测机制已经很清晰了: 
 
 
 
对!KED下硬件写断点,对!KBCE下硬件执行断点; 
 
 
主动触发CC断点异常; 
 
 
如果内核调试开启且调试器已附加,则内核调试引擎会执行!KED中断到调试器以报告异常; 
 
 
!KED写入!KED触发硬件写断点; 
 
 
资源允许则回到3形成递归调用,资源不足则调用!KBCE; 
 
 
!KBCE触发硬件执行断点,回到3形成递归调用。(系统卡死,不会形成崩溃转储) 
 
 
 
忽略EAC主动触发的CC异常,继续执行: 
 
 
2: 
S-800000() 
F 
T 
!KED+0: 
8`79548,[!KLB(8`7980)] 
2:3 
!KED: 
8`78843 
8`784883, 
8`788360[!KED(8`7900)],0 
2:!KED+90 
可以看到!KED同样会写!KED字段,按同样方式NOP掉即可。 
 
 
 
 
 
 
 
 
KDE检测 
对CC进行之后,我们发现虽然系统正常运行,但是调试机再次'失联'了,并且应用提示检测到’调试模式‘,查看,可以发现!KDE被清零了,这是一个对内核调试很重要的字段,清零就意味着客户机不会再响应调试器的任何请求。 
 
 
0:!KDE 
8`7000000000000000-0000000000000000 
8`7000000000000000-000000000000 
8`710000000000000-0008700@ 
8`71000000000000000-0000000000000000 
8`71000000000000000-0000000000000000 
机制很简单,我不打算继续深究其具体现,打补丁,过校验等,也许可以用一种相对通用的思路来解决这种检测(考虑到TP等也有类似的检测机制): 
 
 
 
将!KDE及!KDNP换个位置存储 
 
 
找到系统对这两个变量的引用,重定向到我们指定的位置 
 
 
将!KDE置0,!KDNP置1,原地址展示伪造后的信息以过检测 
 
 
 
经过上述操作后,程序对!KDE和!KDNP的破坏性修改将不会再影响到调试机制,其中难点在于第2步,可以使用IDA交叉引用查找,也可以WDBG下硬件断点动态查找(推荐),不多赘述,现如下: 
 
 
#WKV763MP(4)F64 
#P:WN,:TSSUTS 
#B:76345_-34 
#将!KDE及!KDNP重定向到!KDE+2处 
#需要注意:1所选择的重定向HOOK是没有通用性的,需灵活修改应用,2根据自己的调试环境自行调整偏移和补丁 
 
!KDE0000 
!KCFDB+0+6 
!KPBI+4+9 
!KPBI++2 
!KPBI++332 
!KPBI++39 
!KCRF+4+39 
!KCRF+41+3 
!KSWC+00+3 
!KSWC+80+3 
!KED+3+32 
!KED++34 
!KDE0000 
PS:不要处理!EQSI,否则NQSI依然可以检测到调试器。 
 
 
 
 
 
未完待续 
经过上面的处理后,调试器功能已经正常了,不过应用还不能正常运行,提示检测到‘测试签’,‘内核调试’等。 |   
 
 
 
 |