flat assembler
Message board for the users of flat assembler.

Index > Windows > add exception handling for win x64 driver loaded via ATSIV

Author
Thread Post new topic Reply to topic
Feryno



Joined: 23 Mar 2005
Posts: 509
Location: Czech republic, Slovak republic
Feryno 02 Aug 2013, 09:20
u37 asked me months ago to help him with adding support for exception handling for drivers loaded via ATSIV
Unlike MmLoadSystemImage used by OS when loading drivers, ATSIV loads drivers into memory which is not aligned at page boundary, PE32+ header is missing, exception handling is missing, driver is not in PsLoadedModuleList and maybe more and more things are missing also.

Exception handling for drivers in x64 is based on image ExceptionDirectory and is recorded in PsInvertedFunctionTable.
The table is a cache of exception directories and is sorted ascendent according virtual address of driver. OS finds corresponding exception handler quite fast, e.g. when the table has 100h members, the scan begins in the middle of table (80h-th item in the table) and then the algorithm decides whether continue in low or up half, so the second iteration tries to compare with 40h-th item or 0C0h-th item depending on the previous check and so on (so for 100h members in the table the corresponding member is found in 9 iterations or even less). Finding corresponding driver base is really fast even the table is full. Then OS gets address of Exception directory of the driver and handles exception according Exception directory.

some more detailed reading is available here:
http://uninformed.org/index.cgi?v=8&a=2&p=20
http://uninformed.org/index.cgi?v=6&a=1&p=16

So I realized that my task is to add record about driver into PsInvertedFunctionTable. The table is not exported and may be found in kernel if you have corresponding symbols. I had to develop a method how to find it by scanning kernel.
The problem with inserting a record about the driver into the table is in fact that at the moment of insertion, OS may attempt to do insertion of another driver, or OS may attempt to remove record of another driver. Not to produce mess in the table and crash, OS uses spinlock when accessing the table. Finding PsInvertedFunction table is difficult, but finding where to acquire/release spinlock for this resource is not possible without having symbols for the kernel.
So my method has small risk that you can corrupt the PsInvertedFunctionTable.
I tested everything under windows server 2003 x64 SP2, windows server 2008 R2 x64 SP1, windows server 2012 x64 and worked fine at me.
I let the source file also with redundant procedures (maybe someone will find something useful there) - e.g. when the table is full, overflow bit should be set and then OS may attempt to scan PsLoadedModuleList which is much more slower than iterate in PsInvertedFunctionTable. The slow way worked at me in the first 2 mentioned OS-es but produced always crash at the third mentioned OS.

The source code should be cleaned, but I won't have time/power to do that yet. Take it as a sample that something like this is possible with necessity to accept some small risk of BSOD (this is not acceptable in production drivers, but is OK for hobby reasons).

Btw. original drivers coming with OS use jumps to __C_specific_handler in exception handling procedure, but exception handling is working also with method shown by u37 (I'm guessing he ported it from method working in ring3).

Everything is in the file a05.asm and structures definitions are at the end of KMD64.inc


Description: something to play with - adding exception handler for x64 driver loaded by ATSIV
Download
Filename: manual_exception_handling_driver.zip
Filesize: 100.88 KB
Downloaded: 450 Time(s)

Post 02 Aug 2013, 09:20
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
yoshimitsu



Joined: 07 Jul 2011
Posts: 96
yoshimitsu 14 Aug 2013, 07:29
looks very interesting like the rest of your work, however, where did you actually get the ATSIV-loader I can't seem to find a download (it's included in your archive, but you didn't attach its readme or was it just a single exe?).
also some sites say ATSIV's signature has been revoked and thus it stopped working, I will later test it and study your source code :)
Post 14 Aug 2013, 07:29
View user's profile Send private message Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 509
Location: Czech republic, Slovak republic
Feryno 15 Aug 2013, 05:25
Hi yoshimitsu, I didn't get the ATSIV, u37 sent me it and I let everything in the package including ATSIV, I just added there a way to handle exceptions (sometimes driver want to RDMSR from some MSR which may cause exception, it is possible to avoid that by identifying CPU features using CPUID but you can't know which CPUs come in the feature and for what do we have exceptions).
I was consulting ATSIV signatures with u37 (whether my work here has a feature) and ATSIV seems to be possible to run in the feature (microsoft asked Verisign to remove keys but then the keys were restored). Anyway ATSIV runs fine at my win 2003 server x64 SP2, win 2008 server R2 x61 SP1, windows server 2012 x64.
Maybe it is hard to download ATSIV today, I'm guessing that some forces made internet search providers to block links.
I have an older ATSIV version in my harddisk archive if you want (PM then).
The sample posted here works but is better for studying kernel internals. E.g. it is possible to modify PsInvertedFunctionTable so then any exception is redirected to attacker (malware).
Post 15 Aug 2013, 05:25
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 509
Location: Czech republic, Slovak republic
Feryno 16 Sep 2013, 08:51
Quote:
The problem with inserting a record about the driver into the table is in fact that at the moment of insertion, OS may attempt to do insertion of another driver, or OS may attempt to remove record of another driver. Not to produce mess in the table and crash, OS uses spinlock when accessing the table. Finding PsInvertedFunction table is difficult, but finding where to acquire/release spinlock for this resource is not possible without having symbols for the kernel.
So my method has small risk that you can corrupt the PsInvertedFunctionTable.

the problem when modifying critical kernel structure shared among all CPUs can be solved without spinlocks in a way described in 'Subverting the Windows Kernel' by Greg Hoglund, James Butler
Chapter 7. Direct Kernel Object Manipulation
Hiding with DKOM
Synchronization Issues

the CPU doing modification of PsInvertedFunctionTable must increase IRQ to dispatch level (then no choice of rescheduling other task and interrupting the modification at current CPU) + it must force all other CPUs to increase IRQ to dispatch level, and other CPUs must wait at a barrier until the modification is done (when all CPUs reach the barrier they must signalize that fact and then the first CPU starts the modification and after it finishes it must signalize to the others to leave the barrier, restore IRQ and continue)

if someone needs it and is unable to implement it let me know
Post 16 Sep 2013, 08:51
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.