c++ dll infinite loop without using a thread - c++

is it possible to use an infinite loop in a dll function without using a thread?
here's some example code:
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) {
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, (LPCSTR)hModule, &hModule);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)myfunction, 0, NULL, 0); //my current method
myfunction(); //locks the program at runtime if i do it this way (just an example)
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
and here's an example of the function in the thread:
void myfunction() {
//begin the infinite loop after 5 seconds
Sleep(5000);
for (;;) //set no condition for breaking the loop
{
Sleep(500); //this keeps the cpu from spiking
//call my functions
function1();
function2();
function3();
function4();
}
}
this code works well. i just wonder if there are alternatives. for example: can the function be written into the memory of the process? or called at a later time, instead of DLL_PROCESS_ATTACH?

First issue
This is undefined behavior:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)myfunction, 0, NULL, 0);
The fact that you are casting the function signature of myFunction is likely to corrupt the stack.
Change your signature of myFunction as follows:
DWORD __stdcall myfunction(void*) {
You know you got it right when you can remove the suspicious cast from CreateThread:
CreateThread(NULL, 0, myfunction, 0, NULL, 0);
Second issue
You shouldn't be doing anything of significance in DLL_PROCESS_ATTACH to begin with. And according to Raymond, you definitely shouldn't be creating a thread.

Related

check and protect a thread in c++

Currently, I created a simple thread to clear memory:
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, test, 0, 0, 0);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Code:
DWORD WINAPI test(LPVOID lpvParam) {
memo:
Sleep(10000);
SetProcessWorkingSetSize(GetCurrentProcess(), 102400, 614400);
goto memo;
}
Is there any way to protect this thread? And prevent it from being paused with some external program (such as Process Hacker 2)?
Example: if the thread is running, returns true, if it is externally paused or interrupted, returns false and closes the program with ExitProcess()?
I tried different methods like
std::thread
thread.join().
thread.joinable()
None of them worked.
prevent thread from being paused with some external program (such as Process Hacker 2)?
Instead of creating a new thread to run your code periodically, create a waitable timer with CreateWaitableTimer and schedule it with SetWaitableTimer. The timer runs the callback in the thread that called SetWaitableTimer, so that there is no other thread to pause.
That also solves the problem that threads must not be created in DllMain.

Can't find RequireSignedAppinit_DLLs in Registery

I am trying to do a small dll injection on my computer, and it doesn't seem to work.
I updated AppInit_DLLs with the path to my dll, and I read online that I need to set LoadAppinit_DLLs to 1 (which I have) and RequireSignedAppinit_DLLs to 0 for the injection to work.
but I can't find RequireSignedAppinit_DLLs in the registery..
My Registery
And here is my dll code: (It's very messy I am just trying to see if it will work before I actually make it clean)
#include "pch.h"
#define DLL_EXPORT
#include "mydll.h"
extern "C"
{
DECLDIR void Share()
{
MessageBox(NULL, (LPCWSTR)L"DLL injection!", (LPCWSTR)L"Hacked", 0);
}
void Keep()
{
MessageBox(NULL, (LPCWSTR)L"DLL injection!", (LPCWSTR)L"Hacked", 0);
}
DECLDIR void openWindow()
{
MessageBox(NULL, (LPCWSTR)L"DLL injection!", (LPCWSTR)L"Hacked", 0);
}
}
BOOL APIENTRY DllMain(HANDLE hModule, // Handle to DLL module
DWORD ul_reason_for_call,
LPVOID lpReserved) // Reserved
{
openWindow();
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// A process is loading the DLL.
Keep();
Share();
openWindow();
break;
case DLL_THREAD_ATTACH:
// A process is creating a new thread.
Keep();
Share();
openWindow();
break;
case DLL_THREAD_DETACH:
// A thread exits normally.
Keep();
Share();
openWindow();
break;
case DLL_PROCESS_DETACH:
// A process unloads the DLL.
Keep();
Share();
openWindow();
break;
}
return TRUE;
}
Hope anyone can help...
Just create the RequireSignedAppinit_DLLs REG_WORD value yourself.
This is fine for experimentation but a real application should not modify these values because it decreases the security of the system.

Injected DLL Main loop crashes the process

I'm currently trying to inject a DLL into a project, but everytime i use a while loop the process crashes.
This is the code:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved ){
switch(ul_reason_for_call){
case DLL_PROCESS_ATTACH:
while(char c = getch()){
if(c == 'p'){
MessageBox(0,L"CAPT",L"CAPT",MB_OK);
}
}
break;
}
return TRUE;
}
Since you changed your original question, I'll rearrange my answer a bit...
There are significant limits on what you can safely do in a DLL entry point.
Please read carefully through the remaks on the following page:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
and
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370448(v=vs.85).aspx
For example, it shouldn't take more than 300ms (recommended time) during the DLL_PROCESS_ATTACH. You're also not returning anything (should be a boolean).
However, I think the main reason your software hangs is because MessageBox and/or getch() probably creates a deadlock there. Regarding the MessageBox use OutputDebugString instead, refer to this answer: https://stackoverflow.com/a/10981735/5874704
Also as suggested in comments:
Don't put the while loop in DllMain. Use CreateThread in DllMain to launch a new thread. Put the while loop there
Previously you also asked about the definition of the DLLMain. This is the "bare"-function of the DllMain:
BOOL WINAPI DllMain(
HINSTANCE hDllHandle,
DWORD nReason,
LPVOID Reserved)
{
BOOL bSuccess = TRUE;
switch ( nReason )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return bSuccess;
}

Terminating thread on DLL unload

I'm trying to write a DLL plug-in for a third-party software.In the plug in i'm creating a thread in an initialization function which is called by the hosting program. However, there is no shutdown routine in which I could properly terminate the thread. I'm tried this code:
DLL_EXPORT void InitFunction() // is called by the host application
{
myThread = std::move(std::thread{myThreadFunction});
}
bool WINAPI DllMain( HINSTANCE hDll, DWORD fdwReason, LPVOID lpvReserved )
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hDll);
} break;
case DLL_PROCESS_DETACH:
{
IsRunning.store(false); // tell the thread it's time to terminate;
if(myThread.joinable())
myThread.join();
}break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return true;
}
I know this won't work, because windows would call DllMain upon thread termintation, but the DllMain is still running and therefore would deadlock. I tried using DisableThreadLibraryCalls() in different places in the Dll, but that didn't work either. So, How can I terminate the threads in my DLL properly?

Detouring DrawText

I've downloaded and compiled the Microsoft detouring library. Inside my project I've included the header file and added the .lib file as a dependency. Everything compiles without errors. Now I've been trying to detour DrawText, but for some reason that detoured function doesn't get called at all. Similiarly I tried detouring the Sleep function and that worked as intended and the function I detoured to was called.
I'm not very well-versed in the business of API programming nor any other low level activities. I suspect it might have something to do with the fact that I'm trying to do this inside a console application instead of having the detouring done inside a DLL. I just find it strange that it would be able to detour Sleep in that case.
Is there something wrong with my approach or does the fault lie in the code?
#include <windows.h>
#include <stdio.h>
#include "detours.h"
int ( WINAPI *Real_DrawText )(HDC a0, LPCSTR a1, int a2, LPRECT a3, UINT a4) = DrawTextA;
int Mine_DrawText(HDC hdc, LPCSTR text, int nCount, LPRECT lpRect, UINT uOptions)
{
printf("TEST");
return Real_DrawText(hdc, text, nCount, lpRect, uOptions);
}
int main(int argc, char **argv)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_DrawText, Mine_DrawText);
DetourTransactionCommit();
printf("Calling Sleep\n");
Sleep(1000);
printf("Second callout");
Sleep(5000);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_DrawText, Mine_DrawText);
DetourTransactionCommit();
return 0;
}
Based on your code-example, it seems you're only detouring your own process. Therefore detouring DrawText doesn't output anything. Perhaps, you need to inject your code to desired target's process memory and detour the API call from there. For example, you can create system wide CBT hook which works kind of a.. launch point to your detouring needs. Something like this, to point you out a direction:
LRESULT CALLBACK CBTProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
else if (!g_pClient)
return 0;
HWND hWnd = (HWND)wParam;
if (!hWnd)
return 0;
switch (nCode) {
case HCBT_ACTIVATE:
/** Here, you can check up against the handle to see,
* if the target window is the one you're looking for...
*
*/
if (!g_pClient->IsRegisteredWindow(hWnd))
if (g_pClient->RegisterWindow(hWnd)) {
}
break;
case HCBT_DESTROYWND:
if (g_pClient->IsRegisteredWindow(hWnd))
g_pClient->UnregisterWindow(hWnd);
break;
}
return 0;
}
bool __0XYOUROWN_API InstallHook()
{
// Call this one from your main process; set's up the system-wide hook.
g_hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTProcedure, g_hInstance, 0);
/** #pragma data_seg("Shared")
* HHOOK g_hHook = NULL;
* #pragma data_seg()
*/
return g_hHook != NULL;
}
/** The actual DLL...
*
*
*/
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
g_hInstance = (HINSTANCE)hModule;
if (::GetModuleHandle(_T("THEDESIREDMODULE.EXE")) != NULL) {
g_pClient = new Client();
if (g_pClient) {
InitializeCriticalSection(&g_CriticalSection); // You can setup a critic. sec. for later synchronization...
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);
DetourTransactionCommit();
}
}
break;
case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break;
case DLL_PROCESS_DETACH:
if (::GetModuleHandle(_T("THEDESIREDMODULE.EXE")) != NULL) {
if (g_pClient) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_DrawTextW, Mine_DrawTextW);
DetourTransactionCommit();
delete g_pClient;
g_pClient = NULL;
}
}
break;
}
}
It seems you're assuming printf() will call DrawText(). It won't. DrawText() is a GDI function. printf() goes to WriteConsole(). These don't intermix. "Console Windows" are quite unlike all other windows. This distinction is a fundamental architectural one; they're even managed by separate kernel components.
Only a side note: EasyHook - The reinvention of Windows API Hooking is an open source (LGPL) project developing a successor to Detours. It is quite mature already.