Hooking LoadLibrary API call - c++

I want to load a different version of a DLL than is present in the working directory of the application. For this I need to hook the LoadLibrary call so that when the application makes a call to load the DLL I can substitute it with the newer version of that DLL transparently. I tried using NCodeHook and have the following code in my DLL which I inject into the application using NInjectLib but it crashes while loading kernel32.dll. Can anybody please tell me if this is the correct way of injecting the call or are there any other alternatives.
// CodeHook.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <NCodeHookInstantiation.h>
#include "CodeHook.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
typedef HMODULE (WINAPI *LoadLibraryFPtr)(LPCTSTR dllName);
#pragma data_seg("SHARED")
LoadLibraryFPtr origFunc = NULL;
#pragma data_seg()
#pragma comment(linker, "/section:SHARED,RWS")
HMODULE WINAPI LoadLibraryHook(LPCTSTR dllName)
{
if (origFunc != NULL)
{
return origFunc(dllName);
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
CODEHOOK_API void Initialize (void)
{
NCodeHookIA32 nch;
origFunc = nch.createHookByName("kernel32.dll", "LoadLibrary", LoadLibraryHook);
}
#ifdef _MANAGED
#pragma managed(pop)
#endif

I don't know the NCodeHook library, but one important thing to know is that there are actually 2 versions of the LoadLibrary function: LoadLibraryA(LPCSTR) and LoadLibraryW(LPCWSTR). Make sure you hook the correct one and use the appropriate function definition. You may also need to hook LoadLibraryExA/LoadLibraryExW
Detours is a more widely known library for API hooking. Also see this article for more hooking techniques.

I had similar problems of crashes in kernel32.dll when using a hand-written hooking/detours library. I found a good explanation of the problem in the discussion pages of the MinHook library:
As far I understand it, your detour library does not account for the possibility that a function it tries to hook is implemented using a short jump opcode (apparently the LoadLibrary(Ex)W is implemented this way). This will lead to different bytes which need to be replaced during hooking.
Using MinHook for my hooking of LoadLibrary and friends works for me:
HMODULE WINAPI LoadLibraryA_replacement(_In_ LPCTSTR lpFileName)
{
// do your stuff
return loadLibraryA_original(lpFileName);
}
bool installLoadLibraryHook()
{
// Initialize MinHook.
if (MH_Initialize() != MH_OK)
return false;
if (MH_CreateHook(&LoadLibraryA, &LoadLibraryA_replacement,
reinterpret_cast<LPVOID*>(&loadLibraryA_original)) != MH_OK)
return false;
if (MH_EnableHook(&LoadLibraryA) != MH_OK)
return false;
// same for LoadLibraryW, LoadLibraryExW, LoadLibraryExA
return true;
}

There are lots of pitfalls associated with API hooking. I don't know specifics about the NCodeHook implementation, but there is potential for trouble if the API hooking code doesn't properly deal with non-writable pages. One would assume that the library would call VirtualProtect and that the OS would properly handle copy-on-write, but it's hard to say.
I agree with the comment that this might not be the best solution to your problem. API hooking relies on the application binary interface, which is quasi-documented at best. I would not recommend it for a commercial app that is intended for production use.
Side-by-side assemblies would definitely be useful, as the strong name removes any ambiguities about which DLL needs to be loaded. Alternatively, consider using LoadLibraryEx with an absolute path to the DLL and the LOAD_WITH_ALTERED_SEARCH_PATH flag.

Related

When is calling CoInitialize required for a Windows console application

The code below, derived from https://learn.microsoft.com/en-us/windows/desktop/shell/folder-info#determining-an-objects-parent-folder, works as expected when compiled and run via Visual Studios 2017:
#include "stdafx.h"
#include <shlobj.h>
#include <shlwapi.h>
#include <objbase.h>
#pragma comment(lib, "shlwapi")
int main()
{
IShellFolder *psfParent = NULL;
LPITEMIDLIST pidlSystem = NULL;
LPCITEMIDLIST pidlRelative = NULL;
STRRET strDispName;
TCHAR szDisplayName[MAX_PATH];
HRESULT hr;
hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem);
hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **)&psfParent, &pidlRelative);
if (SUCCEEDED(hr))
{
hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName);
hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName));
_tprintf(_T("%s\n"), szDisplayName);
}
psfParent->Release();
CoTaskMemFree(pidlSystem);
Sleep(5000);
return 0;
}
If I replace CSIDL_SYSTEM with CSIDL_MYDOCUMENTS, though, the GetDisplayNameOf method call fails with:
onecore\com\combase\objact\objact.cxx(812)\combase.dll!74EA3270: (caller: 74EA201B) ReturnHr(1) tid(d4c) 800401F0 CoInitialize has not been called.
onecoreuap\shell\windows.storage\regfldr.cpp(1260)\windows.storage.dll!76FE4FA3: (caller: 76E9F7EE) ReturnHr(1) tid(d4c) 80040111 ClassFactory cannot supply requested class
Adding CoInitialize(NULL); before the call to SHGetFolderLocation fixes the issue.
Why is calling CoInitialize required in one case but not the other?
Also, it seems like CoInitialize should always be called, but it's interesting that the sample code doesn't call it. I'm curious why this is the case. I couldn't get the sample code compiling as is - <iostream.h> couldn't be found, which is why I replaced the cout printing code with a call to _tprintf... Maybe that's an indication of the problem? Does the C++ runtime call CoInitialize for you, and maybe VS is trying to build a C application for me or something (like how on Linux, compiling with gcc and g++ has different implications).
As a rule, you should initialize COM/OLE before creating shell COM objects that inherit from IUnknown, use drag & drop etc. This also applies to functions that might use COM internally which could in theory be most of the SH* functions in shell32 and shlwapi.
Why did it work with CSIDL_SYSTEM?
The Windows 95 shell could run without loading COM/OLE. To do this it provided its own mini-COM implementation. Shell extensions could mark themselves as not requiring real COM and things implemented inside shell32 would call a special CoCreateInstance that tries to load things directly from shell32. This was to avoid loading ole32.dll because it is a very big file to load on a Intel 386 machine with 4 MiB of RAM (Windows 95 minimum requirements).
The IShellFolder implementation that deals with the filesystem is implemented in shell32 and does not require COM and is therefore able to handle a path like c:\Windows\system32.
CSIDL_MYDOCUMENTS however, is not a normal folder, it is a namespace extension and parts of its implementation is in mydocs.dll. And as you found out, parts of it does require COM.
All of this is of course a implementation detail and you should never assume that any of this is going to work without initializing COM.
SHGetFolderLocation may delegate execution to an extension that requires COM initialization. Although the documentation does not explicitly say so, you can find a remark about that for ShellExecute which is part of the same module (shell32.dll).
Because ShellExecute can delegate execution to Shell extensions (data
sources, context menu handlers, verb implementations) that are
activated using Component Object Model (COM), COM should be
initialized before ShellExecute is called. Some Shell extensions
require the COM single-threaded apartment (STA) type. In that case,
COM should be initialized as shown here:
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
There are certainly instances where ShellExecute does not use one of
these types of Shell extension and those instances would not require
COM to be initialized at all. Nonetheless, it is good practice to
always initalize COM before using this function.
You can use the following helper class to automatically initialize the COM library on the current thread.
class COMRuntime
{
public:
COMRuntime() {
::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
}
~COMRuntime() {
::CoUninitialize();
}
};
Then just declare one instance of that class:
int main()
{
COMRuntime com;
// the rest of your code
}

Why does Gplmpgdec (GPL MPEG-1/2 DirectShow Decoder Filter) override / detour IsDebuggerPresent?

In Mpeg2DecFilter.cpp the following code is present:
#include "detours.h"
DETOUR_TRAMPOLINE(BOOL WINAPI Real_IsDebuggerPresent(), IsDebuggerPresent);
BOOL WINAPI Mine_IsDebuggerPresent()
{
TRACE(_T("Oops, somebody was trying to be naughty! (called IsDebuggerPresent)\n"));
return FALSE;
}
...snip...
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if(!fDetourInited)
{
DetourFunctionWithTrampoline((PBYTE)Real_IsDebuggerPresent, (PBYTE)Mine_IsDebuggerPresent);
...snip...
fDetourInited = true;
}
return DllEntryPoint((HINSTANCE)hModule, ul_reason_for_call, 0); // "DllMain" of the dshow baseclasses;
}
I can't for the life of me figure out why Gplmpgdec would override IsDebuggerPresent to always return FALSE. What possible use could this serve?
The thing is, for me it's causing problems due to debugger messages not showing up and (sometimes) the application crashing if a trace message gets written when the Gplmpgdec DLL has been unloaded.
In order to decide how to deal with this problem, I think I really need to know why Gplmpgdec is doing this. Any suggestions regarding a solution are also welcome. I'd rather not have to maintain my own custom Gplmpgdec library though; that kind of maintenance headache I'd rather avoid at all cost. Is there perhaps a way to disable the detour?
Some DirectShow filters actually don't work (on purpose) when a debugger is present.
I'm not sure if this is a workaround for that by Gplmpgdec or if it is related to the other hooked function; ChangeDisplaySettingsEx. You can clearly see references to Macrovision in the code which they probably try to disable.
Media Player Classic/MPC-HC uses the same type of code and it makes more sense in a .exe then in a decoder library.
I was also surprised to see this code in an open source project.
I think it is just a sort of joke from the developer. If you look the message
Oops, somebody was trying to be naughty!
for me it's second degree, and maybe the developer had just discovered IsDebuggerPresent, and found it fun to use it...
I also remember that at the time of this codec, some video codecs prevented the debugging of a DirectShow application (using filtergraph). Maybe this developer came from one of these companies...
to deal with this problem, you just have to comment this code, and recompile it.

MFC app and shared libs

I have a application which seems has written in MFC (process hacker and DependencyWalker show link to MFC90).
Also, There is a library(FTD2XX) in the installation path. But the DependencyWalker won't show the MFC90 link for the lib and show:
SetupAPI.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll
In what framework the lib is built?
I don't have experience in MFC. I don't have information in its compiler and if VC++ libs can be used to link with MFC apps.
If you want to log calls going to a dll, the best way is to write a proxy dll (a dll redirection). But for that you must know the signature (syntax) of the function which you are going to override, i.e. exact number of parameters, their types and return type etc. If I can assume that you somehow can find out signature of all the functions in ftd2xx.dll, then it is merely simple to get it done.
Get dll functions and Ordinal numbers:
For this just use dumpbin.exe comes with Visual Studio (use it by running Visual Studio command prompt)
dumpbin.exe /exports {yourpath}\ftd2xx.dll > ftd2xx.txt
Now your ftd2xx.txt has all the function names and ordinal numbers of the ftd2xx.dll. You can even use your dependency walker to export and get this list.
Create you own dll named ftd2xx.dll:
Open Visual Studio, choose VC++ >> Win32 >> Win32 Project >> Dll (with Export symbols option) and finally use #pragma directive to declare all your exported original dll functions within your dll code like below,
//#pragma comment (linker, "/export:<function>=<origdll_name>.<function>,#<ordinal_number>")
#pragma comment (linker, "/export:FT_Open=ftd2xx_.FT_Open,#1")
#pragma comment (linker, "/export:FT_Close=ftd2xx_.FT_Close,#2")
// :
// :
// :
// delcare all your exported functions here with ordinal number
// :
// :
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
}
Now, you need to write your own function which can pretend as an original function of ftd2xx.dll which will get called when the application calls a original function of ftd2xx.dll. The below code is just to explain how it works. As I said earlier you need to know the exact signature of the dll functions which you want to override (redirect). And also keep in mind that you need to call the original function after whatever you wanted to do, otherwise you may endup having unexpected behaviour with your application.
Assuming FT_Close() function takes no parameter and returns void, I am putting this just for example in which I override FT_Close() function of ftd2xx.dll with a proxy NewFT_Close() function. Note that, if you override a function, then remove it from #pragma directive and add it in a .def file (add a new ftd2xx.def file to your project and declare your new functions like below).
DEF file example
LIBRARY ftd2xx.dll
EXPORTS
FT_Close = NewFT_Close #2
Dll code example
HINSTANCE hInstance = NULL; // handle to ftd2xx.dll
FARPROC fpFTClose = {NULL}; // function pointer to hold original function address
extern "C" void __stdcall NewFT_Close()
{
// This is our proxy function for FT_Close()
// Do whatever you want to do here and the
// finally call the original FT_Close() using
// the function pointer we got from GetProcAddress()
typedef void (__stdcall *PFTCLOSE)();
PFTCLOSE pFc = (PFTCLOSE)fpFTClose;
if(pFc) pFc();
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// Load the original dll in to the memory and get the handle
hInstance = LoadLibraryA("ftd2xx_.dll");
if(!hInstance) return FALSE;
// Get the address of the function to be overriden
fpFTClose = GetProcAddress(hInstance,"FT_Close");
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
// Our dll is getting unloaded from the application, unload original as well
FreeLibrary(hInstance);
break;
}
return TRUE;
}
Note that the original dll is referred as ftd2xx_.dll in LoadLibraryA() call. So, rename the original dll to ftd2xx_.dll or name it whatever you want. Build your proxy dll code and take your proxy dll (ftd2xx.dll) to the path where the original ftd2xx.dll present. Now, your application will call ftd2xx.dll (proxy) as usual, but ftd2xx.dll will call the original dll ftd2xx_.dll internally.
Update #1:
I kept mentioning that you need to know the signature of the functions your are trying to override, and by luck I just found the ftd2xx.h file in the linux version of the driver.
Linux version of ftd2xx
Download the libftd2xx-i386-1.3.6.tgz file from above link and extract it to a folder (I used 7zip), further extract the .tar file to get the release folder and you'll find ftd2xx.h file within the "release" folder. There you go, now you got complete function signatures of the dll and you know how to write a proxy dll. Good Luck.

Using GetProcAddress and EasyHook to hook class methods and constructors

I've had plenty of success using EasyHook to hook system API routines (in C++) out of libraries. These libraries have always been flat and basically filled with globally callable routines. Here is a small sample using MessageBeep() out of the User32.dll library (minus setup code):
HMODULE hUser32 = GetModuleHandle ( L"User32" );
FARPROC TrampolineMethod; // This would have been set to my new replacement trampoline method.
TRACED_HOOK_HANDLE hHook = new HOOK_TRACE_INFO();
NTSTATUS status;
status = LhInstallHook(
GetProcAddress(hUser32, "MessageBeep"),
TrampolineMethod,
(PVOID)0x12345678,
hHook);
This is all works great. The problem is, I now have a need to hook methods out of a class, not just a global function. I don't really care about the object itself, I'm really more interested in examining the parameters of the method and that's it. I don't know how to syntactically identify the routine in the function name parameter for GetProcAddress(), and I'm not even sure if GetProcAddress() supports it. For example, I'd like to hook the Pen::SetColor() method out of the gdiplus.dll library:
HMODULE hGDIPlus = GetModuleHandle ( L"Gdiplus" );
FARPROC TrampolineMethod; // This would have been set to my new replacement trampoline method.
TRACED_HOOK_HANDLE hHook = new HOOK_TRACE_INFO();
NTSTATUS status;
status = LhInstallHook(
GetProcAddress(hGDIPlus, "Pen.SetColor"), // this is probably wrong or not possible here
TrampolineMethod,
(PVOID)0x12345678,
hHook);
This doesn't work of course and I don't think the GetProcAddress(hGDIPlus, "Pen.SetColor") is correct. How do I specify a member function of a class to GetProcAddress()? Is this even possible? Also, how would this look if I wanted to hook a constructor such as Pen::Pen()?
The Portable Executable (PE) format that Windows uses doesn't really supports exporting or importing objects or their methods, so that's not what GdiPlus (or any other DLL) uses internally. The object notation is probably an abstraction implemented in the import library for the DLL.
If you take a look at GdiPlus's export table with the Dependency Walker tool (Windows SDK), or similar, you will see
GdipGetPenColor
GdipSetPenColor
etc.
So it is basically no different than the legacy exports, like MessageBeep.

System-wide hooks with MHook

I have this project where I hook some Windows functions (GetOpenFileNameA, GetOpenFileNameW, GetSaveFileNameA, GetSaveFileNameW) with MHook library. This is the code I use to install the hooks.
for(size_t i = 0; i < FunctionsCount; ++i)
{
HMODULE hModule = GetModuleHandleA(Function[i].ModuleName);
//[1]
if( !hModule )
return FALSE;
*Function[i].Original = GetProcAddress(hModule, Function[i].Name);
if(*Function[i].Original == NULL)
return FALSE;
if(!Mhook_SetHook(Function[i].Original, Function[i].Hooked))
return FALSE;
}
It is called from DllMain on DLL_PROCESS_ATTACH reason.
Now, when I inject my Dll using the CreateRemoteThread approach it works pretty well, but when I want to set up the system-wide hooks using LoadAppInit_DLLs mechanism my hooks doesn't works. After hours debugging I found that the reason is that my Dll is loaded BEFORE comdlg32.dll (which is the module where these functions are), and then the statement [1] returns false, then my Dll is not loaded.
The solution I've so far is to call LoadLibrary if [1] returns false.
HMODULE hModule = GetModuleHandleA(Function[i].ModuleName);
//[2]
if( !hModule )
{
LoadLibraryA(Function[i].ModuleName);
hModule = GetModuleHandleA(Function[i].ModuleName);
}
I've found many site where is said this is evil and I agree (even when works fine). Also if a process doesn't use common dialogs at all I'm hooking functions that will never be called.
If anybody could help, maybe a workaround or an explanation of another way to set-up global hooks it will be appreciated. Thanks in advance
You need to hook LoadLibraryXXX functions and after successful their execution check whether your module has been loaded (calling GetModuleHandle) and hook it if it is loaded.
Also it is a good idea to pin hooked dlls so they are not unloaded anymore.