有两种方法,各有优缺点
方法1:
最简单方法是利用windbg 本地内核调试
Ctrl + K 选择local -> 输入 !dskheap -> 在输入 x win32k!*gphk* 就是系统热键链表首地址
bf9b0bd8 win32k!gphkFirst
^^^^^^^^
在详细一点就要,windbg 本地内核调试命令窗口输入以下命令可以枚举系统热键
!dskheap;.printf "\n\n\n|No|ETHREAD |PWND |Modifier|wFlags | VK| (hex)ID| (dec)ID|phkNext |EPROCESS|(dec)PID| ImageFileName|\n";r $t0=1;r $t1=dwo(win32k!gphkFirst);.while(@$t1>0){.printf "|%2d",@$t0;.printf "|%08X|",@$t1;.printf "%08X|",dwo(@$t1+0n4);.printf "%8X|",low(dwo(@$t1+0n8));.printf "%8X|",hi(dwo(@$t1+0n8));.printf "%8X|",dwo(@$t1+0n12);.printf "%8X|%8d|",dwo (@$t1+0n16),dwo(@$t1+0n16);.printf "%08X|",dwo(@$t1+0n20);.printf "%08X|",dwo(dwo(@$t1))+0x220;.printf "%8d|",poi(poi(dwo (dwo(@$t1))+0x220)+0x84);;.printf "%16ma|\n",poi(dwo(dwo(@$t1))+0x220)+0x174;r $t1=dwo(@$t1+0n20);r $t0=@$t0+1;}
|No|ETHREAD |PWND |Modifier|wFlags | VK| (hex)ID| (dec)ID|phkNext |EPROCESS|(dec)PID| ImageFileName|
| 1|E2834418|BBE68848| 6| 0| C0| C01A| 49178|E1D57370|8645ADB8| 1316| explorer.exe|
| 2|E1D57370|BBE68848| 3| 0| 4A| 3| 3|E27C3918|8645ADB8| 1316| explorer.exe|
| 3|E27C3918|BBE68848| 3| 0| BD| 2| 2|E18923B8|8645ADB8| 1316| explorer.exe|
| 4|E18923B8|BBE68848| 3| 0| 44| 1| 1|E295A118|8645ADB8| 1316| explorer.exe|
| 5|E295A118|BBE68848| 3| 0| 49| 0| 0|E28D86F0|8645ADB8| 1316| explorer.exe|
| 6|E28D86F0|BBE6A058| 2| 0| 1B| F130| 61744|E2B7C800|86C13D40| 1316| explorer.exe|
| 7|E2B7C800|BBE68848| 8| 0| 42| 1FF| 511|E2A19588|8645ADB8| 1316| explorer.exe|
| 8|E2A19588|BBE68848| 8| 0| 44| 1FE| 510|E2A3A168|8645ADB8| 1316| explorer.exe|
| 9|E2A3A168|BBE68848| 8| 0| 13| 1FD| 509|E1A0F4D0|8645ADB8| 1316| explorer.exe|
|10|E1A0F4D0|BBE68848| C| 0| 9| 1FC| 508|E28E04F0|8645ADB8| 1316| explorer.exe|
|11|E28E04F0|BBE68848| 8| 0| 9| 1FB| 507|E28FF208|8645ADB8| 1316| explorer.exe|
|12|E28FF208|BBE68848| A| 0| 46| 1FA| 506|E28B8540|8645ADB8| 1316| explorer.exe|
|13|E28B8540|BBE68848| 8| 0| 46| 1F9| 505|E2960190|8645ADB8| 1316| explorer.exe|
|14|E2960190|BBE68848| 8| 0| 45| 1F8| 504|E1A9A4E8|8645ADB8| 1316| explorer.exe|
|15|E1A9A4E8|BBE68848| 8| 0| 70| 1F7| 503|E1D239E8|8645ADB8| 1316| explorer.exe|
|16|E1D239E8|BBE68848| C| 0| 4D| 1F6| 502|E294BB38|8645ADB8| 1316| explorer.exe|
|17|E294BB38|BBE68848| 8| 0| 4D| 1F5| 501|E296A468|8645ADB8| 1316| explorer.exe|
|18|E296A468|BBE68848| 8| 0| 52| 1F4| 500|E2872E28|8645ADB8| 1316| explorer.exe|
|19|E2872E28|BBE326C0| 8| 0| 55| 6| 6|E1FEC800|86C867A0| 576| winlogon.exe|
|20|E1FEC800|BBE326C0| 8| 0| 4C| 5| 5|E1882610|86C867A0| 576| winlogon.exe|
|21|E1882610|BBE326C0| 6| 0| 1B| 4| 4|E1817460|86C867A0| 576| winlogon.exe|
|22|E1817460|BBE326C0| 3| 8000| 2E| 0| 0|E1A62308|86C867A0| 576| winlogon.exe|
|23|E1A62308|00000001| 4| 0| 7B|FFFFFFFA| -6|E187F350|86CE19F8| 552| csrss.exe|
|24|E187F350|00000001| 0| 0| 7B|FFFFFFFB| -5|E27DDC80|86CE19F8| 552| csrss.exe|
|25|E27DDC80|00000001| 8| 0| 0|FFFFFFF9| -7|00000000|86CE19F8| 552| csrss.exe|
方法2:用户模式调试,虽然比较笨拙还凑合用...
win32k.sys不同版本首地址不同,如何查找这个地址?不做内核调试能不能查出来呢?
思路是把这个win32k.sys拷贝到新的文件,编写程序直接调用这个新文件来加载到内存进行调试
// c:/windows/system32/win32k.sys 拷贝到程序目录下
HINSTANCE hwin32kDll = ::LoadLibrary( "./win32k.sys" );
if(!hwin32kDll) return 0;
ULONG offset = 0x00e30cdc - 0x00da0000; // ver 5.1.2600.6334 (xpsp_sp3_gdr.130104-0421)
^^^^^^^^ ^^^^^^^^
ULONG newAdd = (ULONG)hwin32kDll + offset;
ULONG gphkFirst = *(ULONG*)( newAdd );
char buf[100];
sprintf(buf,"baseDLL = %08X offset = %08X phkFirst [%08X] = %08X",
hwin32kDll,offset,newAdd,gphkFirst);
MessageBox(0,buf,"gphkFirst",0);
然后用windbg调试,运行弹出对话框之后输入
--->xp-sp3
0:002> dd win32k
00da0000 00905a4d 00000003 00000004 0000ffff
^^^^^^^^
>uf win32k!FindHotKey
...
win32k!FindHotKey+0x7f:
00e30cdb a3d80b9bbf mov dword ptr ds:[BF9B0BD8h],eax
^^^^^^^^ ^^^^^^^^
...
这里的 BF9B0BD8 就是首地址
--->win8
0:003> dd win32k
00010000 00905a4d 00000003 00000004 0000ffff
00010010 000000b8 00000000 00000040 00000000
0:003> uf win32k!FindHotkey
win32k!FindHotKey+0x14:
000c2af2 0fb6c1 movzx eax,cl
000c2af5 8b3485b0153100 mov esi,dword ptr win32k!gphkHashTable (003115b0)[eax*4]
^^^^^^^^
0:003> dd win32k!gphkHashTable
003115b0 00000000 00000000 00000000 00000000
003115c0 00000000 00000000 00000000 00000000