-1

I am trying to use EasyHook to detect native LoadLibrary calls.

It indeed detects the loading of libraries, however the process results in freezing. This is because the LoadLibrary_Hook method below cannot load the dll or library since It returns 0 IntPtr (Probably can't find the library.).

I even tried setting the events to a "void" type but then the process simply crashes, this is probably because EasyHook expects me to return a value to overwrite the function.

Is there a way for me to return the exactly needed library to be loaded, or just simply get the name of the library that is being loaded without me having to load the library manually?

(There are also names like this which are loading in the process: 瑮汤⹬汤l邐邐讐嗿謘ౕ㍓四襗ﱝ嶉觬嶉觰嶉㯨࿓トă謀ࡅ쌻萏Ͽ䶋㬔瓋㤉ᡝ萏ϯ팻Ѵ᪉ᢉ疋㬐࿳ă㬀瓋謇ᡅᦉᢉ綋㬜 which is kinda odd...)

private static LocalHook hook;

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr LoadLibrary(string lpFileName);

[DllImport("kernel32.dll", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)]
public static extern IntPtr GetProcAddress(IntPtr handle, string varormethodname);

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
public delegate IntPtr LoadLibraryDelegate(string lpFileName);

public TestHook()
{
    IntPtr kernel32 = GetModuleHandle("kernel32.dll");
    Logger.Log("Kernel: " + kernel32);
    IntPtr address = GetProcAddress(kernel32, "LoadLibraryA");
    Logger.Log("Address: " + address);

    hook = LocalHook.Create(address,
    new LoadLibraryDelegate(LoadLibrary_Hook),
    null);
    hook.ThreadACL.SetExclusiveACL(new Int32[] {0});

    //RemoteHooking.WakeUpProcess();
}


public IntPtr LoadLibrary_Hook(string lpFileName)
{
    Logger.Log("File load: " + lpFileName);
    return LoadLibrary(lpFileName);
}
DreTaX
  • 760
  • 2
  • 9
  • 22
  • 1
    Hooking `LoadLibrary` using managed code seems like a really good way to completely hose your process, because even if it worked perfectly, you'd probably end up running managed code in spots where the runtime isn't expecting it to run. If all you want to do is detect when they're loaded, a sane way to do this would be using ETW to trace the library load events instead (as discussed [here](https://stackoverflow.com/a/33132492/4137916)). If you actually want to redirect loaded libraries, then all I can advise is: don't, or use a dedicated CLR hosting process and have unmanaged code do it. – Jeroen Mostert Jul 31 '18 at 11:51
  • So basically this ETW could be used somehow to detect LoadLibrary calls also? – DreTaX Jul 31 '18 at 12:03
  • ETW would not detect the calls to `LoadLibrary` itself, it would detect DLLs getting loaded in the process (whether through explicit `LoadLibrary` calls or otherwise). Almost, but not quite the same thing; it depends on what you want. – Jeroen Mostert Jul 31 '18 at 12:12
  • if `LoadLibrary` is returning null you need to call `GetLastError` or `Marshal.GetLastWin32Error` to work out why, this is a common winapi situation, its how you work out what went wrong, my Spidey Senses tells me this might be a bitness thing – TheGeneral Jul 31 '18 at 12:16
  • `System.Console.WriteLine(Marshal.GetLastWin32Error());` also you want to set `SetLastError=true` on your dllImport see this https://stackoverflow.com/questions/17918266/winapi-getlasterror-vs-marshal-getlastwin32error – TheGeneral Jul 31 '18 at 12:19
  • Seems like returning a call to the original method using the original method's address doesn't stop the process dying and it also loads the libs as intended without interfering. Thanks for the suggestions! – DreTaX Jul 31 '18 at 12:40
  • At-least target `LdrLoadDll`. Anyway, there is routine under DLL which can register you a callback to intercept DLL loads under context of the current process... No hooking required. – ImmortaleVBR Aug 01 '18 at 05:04
  • Why LdrLoadDll? What routine? – DreTaX Aug 01 '18 at 09:06
  • `LoadLibraryA/W` leads to `LoadLibraryExA/W` which leads to `LdrLoadDll`. Patching `LdrLoadDll` will be more effective - people will need to remove the patch, rely on `LdrpLoadDll` (undocumented and non-exported) or manually map a DLL to bypass your patch. They can always use a duplicate of `NTDLL` as well and then rely on that, but regardless of all of this, patching `LdrLoadDll` makes it a tad harder than if you were patching the Win32 API. – ImmortaleVBR Aug 03 '18 at 05:33
  • `Anyway, there is routine under DLL which can register you a callback to intercept DLL loads under context of the current process` - it's documented as well. The routine is exported by `NTDLL.DLL` and it is named `LdrRegisterDllNotification` (`LdrUnregisterDllNotification` to unregister is also available). It was introduced starting on Windows Vista. You can access it through a static import using the NTDLL library (ntdll.lib) or a dynamic import. If you choose to use this routine and go for a static import, ntdll.lib is available with Windows Driver Kit (WDK). – ImmortaleVBR Aug 03 '18 at 05:37
  • https://learn.microsoft.com/en-gb/windows/desktop/DevNotes/ldrregisterdllnotification and https://learn.microsoft.com/en-gb/windows/desktop/DevNotes/ldrunregisterdllnotification – ImmortaleVBR Aug 03 '18 at 05:39
  • LdrRegisterDllNotification vs LdrLoadDll? Which one would be safer to use against people? – DreTaX Aug 03 '18 at 11:17

1 Answers1

0

Solution was to call the original method using the original function address:

public IntPtr LoadLibrary_Hook(string lpFileName)
{
    Logger.Log("File load: " + lpFileName);
    LoadLibraryDelegate origMethod = (LoadLibraryDelegate)Marshal.GetDelegateForFunctionPointer(LoadLibraryAddress, typeof(LoadLibraryDelegate));
    return origMethod(lpFileName);
}
DreTaX
  • 760
  • 2
  • 9
  • 22