.::SCHiM::. (07-12-2011),Void (07-12-2011)
Been reading up on SCHiMs hooking tuts in the CA section and decided to write a base to hook loadlibrary and filter out some unsavory dlls being injected.
Obviously, this will only work if an injector is using the standard LoadLibrary calling method (which most do, seeing as everyone leeches the same source).
Basically all this does is filter the .dlls being injected against a list of accepted .dll names. As I said at the beginning, this is a base...not to be used as-is as getting around it is a simple matter of renaming your injected file to one that the program uses (i.e just rename any file to d3d9.dll and you'll get around this) but a more useful way would to create a list of SHA256 hashes or MD5s or something, then do a quick hash of every file as it comes in, and compare. Either that or use the absolute paths instead of just the filenames, but still seems a tad sketchy to me.
The "in_array" method is of course not optimized, using a simple sequential sort 'cos I was too lazy to write a sorting and binary searching method.
Anyway, comments are welcome, day 2 of C++ so I hope I'm not doing too badly
Cheers.Code:#include <windows.h> #include <string> /*** GLOBALS ***/ DWORD numberOfSafeMods = 1; //number of safe modules (must match the SafeModules array) LPCSTR SafeModules[] = {"d3d9.dll"}; //your safe modules, woeful protection, but it's the building block...could replace this list with SHA256 hashes or w/e. DWORD *CurrentPtr; //the LoadLibrary pointer. DWORD LoadLibraryAddress; //the value that the LoadLibrary pointer is SUPPOSED to point to :P /** METHOD SIGNATURES **/ void main(); void SetPointer(DWORD*,DWORD*); void SetHook(); void __stdcall LoadLibraryHook(LPCSTR); bool in_array(LPCSTR[], LPCSTR, int); /** METHODS **/ BOOL APIENTRY DllMain(HMODULE hMod, DWORD dwReason, LPVOID homo) { if (dwReason == DLL_PROCESS_ATTACH) { //kick off the main method. CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&main, NULL, NULL, NULL); return TRUE; } } void main() { SetHook(); //make CurrentPtr point to our function. LoadLibraryAddress = *CurrentPtr; //now I'll store the value that LoadLibrary originally pointed to, so we can use it again. SetPointer(CurrentPtr, (DWORD*)&LoadLibraryHook); //make the LoadLibrary pointer point to our function instead. } void __stdcall LoadLibraryHook(LPCSTR hModule) { //in this case I just compared file names (not paths), it's way too easy to detour this if you knew that it //only checked names, because you can have multiple files with the same names. A better way would be to //create a list of accepted MD5s /SHA1's, but cbf figuring out how to calculate an MD5 in C++. std::string rawName = std::string(hModule); rawName = rawName.substr(rawName.find_last_of("\\") + 1); LPCSTR Filename = (const char*)rawName.c_str(); if (in_array(SafeModules, Filename, numberOfSafeMods)) //if it's a safe module.. { SetPointer(CurrentPtr, (DWORD*)LoadLibraryAddress); //make the LoadLibrary pointer point to the correct location. LoadLibrary(hModule); //call LoadLibrary (without our hook interupting) SetPointer(CurrentPtr, (DWORD*)&LoadLibraryHook); //set the hook back to redirect any other LoadLibrary calls. } } void SetPointer(DWORD *Address, DWORD *Hook) { *Address = (DWORD)Hook; //set the value that Address points to point at Hook. return; } void SetHook() { _asm { lea eax, LoadLibrary; mov CurrentPtr, eax; } } bool in_array(LPCSTR haystack[], LPCSTR needle, int sz) { //sz is the number of elements in the haystack array. //check if the needle is in the haystack, straightforward sequential searching. for(int i = 0; i < sz ; i++) { if (strcmp(haystack[i], needle) == 0) { return true; } } return false; //if we made it here without returning true, we couldn't find it so return false. }
You can win the rat race,Originally Posted by Jeremy S. Anderson
But you're still nothing but a fucking RAT.
++Latest Projects++
[Open Source] Injection Library
Simple PE Cipher
FilthyHooker - Simple Hooking Class
CLR Injector - Inject .NET dlls with ease
Simple Injection - An in-depth look
MPGH's .NET SDK
eJect - Simple Injector
Basic PE Explorer (BETA)
.::SCHiM::. (07-12-2011),Void (07-12-2011)
NICE! I have never thought of using this hook like that, however are you sure it works? Have you tested it? I can no longer clearly remember how that dll injection trick worked, but didn't it involve searching and calling the LoadLibrary() externaly? Like bypassing the pointer you're using to hook??
I'm SCHiM
Morals derive from the instinct to survive. Moral behavior is survival behavior above the individual level.
Polymorphic engine
Interprocess callback class
SIN
Infinite-precision arithmetic
Hooking dynamic linkage
(sloppy)Kernel mode Disassembler!!!
Semi debugger
An injector generally uses the pointer to LoadLibrary inside it's own address space, so you would have to detour LoadLibrary instead of just set the pointer to your hook.
Also, a windows thread uses a function:
, notCode:DWORD CALLBACK (__stdcall) FunctionName(LPVOID Parameter);
Code:void main();
Nice job, but needs some work.
Yeah I forgot about the main, was originally making this as a Console App so I could test as I went along, forgot to switch that back when I went back to a .dll.
And yeah, you're right now I think about it, the LoadLibrary address is calculated relative to the injectors LoadLibrary function. Still, there should be a way to get around that, guess I'd have to use the jump hook from part 1 schim hehe. So i could jump from the actual LoadLibrary function rather than the pointer.
BUGGER, why didn't I think this through
Ah well, helped me get more familiar with this particular brand of hooking, guess I'll have to progress to the jmp hook at some point. I only tested this by calling LoadLibrary internally. Wonder if you could just shift the whole LoadLibrary function to a different section of memory, then write my hook to the address it previously occupied.
Would be rad.
You can win the rat race,Originally Posted by Jeremy S. Anderson
But you're still nothing but a fucking RAT.
++Latest Projects++
[Open Source] Injection Library
Simple PE Cipher
FilthyHooker - Simple Hooking Class
CLR Injector - Inject .NET dlls with ease
Simple Injection - An in-depth look
MPGH's .NET SDK
eJect - Simple Injector
Basic PE Explorer (BETA)
Can you please explain this to me a bit more, i am so not familiar with getting the address of a function in the method you showed , but anyway .. it seems that you are then making it point to an INT, then changing that INT , amongst many other things .. to me it really doesn't look like a detour if thats supposed to be what it is .. i'm confused
EDIT : Why do you get the address of LoadLibrary by using the word "LoadLibrary" in asm , its that easy? i've always known to call GetProcAddress to obtain this
FURTHER EDIT :
void SetPointer(DWORD *Address, DWORD *Hook)
{
*Address = (DWORD)Hook; //set the value that Address points to point at Hook.
return;
}
void SetHook()
{
_asm
{
lea eax, LoadLibrary;
mov CurrentPtr, eax;
}
}
SetPointer(CurrentPtr, (DWORD*)&LoadLibraryHook);
Is all saying really that you are doing this :
*LoadLibrary = (DWORD)&LoadLibraryHook;
My question : how is that one line enough to detour the LoadLibrary function .. really ??
EDIT : AFK reading the SCHiMs hooking tuts in the CA sectio
EDIT : AFter reading the guide , i take back most of what i said , it just didn't occur to me that such a pointer would be stored so simply in the .data section :S .. the only thing which i think is a little confusing to teh reader is treating that pointer, as a pointer to int, when in fact its a pointer to function, which means that the data it points to is the start of a function ..
Much appreciation for the knowledge, i learnt something today :P
Last thing! does this only work for staticly linked libraries?
Last edited by d3nd3; 08-03-2011 at 06:05 AM.
yes doesn't sound much to me.. i'm used to years
FBIRyan (08-06-2011)