donut icon indicating copy to clipboard operation
donut copied to clipboard

Only load PE imports if they are not already loaded

Open TheWover opened this issue 5 years ago • 6 comments

In the PE loader, add a routine that checks the PEB to look for the base address of imported modules to see if they are already loaded. If they are, use the copy in memory and avoid every calling LoadLibrary for them. This creates the possibility of avoiding generating image load / modload events for each import.

TheWover avatar Oct 07 '20 13:10 TheWover

Maybe we would event want to hook LoadLibrary in the PE module so that it performs this logic too when dynamically loading modules?

TheWover avatar Oct 07 '20 14:10 TheWover

An option to manually map those dependencies may also be nice. Definitely not something everyone would want, but would ensure you get 0 new modload events as a result of loading a PE. The manual mapping logic already exists in Donut.

Using Module Overloading / phantom DLL hollowing would take that a step further. Though at that point you do get modload events, just for decoy files rather than what you are actually loading. If we did this, the decoy module should be chosen from the list of already loaded modules. So that it looks like LoadLibrary was called on existing modules and doesn't generate any modload events for anomalous modules that the host process has never loaded before.

TheWover avatar Oct 07 '20 14:10 TheWover

Keep in mind that if you never call LoadLibrary the reference count of the module will not be incremented and if FreeLibrary happens to get called on it.

TheWover avatar Oct 07 '20 14:10 TheWover

Could just hook FreeLibrary to prevent it from unloading your modules. Point it to a list somewhere in memory that holds the list of modules it's not allowed to load.

TheWover avatar Oct 07 '20 14:10 TheWover

@TheWover a simpler solution is just to query the module list everytime you are thinking about doing a load and if the module is already loaded call LdrAddRefDll. You could also potentially manually increment LDR_DATA_TABLE_ENTRY->ReferenceCount which should prevent FreeLibrary from unloading the DLL, however, the loader adds references to the LDR_DDAG (dependency graph) so I'm not sure if this would be 100% stable.

Dewera avatar Dec 05 '20 00:12 Dewera

Update: The original idea has been implemented in dev for v1.0. I may implement Dewera's comment and use LdrAddRefDLL. This is a note to myself to try this out before v1.0 release.

TheWover avatar Dec 08 '22 21:12 TheWover