JustasMasiulis / lazy_importer

library for importing functions from dlls in a hidden, reverse engineer unfriendly way
Apache License 2.0
1.62k stars 219 forks source link

Add kernel mode support #30

Closed hzqst closed 4 years ago

JustasMasiulis commented 4 years ago

I'd add some parts of this under a macro, but I'm not sure how I am feeling about the approach overall.

SpriteOvO commented 4 years ago

If don't use MmIsAddressValid, it will read the session space address on traversal, which will trigger a BSOD. (For example, reading win32k.sys when traversing in DriverEntry will trigger BSOD)

While I'm not sure if MmIsAddressValid is effective at avoiding session addresses either, I think another solution would be to just determine the module name hash, since the driver needs to import very few modules.

JustasMasiulis commented 4 years ago

I think another solution would be to just determine the module name hash, since the driver needs to import very few modules.

That's what I'd also recommend and it is supported.

I think I could add another function to lazy_module that allows you to pass your own pointer to LDR_DATA_TABLE_ENTRY allowing you to do something like this:

driver_section = DriverObject->DriverSection;
g_ntoskrnl = LI_MODULE("ntoskrnl.exe").in(driver_section);

LI_FN(ExAllocatePoolWithTag).in(g_ntoskrnl)
or
#define NT_FN(name) LI_FN(name).in(g_ntoskrnl)

Also in the near future there will be a v3 of the API that cleans some stuff up and this would probably become a single line

// no guarantees but should be somewhat similar
LI(ExAllocatePoolWithTag, li::ldr(driver_section), li::mod("ntoskrnl.exe"))
hzqst commented 4 years ago

I think another solution would be to just determine the module name hash, since the driver needs to import very few modules.

That's what I'd also recommend and it is supported.

I think I could add another function to lazy_module that allows you to pass your own pointer to LDR_DATA_TABLE_ENTRY allowing you to do something like this:

driver_section = DriverObject->DriverSection;
g_ntoskrnl = LI_MODULE("ntoskrnl.exe").in(driver_section);

LI_FN(ExAllocatePoolWithTag).in(g_ntoskrnl)
or
#define NT_FN(name) LI_FN(name).in(g_ntoskrnl)

Also in the near future there will be a v3 of the API that cleans some stuff up and this would probably become a single line

// no guarantees but should be somewhat similar
LI(ExAllocatePoolWithTag, li::ldr(driver_section), li::mod("ntoskrnl.exe"))

Using name hash for "ntoskrnl.exe" is not safe for some versions of Windows ("ntkrnlmp.exe" , "ntkrnlup.exe" or even customized boot options). (traversal index==0) is the most accurate way to get ntos.