Attaching a DLL to a Game - c++

I would like to attach my DLL to a game to add more features.
The DLL is 95% done, the problem is in finding the best and easy way to load this DLL from within the game.
My idea is to use this technique:
dinput_ori.dll (old dll)
dinput.dll (my dll that points to dinput_ori.dll)
I don't need to access any members of original DLL, but only load my new DLL.
I am searching for a generic DLL source code that can do the following:
bool WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
std::string DLLFileOri = "dinput_ori.dll";
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
// Load dll
LoadOriDll(DLLFileOri);
MsgBox("This DLL was loaded.");
break;
case DLL_PROCESS_DETACH:
// Close the DLL
UnloadOriDll(DLLFileOri);
break;
}
return true;
}
In this case the name of my DLL is "dinput.dll".
Is there a generic source code that can do this ?
Thanks!

Related

CreateThread in DLL Terminating Prematurely

I am trying to load a DLL from Console Application. The simple console application is shown below:
#include <iostream>
#include <windows.h>
int main(){
HMODULE handleDll = LoadLibraryA("C:\\Tools\\TestDLL.dll");
if (handleDll)
{
std::cout << "DLL Loaded at Address: " << handleDll << std::endl;
}
FreeLibrary(handleDll);
}
The DLL is supposed to a POP a MessageBox which it does but just flashes on the screen instead of waiting for user input. The DLL code is below:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>
DWORD WINAPI ThreadProc( __in LPVOID lpParameter )
{
MessageBox(NULL, L"Hi From The Thread!", L"Pop a Box!", MB_OK);
return 0;
}
extern "C" __declspec(dllexport)
VOID PopMessageBox()
{
DWORD ThreadID;
HANDLE handleThread;
handleThread = CreateThread(NULL, 0, ThreadProc, 0, 0, &ThreadID);
CloseHandle(handleThread);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
PopMessageBox();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
My question is..how do I make the code in the thread function fully execute without prematurely terminating or causing painful deadlocks? Apologies for my imperfect English and inexperience.
The reason is that you are doing something unsafe in your DllMain: you are calling CreateThread.
You are very limited in what you can do from within DllMain in response to a process attach, a fact that the documentation calls out:
There are significant limits on what you can safely do in a DLL entry point. See General Best Practices for specific Windows APIs that are unsafe to call in DllMain. If you need anything but the simplest initialization then do that in an initialization function for the DLL. You can require applications to call the initialization function after DllMain has run and before they call any other functions in the DLL.
The warning links you to "General Best Pratices" which, among other things, says to "[c]all CreateThread. Creating a thread can work if you do not synchronize with other threads, but it is risky."
Even without the risks associated with synchronizing with other threads, this code is flakey in other ways: for example, your main simply calls FreeLibrary and exits. The thread you had spawned in the DLL, which may literally be mid-execution, will have the code it's supposed to run unmapped. You're literally pulling the rug out from under it!

Winapi hook via mhook causes program crash or hang

I am trying to hook StartDocW to intercept printing via mhook. I use AppInit_DLLs to load my library.
DLL code is simple:
#include <windows.h>
#include "mhook/mhook-lib/mhook.h"
using StartDocPtr = int(*)(HDC, const DOCINFO*);
StartDocPtr orig;
int HookedStartDocW(HDC hdc, const DOCINFO* lpdi) {
return orig(hdc, lpdi);
}
BOOL WINAPI DllMain(__in HINSTANCE, __in DWORD Reason, __in LPVOID) {
orig = (StartDocPtr)GetProcAddress(GetModuleHandle("gdi32"), "StartDocW");
switch (Reason)
{
case DLL_PROCESS_ATTACH:
Mhook_SetHook((PVOID*)&orig, &HookedStartDocW);
break;
case DLL_PROCESS_DETACH:
Mhook_Unhook((PVOID*)&orig);
break;
}
}
Hook is working and printing is done OK. But If I change HookStartDocW to following:
int HookedStartDocW(HDC hdc, const DOCINFO* lpdi) {
char buf[40];
GetModuleFileName(NULL, buf, 40);
return orig(hdc, lpdi);
}
Programs on printing will crash immediately. Even if I just leave char buf[40] and comment GetModuleHandle - program will hang. Why is this happening?
Moreover, if program crashes\hangs on printing (if I add anything besides return orig(hdc, lpdi)) - PC starts to behave very weirdly, refusing to run programs, etc. If I reboot it - Windows just endlessly spins on boot screen, the only way to bring it back to live - is to boot via liveCD and rename\delete my hook DLL.
Printing programs: Excel 2016, notepad.
Compiler - MSVC 2015, x64 release DLL compilation, using MBCS instead of unicode.
Your hook is declared wrong.
Look at the actual declaration of StartDocW() in Wingdi.h:
__gdi_entry WINGDIAPI int WINAPI StartDocW(__in HDC hdc, __in CONST DOCINFOW *lpdi);
You can ignore __gdi_entry. WINGDIAPI simply resolves to __declspec(dllimport). What is important in this declaration is the WINAPI.
Like almost all Win32 API functions, StartDocW() uses the __stdcall calling convention. The WINAPI macro resolves to __stdcall.
Your code does not specify any calling convention at all, so it uses your compiler's default, which is usually __cdecl instead. So you are mismanaging the call stack. That is why your code crashes.
You are also using DOCINFO when you should be using DOCINFOW instead. It is clear in your code that you are compiling for MBCS and not for UNICODE, so DOCINFO maps to DOCINFOA. You can't pass a DOCINFOA to StartDocW(), it expects a DOCINFOW instead.
You need to fix your declarations, eg:
#include <windows.h>
#include "mhook/mhook-lib/mhook.h"
using StartDocPtr = int (WINAPI *)(HDC, const DOCINFOW*);
StartDocPtr orig = nullptr;
int WINAPI HookedStartDocW(HDC hdc, const DOCINFOW* lpdi) {
//...
return orig(hdc, lpdi);
}
BOOL WINAPI DllMain(__in HINSTANCE, __in DWORD Reason, __in LPVOID) {
orig = (StartDocPtr) GetProcAddress(GetModuleHandle(TEXT("gdi32")), "StartDocW");
switch (Reason)
{
case DLL_PROCESS_ATTACH:
Mhook_SetHook((PVOID*)&orig, &HookedStartDocW);
break;
case DLL_PROCESS_DETACH:
Mhook_Unhook((PVOID*)&orig);
break;
}
}

Why rundll gives missing entry? [duplicate]

This question already has answers here:
How does RunDll32 work?
(2 answers)
Closed 8 years ago.
I have created a dead-simple DLL in Visual Studio 2010, a win32 project of type DLL.
Then I changed the DllMain to this:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(0,L"Hey there!",0,0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
and I used rundll32 vahid-win32.dll,dllmain to run it. Message box shows, but after that it gives
Error in vahid-win32.dll
Missing entry: dllmain
What is wrong with my DLL? or with me? :-)
Thanks in advance
Your messagebox doesn't come from you passing DllMain function name. Rather it is automatically called. But Rundll32 looking for a export function with name DllMain with dllexport declaration as given below.
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(0,L"Hey there!",0,0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) void mydllmain()
{
MessageBox(0,L"Hey there again!",0,0);
}
when you call RunDll32 with parameter mydllmain, it does me give both the message box with out error.
There's no reason to call DllMain via RunDLL, it's called automatically when the DLL is loaded.
Rather try running a custom function.
Aside from that, the problem is probably the exported name. You need to write a .def file for the DLL.
DllMain it is caused automatically, always. it to cause through rundll32, it will be caused, for this purpose it and is "entry point", you repeatedly try to cause it.

FreeLibrary blocks my application

Good day, everyone!
I wrote some dll, which I use in my project. In constuctor of class I load library lib = LoadLibrary(L"library.dll");, in destructor I free it using
if (lib)
FreeLibrary(lib);
Some times applications blocks when FreeLibrary is called, what I am doing wrong?
I implement dllMain but this is not solve my problem =(
in .h file
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved );
extern "C" {
static projector::CProjCorrectionsClient* corrections;
void DLLPROJECTOR_EXPORT CorrectionsInit (const char* configFile);
void DLLPROJECTOR_EXPORT CorrectionsApply ();
}
in cpp file
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved )
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
qDebug() << "DLL_PROCESS_ATTACH";
corrections = new projector::CProjCorrectionsClient();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
qDebug() << "DLL_PROCESS_DEATTACH";
delete corrections;
qDebug() << "Corrections delete success";
break;
}
qDebug() << "Out side dllmain switch";
return TRUE;
}
On console I see this messages:
DLL_PROCESS_ATTACH
Out side dllmain switch
<...>
Try to release library
DLL_PROCESS_DEATTACH
Corrections delete success
Out side dllmain switch
There is no message after FreeLibrary call and applications freeze.
Make sure you are not waiting for some thread inside DLL_PROCESS_DETACH.
When DllMain is called, system aquires internal critical section, which can cause deadlock if your code inside DllMain waits for some thread T to finish, this thread when finishing will also want to do DLL_PROCESS_DETACH, but since system critical section is aquired it will wait infinitelly causing deadlock.
The question should maybe be - 'what is the dll doing wrong?'. If the library is going to be unloaded because its ref count has reached zero then FreeLibrary will give the dll a chance to clean up, and will call DllMain with DLL_PROCESS_DETACH. Perhaps try debugging the dll to see whats going on when this event occurs.
Also if there is any static data in the DLL that could run destructors then perhaps the issue lies there.

Getting the name of a DLL from within the dll

If I have a dll called "foo.dll" and the end user renames it to "bar.dll". After calling to a LoadLibrary, how can I get the name "bar.dll" from inside my dll?
Is it GetModuleFileName(hModule, buffer); ?
yes, you need to store hModule in DllMain
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
hModule = hinstDLL;
break;
}
}
You need to provide DllMain function, store the module handle you get passed in a static variable, and then use that variable to call GetModuleFilename. You should avoid calling GetModuleFilename (or any other function) in DllMain itself, as Windows is very picky about what you can and can't do in there.