A forum for reverse engineering, OS internals and malware analysis 

Ask your beginner questions here.
 #12310  by iSecure
 Sat Mar 24, 2012 11:08 am
Hi there

I'm wondering how tools like RKU, Kernel Detective, etc are retrieving list of unloaded drivers? Are they using 'MmUnloadedDrivers' kernel variable? Or does some another options exist? And does structure of this objects (unloaded modules) similar to well-known structure '_(K)LDR_DATA_TABLE_ENTRY'?

Thanks.
 #12311  by EP_X0FF
 Sat Mar 24, 2012 11:18 am
Hello,

public rku does not have such feature. However yes, technique is simple. debugger_data-> MmUnloadedDrivers, array etc.

System structure below.
Code: Select all
typedef struct _UNLOADED_DRIVERS {
    UNICODE_STRING Name;
    PVOID StartAddress;
    PVOID EndAddress;
    LARGE_INTEGER CurrentTime;
} UNLOADED_DRIVERS, *PUNLOADED_DRIVERS;
Code: Select all
#define MI_UNLOADED_DRIVERS 50 //nt5.x
 #12312  by iSecure
 Sat Mar 24, 2012 11:26 am
Thanks for quick reply, EP_X0FF.

Is this
Code: Select all
#define MI_UNLOADED_DRIVERS 50 //nt5.x
a maximum array size, which hold such information?

If right, what happens when 51 driver was unloaded? Buffer shifts, and forgets about 1-st unloaded driver?
 #12313  by EP_X0FF
 Sat Mar 24, 2012 11:32 am
iSecure wrote:Is this
Code: Select all
#define MI_UNLOADED_DRIVERS 50 //nt5.x
a maximum array size, which hold such information?
Yes.
If right, what happens when 51 driver was unloaded? Buffer shifts, and forgets about 1-st unloaded driver?
there is global MmLastUnloadedDriver counter, which increments after adding elements to array.
Code: Select all
 if (MmLastUnloadedDriver >= MI_UNLOADED_DRIVERS) {
        MmLastUnloadedDriver = 0;
    }
    Entry = &MmUnloadedDrivers[MmLastUnloadedDriver];

    //
    // Free the old entry as we recycle into the new.
    //
    RtlFreeUnicodeString (&Entry->Name);
 #12314  by iSecure
 Sat Mar 24, 2012 11:38 am
So it possible to delete all information about recently unloaded modules by just
Code: Select all
MmLastUnloadedDriver = 0;
?

Are there any known rootkits that manipulate this 2 kernel variables?
 #12315  by EP_X0FF
 Sat Mar 24, 2012 11:52 am
If you zero this value then list will stay alive. It will be simple forced to be rebuilt with new unloaded modules without reaching current limit.
Are there any known rootkits that manipulate this 2 kernel variables?
Do not remember such. Unloaded modules feature AFAIK exists only in KeDetective and kernel debuggers. And MmLastUnloadedDriver is unexported variable. You can simple zero pointer to array. Windows should reallocate whole array if pointer is NULL. Remembering unloaded modules does not work if MmSnapUnloads internal variable that is set to FALSE if (e.g. safebooting).
 #12316  by iSecure
 Sat Mar 24, 2012 12:05 pm
Hm, my WinDbg don't resolve 'MmSnapUnloads' variable, but nevermind.

And i found some strange behavior:
Code: Select all
Unloaded modules:
930eb000 93155000   spsys.sys
88ba4000 88bb1000   crashdmp.sys
88bb1000 88bbb000   dump_storport.sys
88bbb000 88bd3000   dump_LSI_SAS.sys
88bd3000 88be4000   dump_dumpfve.sys
885ec000 885f5000   vmdebug.sys
6b9f0000 6bc28000   wpdshext.dll
73db0000 73f40000   gdiplus.dll
70c60000 70c92000   WINMM.dll
6e8e0000 6f35c000   ieframe.dll
75880000 75a79000   iertutil.dll
72020000 7205c000   OLEACC.dll
6fca0000 6fcce000   shdocvw.dll
= 13 modules by WinDbg
Code: Select all
0: kd> dd mmlastunloadeddriver l1
8298680c  0000000a
= 10 modules

Who lies? This is Windows 7 if this matters.

And is this array protected by any lock? I'm going to manipulate this array for academic purposes.
 #12317  by EP_X0FF
 Sat Mar 24, 2012 12:16 pm
See MiRememberUnloadedDriver in WinDbg. Internally it called from MmUnloadSystemImage. Serialization is provided by the caller.