Shadow SSDT detailed, WinDbg view Shadow SSDT

Source: Internet
Author: User
Tags ssdt



First. Acquisition of SHADOWSSDT



Well, we've already got the original address of SSDT in R3 and the SDT, SST, and Kiservicetbale relationships mentioned: All SST is stored in the System Service Description table (SDT). There are two SDT in the system, one is servicedescriptortable and the other is Servicedescriptortableshadow. The Servicedescriptor only points to the Kiservicetable SST, while Servicedescriptortableshadow contains all two SST. SSDT is accessible, and Ssdtshadow is not public.



So the conclusion is that servicedescriptortable is derived, and Servicedescriptortableshadow is not exported. So we're not going to get Servicedescriptortableshadow's address? Not exported may not be available. In fact, in keaddsystemservicetable this export function is a Servicedescriptortableshadow address. Let's take a look at the disassembly.






We can see that the servicedescriptortable address and Servicedescriptortableshadow are found in this function.



In fact, Keservicedescriptortableshadow contains 4 sub-structures, the first of which is Ntoskrnl.exe (native API), and keservicedescriptortable points to the same What we really need to get is the second Win32k.sys (Gdi/user support), the third and fourth are generally not used.



How to locate Servicedescriptortableshadow?



① Hard-coded:



For XP
if (GKERNELVERSION==WINXP)
keservicedescriptortableshadow=keservicedescriptortable-0x40;
for 2k
if (gkernelversion==win2k)
KESERVICEDESCRIPTORTABLESHADOW=KESERVICEDESCRIPTORTABLE+0XE0;



For Win7 32



if (gkernelversion==win7x86)
keservicedescriptortableshadow=keservicedescriptortable+0x40;



② Search by Keaddsystemservicetable





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21st
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
ULONG getaddressofshadowtable()
{
ULONG I;
UCHAR*P;
ULONG Dwordatbyte;

Unicode_string uskeaddsystemservicetable;

Rtlinitunicodestring(&Uskeaddsystemservicetable,L"Keaddsystemservicetable");

P= (UCHAR*)Mmgetsystemroutineaddress(&Uskeaddsystemservicetable);

for (I= 0;I< 4096;I++,P++)
{
__try
{
Dwordatbyte= *(ULONG*)P;
}__except(Exception_execute_handler)
{
return 0;
}

if(Mmisaddressvalid((PVOID)Dwordatbyte))
{
if(memcmp((PVOID)Dwordatbyte,Keservicedescriptortable, -) == 0)//Compare what the address points to
{
if((PVOID)Dwordatbyte==Keservicedescriptortable)
{
Continue;
}
returnDwordatbyte;
}
}
}
return 0;
}







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21st
22
Pulong GetAddressOfShadowTable2()
{
Puchar Buff;
Puchar P;
Unicode_string uskeaddsystemservicetable;
Pulong shadowtable=Null;

Rtlinitunicodestring(&Uskeaddsystemservicetable,L"Keaddsystemservicetable");
Buff= (Puchar)Mmgetsystemroutineaddress(&Uskeaddsystemservicetable);
for(P=Buff;P<Buff+Page_size;P++)
{
if(Mmisaddressvalid((PVOID)P))
{
if((*(Pushort)P== 0x888d) && (*(P+6) == 0x83))
{
Shadowtable= (Pulong)(P+2);
Break;
}
}
}
returnShadowtable?Shadowtable:Null;
}





After obtaining the address of Keservicedescriptortableshadow, we use WinDbg to look at the array of functions stored in SHADOWSSDT.






We see that there are Ntoskrnl.exe service function tables in Keservicedescriptortableshadow as well as Win32k.sys service function tables.



Then let's take a look at the array of Win32k.sys's service Function table.






A whole bunch of???????? is because the address of the function inside the SHADOWSSDT cannot be accessed.



Many of the online claims are that only GUI processes can access SHADOWSSDT. Let's try switching to the Explorer.exe process.



This will actually get the SHADOWSSDT function address.



Quote a passage from the Black Moon Leader's article.



MJ says Win32k.sys is related to the session, meaning that Win32k.sys can be accessed in session Leader (Csrss.exe) and in any process space that is part of the session.
WindowsXP System Services and the first logged-on user to share the same session, that is, session 0,vista/win7 used session isolation, system services using session 0, the first user to use session 1, and so on.
in both systems, this rule is adhered to. But there is a special process that does not belong to any session, which is session Manager (Smss.exe).
Switch to Smss.exe process space to see:



Kd> dt_eprocess 8501d3e8   imagefilename
nt!_eprocess
   +0x16c imagefilename: [15]& nbsp "Smss.exe"
kd> . Process 8501d3e8  
Implicit process is now 8501d3e8
WARNING:. Cache Forcedecodeuser is not enabled
kd> dd 8fc25000
bf800000???????????????? -?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800010???????????????? -?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800020???????????????? -?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800030???????????????? -?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800040???????????????? -?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800050???????????????? -?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800060???????????????? -?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800070???????????????? -?? ?? ?? ?? ?? ?? ?? ?? ????????????????



Kd>!pte 8fc25000
VA 8fc25000
PDE at c06023f0 PTEs at c047e128
Contains 0000000000000000
Not valid
In Session Manager's process space, Win32k.sys is also inaccessible because it does not belong to any one session.
Observe the process to see:





Other words In addition to the system process and the SMSS process, Win32k.sys can be accessed in any other part of the session process, not only by the GUI process.





Second, how to hook?



It seems that the problem is not large, shadow SSDT and SSDT are essentially 1 address tables, the simplest way is to replace your function with the Address table corresponding to the specific hook code can even completely copy SSDT, here are only a few small problems encountered.
1. Win32k.sys not always in memory, if not GUI thread, shadow SSDT address is invalid
Workaround:
1. Hook in the Driverdispatch
Driverdispatch is the thread context in which the Driveriocontrol is executed.
We use 1 GUI threads to Driveriocontrol
2. Attachtoprocess
Here we use the Explorer.exe process.





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21st
22
23
24
25
26
27
28
29
30
VOID Keattachcsrss()
{
NTSTATUS status;
Peprocess Exlorereproc;
Pkapc_state apcstate;
ULONG I;

Dbgprint("Getexploreridbyenumprocess ==>%d",Getexploreridbyenumprocess());

Dbgprint("keservicedescriptortableshadow=%x \ r\ n",Keservicedescriptortableshadow);
Dbgprint("count=%x \ r\ n",Keservicedescriptortableshadow -win32k.Numberofservice);
Dbgprint("servicetablebase=%x \ r\ n",Keservicedescriptortableshadow -win32k.Servicetablebase);

Status=Pslookupprocessbyprocessid((HANDLE)Getexploreridbyenumprocess(), &Exlorereproc);

if (!Nt_success(Status))
{
Dbgprint("Pslookupprocessbyprocessid () error\ n");
return ;
}
Apcstate= (Pkapc_state)ExAllocatePool(NonPagedPool, sizeof(Kapc_state));
Kestackattachprocess(Exlorereproc,Apcstate);

for (I=0;I<Keservicedescriptortableshadow -win32k.Numberofservice;I++)
{
Dbgprint("Index:%d, Address:%x, original address:%8x \ r\ n",I,Keservicedescriptortableshadow -win32k.Servicetablebase[I],Getshadowssdtfunctionoriaddr(I));
}

Keunstackdetachprocess(Apcstate);
}





The implementation of this method is getexploreridbyenumprocess by simply traversing the list of process activities.






Third. obtaining the name of the SHADOWSSDT function



The simpler one should be the design of a table of function names and the method of using symbol.



The simple reason for this is that I only need a win32k.sys,win32k.pdb, and I can get the job done by calling less than 10 APIs.
1. Call Syminitialize to initialize the function dbghelp this series.
2. Call Imageload to read the file Win32.sys.
3. Call Symloadmodule to read the PDB file.
4. Call the Symenumsymbols enumeration symbol, where one of the parameters is the callback function Symenumsymbolsproc,that ' s the key.
There is a system in Symenumsymbolsproc that will help populate a parameter for the PSYMBOL_INFO structure. My main use in this structure is name and address.
5. Call Imageunload and Symcleanup to do some cleanup work.
The first is to get the address of w32pservicetable. Familiarity with SHADOWSSDT knows that w32pservicetable is initialized in the kernel to populate the SHADOWSSDT table.
Then, knowing the address of the w32pservicetable, the following things are also easy. Use Symenumsymbolsproc to save the address and function name of each function SHADOWSSDT.



However, I do not recommend this method to get the SHADOWSSDT function address. PDB files also have a few m bar, but also to request the PDB file, but also depends on the network environment.



So it's better to use hard-coded ...



This article link: http://www.blogfshare.com/shadowssdt-explain-in-detail.html



JPG change rar



Shadow SSDT detailed, WinDbg view Shadow SSDT


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.