EasyHook LoadLibrary завершается сбоем

Я пытаюсь использовать EasyHook для обнаружения собственных вызовов LoadLibrary.

Он действительно обнаруживает загрузку библиотек, однако процесс приводит к зависанию. Это связано с тем, что метод LoadLibrary_Hook ниже не может загрузить dll или библиотеку, поскольку он возвращает 0 IntPtr (вероятно, не может найти библиотеку).

Я даже попытался установить для событий тип «void», но затем процесс просто вылетел, вероятно, потому, что EasyHook ожидает, что я верну значение для перезаписи функции.

Есть ли у меня способ вернуть именно ту библиотеку, которая должна быть загружена, или просто получить имя загружаемой библиотеки без необходимости загружать библиотеку вручную?

(Есть также такие имена, которые загружаются в процессе: 瑮 汤 ⹬ 汤 l 邐 邐 讐 嗿  謘 ౕ㍓ 觬  嶉 觰 㯨 ࿓ ă 謀 ࡅ 쌻 萏 Ͽ 䶋 㬔 瓋 㤉 ᡝ 萏 ϯ 팻 Ѵ᪉ ᢉ 疋 㬐 ࿳ ă 㬀 瓋 謇 ᡅ ᦉ ᢉ 綋 что довольно странно ...)

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);
}

person DreTaX    schedule 31.07.2018    source источник
comment
Перехват LoadLibrary с использованием управляемого кода кажется действительно хорошим способом полностью обострить ваш процесс, потому что, даже если бы он работал идеально, вы, вероятно, закончили бы запуском управляемого кода в местах, где среда выполнения не ожидает его запуска. Если все, что вам нужно сделать, это определить, когда они загружены, разумным способом сделать это будет использование ETW для отслеживания событий загрузки библиотеки (как обсуждалось здесь). Если вы действительно хотите перенаправить загруженные библиотеки, все, что я могу посоветовать, это: не используйте или используйте выделенный процесс хостинга CLR и пусть это сделает неуправляемый код.   -  person Jeroen Mostert    schedule 31.07.2018
comment
Итак, в принципе, эту ETW можно было бы как-то использовать также для обнаружения вызовов LoadLibrary?   -  person DreTaX    schedule 31.07.2018
comment
ETW не обнаружит вызовы самого LoadLibrary, а обнаружит, что библиотеки DLL загружаются в процессе (будь то явные вызовы LoadLibrary или иначе). Почти, но не совсем то же самое; это зависит от того, чего вы хотите.   -  person Jeroen Mostert    schedule 31.07.2018
comment
если LoadLibrary возвращает значение null, вам нужно позвонить GetLastError или Marshal.GetLastWin32Error, чтобы выяснить, почему, это обычная ситуация с winapi, это то, как вы выясняете, что пошло не так, мои Spidey Senses говорят мне, что это может быть проблема битвы   -  person TheGeneral    schedule 31.07.2018
comment
System.Console.WriteLine(Marshal.GetLastWin32Error()); также вы хотите установить SetLastError=true в свой dllImport, см. Этот stackoverflow .com / questions / 17918266 /   -  person TheGeneral    schedule 31.07.2018
comment
Похоже, что возврат вызова исходного метода с использованием адреса исходного метода не останавливает процесс смерти, а также загружает библиотеки, как задумано, без вмешательства. Спасибо за предложения!   -  person DreTaX    schedule 31.07.2018
comment
По крайней мере цель LdrLoadDll. В любом случае, в DLL есть подпрограмма, которая может зарегистрировать вам обратный вызов для перехвата загрузки DLL в контексте текущего процесса ... Никаких подключений не требуется.   -  person ImmortaleVBR    schedule 01.08.2018
comment
Почему LdrLoadDll? Какая рутина?   -  person DreTaX    schedule 01.08.2018
comment
LoadLibraryA/W ведет к LoadLibraryExA/W, что ведет к LdrLoadDll. Патч LdrLoadDll будет более эффективным - людям нужно будет удалить патч, полагаться на LdrpLoadDll (недокументированный и неэкспортированный) или вручную сопоставить DLL, чтобы обойти ваш патч. Они всегда могут использовать дубликат NTDLL, а затем полагаться на него, но независимо от всего этого, исправление LdrLoadDll делает его немного сложнее, чем если бы вы исправляли Win32 API.   -  person ImmortaleVBR    schedule 03.08.2018
comment
Anyway, there is routine under DLL which can register you a callback to intercept DLL loads under context of the current process - это тоже задокументировано. Подпрограмма экспортируется NTDLL.DLL и называется LdrRegisterDllNotification (LdrUnregisterDllNotification также доступна отмена регистрации). Он был представлен начиная с Windows Vista. Вы можете получить к нему доступ через статический импорт с использованием библиотеки NTDLL (ntdll.lib) или динамический импорт. Если вы решите использовать эту процедуру и выберете статический импорт, ntdll.lib будет доступен с Windows Driver Kit (WDK).   -  person ImmortaleVBR    schedule 03.08.2018
comment
LdrRegisterDllNotification против LdrLoadDll? Какой из них будет безопаснее использовать против людей?   -  person DreTaX    schedule 03.08.2018


Ответы (1)


Решением было вызвать исходный метод с использованием исходного адреса функции:

public IntPtr LoadLibrary_Hook(string lpFileName)
{
    Logger.Log("File load: " + lpFileName);
    LoadLibraryDelegate origMethod = (LoadLibraryDelegate)Marshal.GetDelegateForFunctionPointer(LoadLibraryAddress, typeof(LoadLibraryDelegate));
    return origMethod(lpFileName);
}
person DreTaX    schedule 31.07.2018