Using GetProcAddress and EasyHook to hook class methods and constructors - c++

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.

Related

Hook APIs that imported to program by LoadLibrary/GetProcAddress

I know how I can hook functions from the IAT table, but I have a problem with APIs which were imported by calling LoadLibrary/GetProcAddress functions. I want to know exactly how someone could hook those functions. I realize that I should hook the GetProcAddress function but how can I check the parameters that were passsed to that function?
For example, consider a program which is going to include MessageBoxW via LoadLibrary/GetProcAddress, how can I hook that MessageBoxW and then check the parameters that have been passed to it?
I have searched a lot in StackOverflow and Google, but I couldn't find a step-by-step tutorial about this. So, if you have such a tutorial or article, I would be really grateful to read them.
In order to hook APIs that they are loaded into a binary dynamically with help of LoadLibrary/GetProcAddress, you should intercept return address of the GetProcAddress and name of the functions that passed to it (for example, consider a program try to load MessageBoxA in this way).
In the second step, you should save that original address of MessageBoxA API in a variable like OriginalMessageBoxA.
In the third and final step, you should return address of your modified API (HookedMessageBoxA) to the callee of the GetProcAddress so when the program try to call that address, program redirected to your function. Something like the following one:
VOID* HookedGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
if (std::string(lpProcName).compare("MessageBoxA") == 0)
{
OMessageBoxA = (PMessageBoxA)GetProcAddress(hModule, lpProcName);
return HookedMessageBoxA;
}
else
{
return OGetProcAddress(hModule, lpProcName);
}
}
In that moment, caller will go through your HookedMessageBoxA and you can check parameters that passed to MessageBoxA. As folks said, it is kinda same like normal IAT hook with a minor changes and tricks.

How to hook an exe function?

I need to get something from a program. And with the help of ollydbg and IDA, I found the "thing" I can get is in a function called sub_HEXHEX.
Now I know how to hook a function from Dll like DrawTextA or other one.
I need to get function address with
HMODULE hmod = LoadLibrary(L"User32.dll");
GetProcAddress(hmod, "DrawTextA")
But when I need to hook this sub_HEXHEX, I confused. I can get that exe's HANDLE, I know the function's Address (that 0x00HEXHEX), but there's no GetProcAddress I can use. I tried use HANDLE + 0x00HEXHEX as function's address, but I think im wrong with 'offset' things.
Here is what I did
DWORD dwPid = GetCurrentProcessId();
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPid);
OldA2ECB0 = (sub_A2ECB0)((HMODULE)hProcess + 0xA2ECB0);
pfOldA2ECB0 = (FARPROC)OldA2ECB0;
And sub_A2ECB0
typedef int(*sub_A2ECB0)(LPCSTR param1, int param2);
But pfOldA2ECB0 will be NULL.
My knowledge is poor with C++ and Win32 (English, too), so its toooooo difficult for me.
From what I understand, and I do believe I understand correctly what you want is internal hooking.
I can show you how to do this in 3 simple steps.
These are the things you must understand:
The function shown in IDA is not exported, thus you cannot use GetProcAddress()
You must be within the context of the remote process to hook internal functions
You cannot use libraries like Detours, you must have your own method/function for hooking
These are the steps you must do:
Be withing the context of the remote process, simplest method: inject your dll.
Get the address offset from IDA, in your case is 00A2ECB0.
Simply apply the hook once inside the remote process:
//0xE8 instruction is a relative call instruction
SetCompleteHook(0xE8,0x00A2ECB0,&YOUR_OWN_FUNCTION);
Helper:
void SetCompleteHook(BYTE head,DWORD offset,...)
{
DWORD OldProtect;
VirtualProtect((void*)offset,5,PAGE_EXECUTE_READWRITE,&OldProtect);
if(head != 0xFF)
{
*(BYTE*)(offset) = head;
}
DWORD* function = &offset+1;
*(DWORD*)(offset+1) = (*function)-(offset+5);
VirtualProtect((void*)offset,5,OldProtect,&OldProtect);
}
And that's it really, it's as simple and straightforward as possible in your scenario.
You can go further of course and perform much more complex internal hooking, but for your learning purpose this is a massive step ahead and starting point.
Enjoy!

C++ Builder XE2: Initializing a Data Module in a dll

I'm trying to create a dll that contains a VCL data module - the idea being that various applications can all load the same dll and use the same database code.
The data module itself is tested ok as part of an application - I've copied the form over to my dll project.
So in the dll entry point method, I need to initialize the data module:
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
//if I don't call this, I get an exception on initializing the data module
CoInitialize(NULL);
//initialize a standard VCL form; seems to works fine
//I'm not using Application->CreateForm as I don't want the form to appear straight away
if(!MyForm) MyForm = new TMyForm(Application);
//this doesn't work - the thread seems to hang in the TDataModule base constructor?
//I've also tried Application->CreateForm; same result
if(!MyDataModule) MyDataModule = new TMyDataModule(Application);
}
I've also seen something about how I need to call Application->Initialize before creating the form but this doesn't seem to make any difference.
Any ideas?
Thanks
You really should not be doing very much work in your DllEntryPoint() at all. Certainly not calling CoInitialize(), anyway. It is not the DLL's responsibility to call that when loaded. It is the calling app's responsibility before loading the DLL.
You should either:
export an additional function to initialize your DLL and then have the app it after loading the DLL (same for uninitialing the DLL before unloading it)
don't create your TForm/TDataModule until the first time the DLL actually needs them.
move your TForm/TDataModule into their own worker thread inside the DLL. In this case, you would then call CoIniitalize().
And in all cases, don't relay on the DLL's Application object to manage the lifetime of your TForm/TDataModule. Free them yourself instead before the DLL is unloaded.

How does one read a localized name from the registry?

Consider the following registry export:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\WinSock2\Parameters\Protocol_Catalog9\Catalog_Entries\000000000001]
;...
"ProtocolName"="#%SystemRoot%\\System32\\wshtcpip.dll,-60100"
The intention here appears to be for someone to load the DLL in question, and use some form of API retrieve the actual name. But I don't know what that API is :/
I'd like to avoid loading the DLL into my address space (and thus call DLL_PROCESS_ATTACH) if at all possible; can't really trust third party DLLs to be trustworthy.
RegLoadMUIString will do the necessary for you. Note however, that it was introduced in Vista so won't help if you need to support XP.
If you want to avoid code in the DLL running whilst you extract resources, use LoadLibraryEx passing LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE, or possibly LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE. Once you have done that, you can call LoadString to extract the MUI value.
This is going to help:
HMODULE hModule = LoadLibrary(_T("wshtcpip.dll")); // LoadLibraryEx is even better
TCHAR pszValue[1024] = { 0 };
INT nResult = LoadString(hModule, 60100, pszValue, _countof(pszValue));
LoadString will take care of downloading resource from MUI, if needed. LoadString uses thread locale, which you might want to override prior to the call.
Also: Loading Language Resources on MSDN.

Given a COM DLL, extract all classes CLSID and corresponding interface name

My question is similar to Getting CLSID for a DLL file?, I think.
I have a directory with some DLLs, each one implementing one or more COM interfaces. I would like to get:
1) Each interface name
2) The CLSID of the class implementing the interface
For each DLL. It's important that everything can be done programatically (So I can't use some sort of COM browser and manually look up for that information).
Later I will lookup the CLSID given the interface name and call some methods using IDispatch.
One alternative seems to be scanning the registry trying to match the type, interface and class GUID and the .dll filename. But that seems to be slow and not robust.
Does someone has a clear solution to this problem?
EDIT:
With the response of Ben Voigt, I came with the following code which suit my needs:
ITypeLib *typelib;
ITypeInfo *typeinfo;
LoadTypeLibEx(_T("c:\\mydir\\mycom1"), REGKIND_NONE, &typelib);
for (UINT i = 0;i < typelib->GetTypeInfoCount();++i) {
TYPEKIND typekind;
typelib->GetTypeInfoType(i, &typekind);
if (typekind == TKIND_COCLASS) {
// class!
CComBSTR className;
TYPEATTR *typeattr;
typelib->GetTypeInfo(i, &typeinfo);
typeinfo->GetDocumentation(MEMBERID_NIL, &className, NULL, NULL, NULL);
typeinfo->GetTypeAttr(&typeattr);
GUID classGUID = typeattr->guid;
for (UINT j = 0;j < typeattr->cImplTypes;++j) {
// interface!
CComBSTR interfaceName;
HREFTYPE hreftype;
ITypeInfo *classtypeinfo;
typeinfo->GetRefTypeOfImplType(j, &hreftype);
typeinfo->GetRefTypeInfo(hreftype, &classtypeinfo);
classtypeinfo->GetDocumentation(MEMBERID_NIL, &interfaceName, NULL, NULL, NULL);
// associate interfaceName with classGUID here
}
}
}
You can't get that from the COM DLL, but you can get it from the typelib. I'm pretty sure the MIDL compiler has a switch to decompile a typelib, but parsing IDL wouldn't be as easy as using the TypeLib API.
To complicate matters, the typelib is often stored as a resource inside the DLL. So you'd extract the resource, and open it with the TypeLib API.
Start with LoadTypeLibEx which will return you an ITypeLib* interface pointer (you knew you were going to need COM in order to get information about COM libraries, right?). This will actually do the resource extraction step for you.
Then, call ITypeLib::GetTypeInfoCount to find out how many types there are. Call ITypeLib::GetTypeInfoType for each one to find the interfaces and coclasses. And call ITypeLib::GetTypeInfo followed by ITypeInfo::GetDocumentation to get the name.
It looks like you have all of this so far. Next you need the GUID of the type, which is gotten with ITypeInfo::GetTypeAttr (not ITypeLib::GetLibAttr). That gives you a TYPEATTR structure, which has a guid field.
From the same TYPEATTR structure, you'll need the cImplTypes field. That together with ITypeInfo::GetRefTypeOfImplType will let you match up each coclass to the interfaces it implements.
Note that there's not guaranteed to be a 1:1 relationship between interfaces and implementation coclasses. And the interface can be in a different library from the coclass.
Few caveats to Ben Voigt's answer: not every COM DLL has a typelib. In your case, it seems, it does; but that's not a requirement. The only rock-solid requirement is that the DLL exports the function DllGetClassObject(), where you pass a CLSID and get back an object factory.
You could load the library and call DllGetClassObject for every registered CLSID on the system (scan the registry under HKCR\CLSID for the list of those). The ones where you get a valid object back are the ones that the DLL supports. Now, in theory, it's not even a requirement that the CLSIDs the DLL supports are registered; I can envision a DLL that implements private object classes that only the intended client knows about and no one else should. But this is a very, very exotic scenario; for one thing, the regular COM mechanism of looking up the DLL path by the CLSID will break for those. The client would have to load the DLL directly.
You could also scan the registry for the CLSID's where the DLL under consideration is registered as InprocServer32; this, again, will break in case of private classes. You can do a registry search in regedit, search in data. Also, you'd have to deal with filename case issues, short vs. long names, hardlinks, environment variable substitution and so on. So I would not recommend it.
EDIT: just thought of another way. Download Regmon, run it, and call regsvr32 on the DLL. Then watch what CLSID's are touched.
You might want to look at the source code in WiX's heat utility, which does the same thing:
http://wix.sourceforge.net/manual-wix3/heat.htm