DLL only injects if I inject together with it's dependencies - c++

I was using this source code for learning purpose https://github.com/W1lliam1337/digital-sdk. It was working since last week but then I changed some Visual Studio settings and copy&pasted source to other folder and today it started not working anymore.There it generates some dll files on debug/release folder when I compile project.I was only injecting cheat dll to make it work and it was working but now its not working if I only inject cheat dll and then as you can see I tried to inject all of them together after I click inject button 3 times Its worked. Can someone help me with that ? Other projects works well. What did I change and its caused this ? I really have no idea I don't have knowledge on Visual Studio settings too.Please someone help me
Edit : I tried other injectors too still not working Its more like I messed up with project/Visual Studio settings
VIDEO
https://streamable.com/rvn7bg
Here is how my DllMain and Thread looks like.
DWORD WINAPI HackThread(HMODULE hModule)
{
AllocConsole();
FILE* f;
freopen_s(&f, "CONOUT$", "w", stdout);
//My Stuff bla bla..
while (!GetAsyncKeyState(VK_END) & 1)
{
Sleep(20);
}
if (f) fclose(f);
FreeConsole();
FreeLibraryAndExitThread(hModule, 0);
return 0;
}
BOOL APIENTRY DllMain( HMODULE hmodule,
DWORD reason_for_call,
LPVOID reserved
) {
if ( reason_for_call != DLL_PROCESS_ATTACH )
return FALSE;
/* #xref: https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-disablethreadlibrarycalls */
DisableThreadLibraryCalls( hmodule );
std::thread( instance ).detach( );
return TRUE;
}

Related

Prevent exit from DllMain with dll hijacking in c++

Hi i'm testing dll hijacking scenario for the educational purpose and i have problem when DllMain loaded i want to create something that keeps my method (Thread) running but the problem is even if i create a new thread still when DllMain reaches at the end my thread killed with it !
if i do something like WaitForSingleObject or while (1) {} it causes the deadlock of course
Also i want to prevent the Main Process (executable file) to exit ! because when the applications loads all modules after that it close him self ! and that's not what i want ! i want to keep the application running . as long as the application is running my thread is live
any thoughts or advise ?
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)LiveBackgroundListenerFunction, 0, 0, 0);
}
//while (1) {} #DeadLock !!!
//WaitForSingleObject(hdl, 100); #DeadLock !!!
return TRUE;
void LiveBackgroundListenerFunction()
{
While(1)
{
Sleep(5000);
//Do Somthing......
}
}
thanks in advance

Can't load custom DLL

I created a simple DLL that open cmd.exe.
I did it with these options:
In the default dlllmain.cpp I added a code that creates a new cmd.exe:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <Windows.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
BOOL h = CreateProcessW(L"C:\\Windows\\System32\\cmd.exe", L"", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
These three lines below the DLL_PROCESS_ATTACH worked for me when I tested it with a console application.
I am expecting that every process that will load this DLL will open cmd.exe.
I tried to load the DLL with PowerShell:
Add-Type -TypeDefinition #"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
public static class Kernel32
{
[DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)]
public static extern IntPtr LoadLibrary(
[MarshalAs(UnmanagedType.LPStr)]string lpFileName);
}
"#
$LibHandle = [Kernel32]::LoadLibrary("C:\tmp\myDll.dll")
But nothing happens, the value of the $LibHandle was 0.
What I am doing wrong ?
I found what was the problem.
My system is 64 bit and the file was compiled in 32 bit.
I needed to specify in Visual Studio that I am compiling it in x64 bit.
I didn't check it in the beginning because I thought that when I am compiling it on "Any CPU" mode, it compile the file in 64 bit automatically as the OS architecture.
Now it works fine.

Debugging .DLL Injection Issue - Breakpoint On Supposedly Executing Code Not Being Hit

I have written a program (.DLL) which is to be injected into process.exe.
DLL injector code:
Bool InjectDll(DWORD pID, const char* dllPath) {
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (!Proc)
{
return false;
}
void* LoadLibAddr = (void*)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
void* RemoteString = (void*)VirtualAllocEx(Proc, NULL, strlen(dllPath), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, dllPath, strlen(dllPath), NULL);
HANDLE ret = CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, (LPVOID)RemoteString, CREATE_SUSPENDED, NULL);
if (ret) {
return true;
}
}
DllMain() function of .DLL to be injected:
#include <Windows.h>
extern void vMain();
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&vMain, 0, 0, 0);
return true;
}
return false;
}
vMain:
void vMain() {
CreateConsole();
std::cout << "vMain() has executed!\n";
}
The .DLL to be injected works fine when I compile it in visual studio, but when I compile in QT Creator, vMain() never gets executed. The injector, .DLL, and target process are all 32-bit. So I have tried to debug the target process by making the .DLL injector call CreateRemoteThread() with the CREATE_SUSPENDED flag, that way I can set a breakpoint on LoadLibraryA(), resume the thread, step through execution from the breakpoint, and view the return value. However, my breakpoint on LoadLibraryA() isn't being hit.
So I debugged the .DLL injector application to make sure that the remote thread was being created. I confirmed that it is by calling GetThreadID() on the return value of CreateRemoteThread(), outputting it, and viewing that thread in the threadlist of the target process:
Keep in mind the thread is still suspended. Upon further inspection, EIP points to the first instruction in _RtlUserThreadStart(). I set a breakpoint on this instruction. I then resume the suspended thread by calling ResumeThread() from my .DLL injector program. The breakpoint is not hit.
It is noteworthy that the target application does not have any anti-breakpoint mechanism, and breakpoints have worked fine for me apart from this instance.
So how can I figure out what the issue is? Is there a reason my breakpoints are not being hit? Is there a better way to debug the problem?
When doing console output from inside a DLL, you may need to redirect stdout to the console:
// AllocConsole() instead of CreateConsole()
AllocConsole();
freopen("CONOUT$", "w", stdout); // <====
std::cout << "vMain() has executed!\n";
Additionally, It's not a good idea to create threads inside DllMain() and here's why:
https://blogs.msdn.microsoft.com/oldnewthing/20070904-00/?p=25283
https://blogs.msdn.microsoft.com/oldnewthing/20040127-00/?p=40873/
Related question:
Creating a thread in DllMain?
I remember I've had some trouble with it in the past and I stopped doing such things as creating threads / windows inside DllMain(), as recommended.
Still, there are cases where it works, but I wouldn't trust it.
That being said, if the above doesn't work, try to call your vMain() directly without a thread and see what happens.

Unable to call method in managed dll after loading CLR. Why?

I have met some issues when trying to inject a dll into a process. I am quite new at the topic but am familiar with C# so reading and understand the syntax of C++ wasnt that unfamiliar and i understand it for the most part.
What i am trying is only for learning, and i am trying this with simple applications like notepad.exe and calc.exe.
Project setup:
WPF application - To pick the process i want to tinker with and inject the unmanaged dll.
CppDLL.dll - Unmanaged dll to load CLR, managed dll and call method on managed dll.
SharpDLL.dll - Managed dll.
(wpf) c# of interest
dllToInject = fileDialog.FileName;
Process targetProcess = Process.GetProcessById(processToInject.ID);
var dllInjector = DllInjector.GetInstance;
DllInjectionResult injectResult;
if ((injectResult = dllInjector.Inject(processToInject.Name,dllToInject)) == DllInjectionResult.Success)
{
MessageBox.Show("Success");
} else
{
MessageBox.Show("Error: " + injectResult.ToString());
}
The unmanaged dll is successfully injected when not trying to load clr and managed dll as shown below.
But when i try to load CLR and managed dll it fails.
CppDLL.dll dllmain.cpp :
#include "stdafx.h"
#include <Windows.h>
#include <metahost.h>
#pragma comment(lib, "mscoree.lib")
#import "mscorlib.tlb" raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") \
rename("ReportEvent", "InteropServices_ReportEvent")
void LoadDotNet()
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
IID_PPV_ARGS(&pClrRuntimeHost));
hr = pClrRuntimeHost->Start();
DWORD pReturnValue;
hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(
L"C:\\Users\\DanHovedPC\\Desktop\\inject\\SharpDLL.dll",
L"SharpDLL.Injected",
L"Start",
L"Hello from .NET",
&pReturnValue);
pMetaHost->Release();
pRuntimeInfo->Release();
pClrRuntimeHost->Release();
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, L"Hi!", L"From cpp DLL", NULL);
//LoadDotNet();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
SharpDLL.dll Injected.cs
using System.Windows;
namespace SharpDLL
{
class Injected
{
public static int Start(string arg)
{
MessageBox.Show(arg);
return 0;
}
}
}
In CppDLL.dll if i uncomment the function and comment the messagebox it fails. The SharpDLL.dll does not get injected. And when i try to close notepad the process still shows up in Process Explorer.
I have looked at the process in Process Explorer beforehand and the clr.dll is not loaded by default, but it gets loaded when the function runs. Maybe it could be the .NET version? I am running Windows 10 x64.
Update
The code runs until i try to actually start the runtime
void LoadDotNet()
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
IID_PPV_ARGS(&pClrRuntimeHost));
// start runtime
MessageBox(NULL, L"Runs up to here...", L"DEBUG", NULL);
hr = pClrRuntimeHost->Start();
MessageBox(NULL,(LPCWSTR)GetLastError(),L"DEBUG",NULL);
pMetaHost->Release();
pRuntimeInfo->Release();
pClrRuntimeHost->Release();
}
The first messagebox shows.
I figured out that the problem was that code within DllMain must not access the CLR.
Code within DllMain must not access the CLR. This means that DllMain should make no calls to managed functions, directly or indirectly; no managed code should be declared or implemented in DllMain; and no garbage collection or automatic library loading should take place within DllMain.
https://msdn.microsoft.com/en-us/library/ms173266.aspx
When creating a new thread the code runs successfully
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
//printf("DLL Loaded!");
CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)LoadDotNet, NULL, 0, NULL);
}
return TRUE;
}
And from reading a comment on another question here on SO CreateThread should be safe in this particular case.

Visual C++: Linking a DLL from another DLL using a relative path

I have the following file structure
C:\Application\application.exe
C:\Application\plugins\myplugin\myplugin.dll
C:\Application\plugins\myplugin\libs\utils.dll
Here application.exe loads myplugin.dll dynamically via LoadLibrary. Note that I have no control over application.exe as I am developing the plugin only.
What I want is to make myplugin.dll load libs\utils.dll via a relative path (ideally using static linking). That is, I don't want to be dependent on the location of application.exe. I currently add C:\Application\plugins\myplugin\libs to the PATH environment variable when installing myplugin, but environment variables are not an ideal solution and I want to avoid doing that.
I was hoping I could use assemblies and config files to specify the relative path libs\utils.dll in myplugin.dll. And I tried this, but to no avail. I then saw someone mentioning here on StackOverflow that config files only work for applications (i.e. executables). But as I said above, I have no control over application.exe. Is there a solution to this seemingly simple problem which I believe on Unix systems can be solved via rpaths?
You cannot statically link to a DLL path at all, relative or absolute. The PE imports table only contains filenames. That is why a DLL search path exists to locate DLLs.
If you want to control where utils.dll is loaded from, you have to load it dynamically. myplugin.dll can retrieve its own path using GetModuleFileName(), using the module handle that is passed in to its DllMain() entry point. It can then remove the filename from the path, append the relative path to the path, and then load the DLL when needed (not inside of DllMain() itself, or else a deadlock/crash may occur).
There are two ways you can handle this:
load everything dynamically yourself:
#include <windows.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
HINSTANCE hThisDLL = NULL;
HMODULE hUtils = NULL;
typedef ReturnType __CallingConv (*DllFuncType)(Params);
DllFuncType DllFunc = NULL;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
hThisDLL = hinstDLL;
...
}
return TRUE;
}
...
ReturnType CallDllFunc(Params)
{
if (!hUtils)
{
TCHAR szUtilsFileName[MAX_PATH] = {0};
GetModuleFileName(hThisDLL, szUtilsFileName, MAX_PATH);
if (!PathRemoveFileSpec(szUtilsFileName))
{
// do something...
return ...;
}
if (!PathAppend(szUtilsFileName, TEXT("libs\\utils.dll")))
{
// do something...
return ...;
}
hUtils = LoadLibrary(szUtilsFileName);
if (!hUtils)
{
// do something...
return ...;
}
}
if (!DllFunc)
{
DllFunc = (DllFuncType) GetProcAddress(hUtils, "DllFuncName");
if (!DllFunc)
{
// do something...
return ...;
}
}
return DllFunc(Params);
}
static link to everything like you normally would, but then utilize your compiler's delay load feature (if supported) so you can specify the DLL's filename dynamically at runtime, but still statically link to the DLL function itself (the delay-load mechanism will call GetProcAddress() for you).
#include <windows.h>
#include <shlwapi.h>
#include <delayimp.h>
#pragma comment(lib, "Delayimp.lib")
#pragma comment(lib, "shlwapi.lib")
HINSTANCE hThisDLL = NULL;
FARPROC WINAPI DelayLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
if ((dliNotify == dliNotePreLoadLibrary) &&
(strcmpi(pdli->szDll, "utils.dll") == 0))
{
TCHAR szUtilsFileName[MAX_PATH] = {0};
GetModuleFileName(hThisDLL, szUtilsFileName, MAX_PATH);
if (!PathRemoveFileSpec(szUtilsFileName))
{
// do something...
return NULL;
}
if (!PathAppend(szUtilsFileName, TEXT("libs\\utils.dll")))
{
// do something...
return NULL;
}
HMODULE hUtils = LoadLibrary(szUtilsFileName);
return reinterpret_cast<FARPROC>(hUtils);
}
return NULL;
}
PfnDliHook __pfnDliNotifyHook2 = DelayLoadHook;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
hThisDLL = hinstDLL;
...
}
return TRUE;
}
...
ReturnType CallDllFunc(Params)
{
return DllFuncName(Params);
}