zl程序教程

您现在的位置是:首页 >  Java

当前栏目

驱动开发:WinDBG 枚举SSDT以及SSSDT地址

2023-02-18 16:46:15 时间

在前面的博文《驱动开发:内核读取SSDT表基址》中已经教大家如何寻找SSDT表基地址了,今天给大家分享两个适用于WinDBG调试器上的脚本文件,该脚本文件可以很好的枚举出当前系统内的SSDT以及SSSDT表中的数据,可以方便后续文章的学习参考之用,当然脚本不是我写的,文章末尾我会给出参考原文链接。

第一段脚本可用于枚举64位系统下所有的SSDT表,将脚本保存为enum_ssdt.log写入以下内容。

aS ufLinkS "<u><col fg=\\\"emphfg\\\"><link name=\\\"%p\\\" cmd=\\\"uf 0x%p\\\">";
aS ufLinkE "</link></col></u>";
 
r $t1 = nt!KeServiceDescriptorTable;
r $t2 = poi(@$t1 + 0x10);
r $t1 = poi(@$t1);
 
.printf "\n\nKeServiceDescriptorTable->KiServiceTable:  %p\nKeServiceDescriptorTable->Count: %d\n", @$t1, @$t2;
.printf "\nOrd   Address   fnAddr   Symbols\n";
.printf "--------------------------------\n\n";
 
.for (r $t0 = 0; @$t0 != @$t2; r $t0 = @$t0 + 1)
{
    r @$t3 = (poi(@$t1 + @$t0 * 4)) & 0x00000000`FFFFFFFF;
    $$.printf "2. %p\n", @$t3;
       
    .if ( @$t3 & 0x80000000 )
       {
               r @$t3 = (@$t3 >> 4) | 0xFFFFFFFF`F0000000;
               r @$t3 = 0 - @$t3;
               r @$t3 = @$t1 - @$t3;
       }
       .else
       {
           r @$t3 = (@$t3 >> 4);
               r @$t3 = (@$t1 + @$t3);
       }
       
    .printf /D "[%3d] ${ufLinkS}%p${ufLinkE} (%y)\n", @$t0, @$t3, @$t3, @$t3, @$t3;
}
 
.printf "\n- end -\n";

回到WinDBG中输入命令$><d://enum_ssdt.log调用脚本,可得到如下输出。

还有一个输出SSSDT地址的脚本,直接保存位enum_sssdt.log,写入以下内容。

aS ufLinkS "<u><col fg=\\\"emphfg\\\"><link name=\\\"%p\\\" cmd=\\\"uf 0x%p\\\">";
aS ufLinkE "</link></col></u>";

r $t1 = nt!KeServiceDescriptorTableShadow;
r $t2 = @$t1 + 0x08*4;
r $t3 = poi(@$t2 + 0x10);
r $t2 = poi(@$t2);

.printf "\n\nKeServiceDescriptorTableShadow->W32pServiceTable:  %p\nKeServiceDescriptorTableShadow->Count: %d\n", @$t2, @$t3;
.printf "\nOrd   Address         Symbols\n";
.printf "--------------------------------\n\n";

.for (r $t0 = 0; @$t0 != @$t3; r $t0 = @$t0 + 1)
{
    r @$t4 = (poi(@$t2 + @$t0 * 4)) & 0x00000000`FFFFFFFF;
    $$.printf "2. %p\n", @$t4;

    .if ( @$t4 & 0x80000000 )
       {
               r @$t4 = (@$t4 >> 4) | 0xFFFFFFFF`F0000000;
               r @$t4 = 0 - @$t4;
               r @$t4 = @$t2 - @$t4;
       }
       .else
       {
           r @$t4 = (@$t4 >> 4);
               r @$t4 = (@$t2 + @$t4);
       }

    .printf /D /os "[%3d] ${ufLinkS}%p${ufLinkE} (%y)\n", @$t0, @$t4, @$t4, @$t4, @$t4;
}

.printf "\n- end -\n";

使用WinDBG附加到应用层explorer.exe,并执行遍历命令。

0: kd> !process 0 0 explorer.exe
0: kd> .process ffff9b8a552b0340
0: kd> .reload win32k.sys
0: kd> $><d://enum_sssdt.log

输出遍历效果如下所示。

参考文献

https://www.cnblogs.com/ImprisonedSoul/p/15603120.html https://www.cnblogs.com/ImprisonedSoul/p/15603209.html