MFC app and shared libs - c++

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.

Related

How to use `/DELAYLOAD` on a DLL from another DLL

I have a solution with two DLLs. The first one is the "main" DLL. It happens to be an ODBC driver, but I think that is not important for this question.
The second DLL contains all the UI logic for the first one. As the UI is not always needed, I want to use the /DELAYLOAD feature which explicitly says:
The delayed loading of a DLL can be specified during the build of
either a .EXE or .DLL project.
The main DLL's project correctly references the UI ones. If I don't use /DELAYLOAD, everythin works just fine. The two DLLs will be installed into the same directory, so I thought loading one DLL from within the other should be easy. But apparently, it's not.
As soon as the first function from the UI DLL is called, the application (any ODBC client in my case) crashes.
GetLastError() yields 126 which apparently means that the target DLL could not be found in any of the search paths.
And indeed, according to this answer LoadLibrary() does have a look into the directory of the calling executable, but not into the one of the currently executed DLL. I'm assuming /DELAYLOAD is also just using LoadLibrary() under the hood, is that correct?
If I copy the executable into the installation directory of my driver, it works just fine, which proves my assumption that it just doesn't look in the current DLL's directory.
Appart from that, I was also able to make it run by calling
LoadLibrary(L"C:\\absolute\\path\\to\\UI.dll");
just before the first function of the UI DLL is loaded.
I was also able to determine this path programmatically using
wchar_t buffer[512];
GetModuleFileName(hThisDLL, buffer, sizeof(buffer));
But then I would have to cover every single UI call with this logic. So I wouldn't see much advantage anymore that /DELAYLOAD has over the "old-school" way of using LoadLibrary() and GetProcAddress().
Question
Is there a simple way to make /DELAYLOAD find the target DLL from another DLL in the same directory?
There is. My suggestion would be to create a delay-load-failure hook function.
https://learn.microsoft.com/en-us/cpp/build/reference/failure-hooks?view=vs-2019
Basically, you write a function inside your main DLL that gets notified in the event of a delay load failure. In that function, when the given code indicates failure, you try manually calling LoadLibrary with of a path consisting of the folder in which your main DLL resides plus the name of the DLL that failed to load
How you get the your main DLL from within your main DLL is up to you. There are many ways.
Something like this:
FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
FARPROC fpRet = NULL;
switch (dliNotify)
{
case dliStartProcessing:
break;
case dliNotePreLoadLibrary:
break;
case dliNotePreGetProcAddress:
break;
case dliFailLoadLib:
{
std::string newPath = GetMyModulePath();
newPath += "\\";
newPath += pdli->szDll;
fpRet = reinterpret_cast<FARPROC>(::LoadLibrary(csDir));
}
break;
case dliFailGetProc:
break;
case dliNoteEndProcessing:
break;
default:
break;
}
return fpRet;
}
//
// Set access to our delay load hook.
//
PfnDliHook __pfnDliFailureHook2 = delayHook;

Which module called my DLL exported function?

Background
I'm developing a C++ windows DLL module that exports a single function
__declspec(dllexport) void Run()
Motivation
I would like to implement some sort of accessing rights to my function. I wish to prevent unauthorized modules from activating my DLL proc.
I don't need a robust/bullet proof mechanism. I only like to "defend" this proc from other modules running under my own app.
Approach
Get the calling module name and decide based on the name if access is granted.
Question
Would this approach suffice?
if so, how do I get the name of the calling module?
if so, how do I get the name of the calling module?
get return address by call _ReturnAddress
get base address of the image that contains this return address -
RtlPcToFileHeader
finally call GetModuleFileName function
so code can be like this
HMODULE hmod;
if (RtlPcToFileHeader(_ReturnAddress(), (void**)&hmod))
{
WCHAR sz[MAX_PATH];
if (GetModuleFileName(hmod, sz, MAX_PATH))
{
DbgPrint("%p %S\n", hmod, sz);
}
}
about - are this work in XP ? yes, but with one note. _ReturnAddress is CL intrinsic - so not depended from os version (for say gcc exist __builtin_return_address (0) ) GetModuleFileName also very old api function and exist in win2000, xp, everywhere. about RtlPcToFileHeader
- it exported (and implemented) in ntdll.dll in all windows versions from xp to latest. also begin from win2003 it also exported from kernel32.dll but implementation here - simply jump to ntdll.RtlPcToFileHeader - so if want use this on xp also - link with ntdll.lib and place it before kernel32.lib in libs order or can get it it runtime by GetProcAddress(GetModuleHandle(L"ntdll"), "RtlPcToFileHeader");
or even if somebody afraid that RtlPcToFileHeader will be removed from ntdll (this is of course no) can use this
GetProcAddress(GetModuleHandle(g_xp ? L"ntdll" : L"kernel32"), "RtlPcToFileHeader");

ShowMessage not showing in Delphi DLL called from C++

I want to call this delphi code via a DLL from C++
procedure MyMessage; stdcall;
begin
ShowMessage(DLLName + ' more text');
end;
Using some delphi test code I see no problem , but from C++ no message box is shown.
i did the following C++ coding
// function prototype
typedef void(__stdcall*VoidCall)();
// prototype for info function inside DLL
extern "C" __declspec(dllimport) void __stdcall MyMessage();
MyMessage = (VoidCall)::GetProcAddress(load, "MyMessage");
MyMessage;
As I want to use as a next steps existing delphi forms with a wrapper DLL from C++ , I guess the solution of this problem will also enable me for the next task ....
The presented C++ code does not compile. It mixes binding of a dll via an import library with dynamic loading of a dll via LoadLibrary / GetProcAddress.
To load a DLL created with Delphi, it is easiest to use dynamic loading of the dll. Do this as follows:
// function prototype
typedef void(__stdcall*VoidCall)();
[...]
// Load the library
HMODULE lib = LoadLibrary("Project1.dll");
if (lib != 0)
{
__try
{
// Get the address to the exported function in the DLL
// and store it in the variable myMessageFunction
VoidCall myMessageFunction = (VoidCall) GetProcAddress(lib, "MyMessage");
// Call the function. Note you need the parenthesis even
// when there are no parameters to pass
myMessageFunction();
}
__finally
{
// Unload the library again. Note that you cannot use
// functions from the library after that. So only unload
// the dll once you don't need it anymore.
FreeLibrary(lib);
}
}
else // TODO: Error handling, dll cannot be loaded
If you want to use load time linking, you can create a *.lib file to be used with C++ for a DLL created with Delphi. Use the solution from this question.

Unable to set WSPStartup as a dll export

I am trying to write a LSP for winsock and as per MSDN documentation the dll is supposed to export a single function viz. WSPStartup() as defined in Ws2spi.h
While compiling I get an error:
error C2375: 'WSPStartup' : redefinition; different linkage
If I append the
__declspec(dllexport)
directive to it. On the other hand, if I use the
__control_entrypoint(DllExport)
it compiles fine, but the function is not actually exported. I checked using dependency viewer. To make sure that other LSP implementations export the functions or not, I used dependency viewer on VMWares vsocklib.dll and mswsock.dll, both dlls export the said function.
My sample implementation is as follows :-
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <Ws2spi.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
__declspec(dllexport)
__checkReturn
int
WSPAPI
WSPStartup(
__in WORD wVersionRequested,
__in LPWSPDATA lpWSPData,
__in LPWSAPROTOCOL_INFOW lpProtocolInfo,
__in WSPUPCALLTABLE UpcallTable,
__out LPWSPPROC_TABLE lpProcTable
)
{
return 0;
}
So what am I doing wrong here? How do I make a DLL which exports the WSPStartup() function ??
Since the function prototype is given in the Ws2spi.h file, adding any kind of additional specifiers to the function in the definition will cause the compiler to give the
'redefinition' error.
Also it is not possible to have it exported directly via declspec(dllexport) which will create a decorated name since WSPAPI specifier declares the function as a stdcall.
To mitigate all these problems I exported the method by a DEF file as shown in this article - Exporting from a DLL Using DEF Files
I believe that is the only proper method to get an undecorated WSPStartup() function export in your dll.

Hooking LoadLibrary API call

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.