Hie,

I'm trying to get a code in a DLL runned each time a program is launched.

1) I have put this value in the registery key :

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows="D:\myDLL.dll"

2)

BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    FILE *log = fopen("D:\\log.txt", "a");
    fprintf(log, "DllMain called\n");
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        fprintf(log,"DLL_PROCESS_ATTACH\n");
		break;
      case DLL_PROCESS_DETACH:
        fprintf(log,"DLL_PROCESS_DETACH\n");
        break;

      case DLL_THREAD_ATTACH:
        fprintf(log,"DLL_THREAD_ATTACH\n");
        break;

      case DLL_THREAD_DETACH:
        fprintf(log,"DLL_THREAD_DETACH\n");
        break;
    }
    fclose(log);
    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}

I compile MyDLL.DLL, put it on my D:\ drive. Afterwards, I run several .exe

The LOG.TXT file I expected to be created is just missing !!


Please can someone help me !

Dani AI

Generated

Short answer: two different problems are likely at work here — the AppInit_DLLs approach is fragile on modern Windows, and calling C-runtime file I/O from DllMain is unsafe and often won’t produce a log. As discovered, simply setting AppInit_DLLs is not a guaranteed way to run code in every process (Windows has added code-signing rules and Secure Boot can disable AppInit entirely). (learn.microsoft.com)

About your DllMain: DllMain runs while the loader lock is held and you must keep it tiny. Calling C runtime routines like fopen (and other CRT APIs) from DllMain is unreliable because the CRT may not be initialized in the host process; many APIs (LoadLibrary, registry calls, heavy sync, etc.) are explicitly discouraged. For debugging use OutputDebugString/DebugView or do minimal kernel32 calls (CreateFile/WriteFile) or better yet perform real work from a worker thread created safely after attach. (learn.microsoft.com)

If you want programmatic injection, use the standard, reliable pattern: allocate memory in the target with VirtualAllocEx, write the full DLL path with WriteProcessMemory, then call CreateRemoteThread with the remote thread start address set to LoadLibraryA (so the remote process runs LoadLibrary on your path). Make sure the target handle has the required access rights (CREATE_THREAD / VM_OPERATION / VM_WRITE / VM_READ) and that DLL bitness matches the target process; creating the process suspended and injecting before resume is a common, robust workflow. Also remember LoadLibrary only calls DllMain on the first load of that DLL in the process. (flylib.com)

Quick checklist to troubleshoot now (ties back to suggestions by , and ):

  • Verify target bitness and build the DLL for that bitness (x86 vs x64). (reverseengineering.stackexchange.com)
  • If using AppInit_DLLs, check LoadAppInit_DLLs and RequireSignedAppInit_DLLs and be aware Secure Boot may block it. (learn.microsoft.com)
  • Use Process Explorer / ListDLLs to confirm a DLL was loaded and DebugView (OutputDebugString) to view quick traces. (documentation.help)

These checks explain why your DllMain log never appeared and point to more reliable injection and debugging approaches.

Recommended Answers

All 4 Replies

why do you think that registry key is going to launch mydll.dll every time a program is run? I tried it on my XP computer and it does nothing too.

Thx dear dragon,

My attempt refers to an article I've read on :

I missed my copy/paste in my last post : The real name of the incriminated registry key is "
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLS"

soorry for the confusion :(

Anyway, it does not seem to work, I've tried to inject my DLL several ways, and I just cannot get my DllMain() function called.

Here is an exemple for a second attempt I made, using CreateRemoteThread :

DLL.H :

#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */


DLLIMPORT void HelloWorld (void);


#endif /* _DLL_H_ */

DLLMAIN.C :

/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

DLLIMPORT void HelloWorld ()
{
    FILE *log= fopen("D:\\log.txt", "a");
    fprintf(log, "Hello world !\n");
    fclose(log);
}


BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    return TRUE;
}

DLLMAIN.C is compiled in order to obtain an "inject.dll" file, I copy this file onto my D:\ drive.

I also put on D:\ a copy of the Notepad.exe executable.

The 'launcher' app :

#include <stdio.h>
#include <windows.h>

#define MAXINJECTSIZE 4096

typedef HINSTANCE (*LoadLibrary_Ptr)(LPCTSTR);
typedef FARPROC (*GetProcAddress_Ptr)(HMODULE, LPCSTR lpProcName);

typedef struct _injectionRoutineParam
{
        LoadLibrary_Ptr _call_LoadLibrary;
        GetProcAddress_Ptr _call_GetProcAddress;
        HINSTANCE _ret;
        FARPROC _proc;
        char _dll_name[1024];
        char _proc_name[256];
}InjectionRoutineParam;

DWORD __stdcall injectionThreadRoutine(InjectionRoutineParam* param)
{
      HINSTANCE hinstance = param->_call_LoadLibrary(param->_dll_name);
      param->_ret = hinstance;
      FARPROC proc= param->_call_GetProcAddress(hinstance, param->_proc_name);
      param->_proc = proc;
      return 0;
}

void inject(HANDLE process, char *dllName)
{
     char * procName ="HelloWorld";
     InjectionRoutineParam param;
     DWORD threadId;
     void *p = VirtualAllocEx( process, 0, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
     void *data = VirtualAllocEx( process, 0, sizeof(InjectionRoutineParam), MEM_COMMIT, PAGE_EXECUTE_READWRITE );
     
     HINSTANCE kernel32=LoadLibrary("KERNEL32.DLL");
     param._call_LoadLibrary = (LoadLibrary_Ptr)GetProcAddress( kernel32, "LoadLibraryA" );
     param._call_GetProcAddress = (GetProcAddress_Ptr)GetProcAddress( kernel32, "GetProcAddress" );
     memcpy(param._dll_name,dllName,strlen(dllName));
     memcpy(param._proc_name, procName, strlen(procName));
     
     WriteProcessMemory( process, p, (void*)&injectionThreadRoutine, MAXINJECTSIZE, 0 );
     WriteProcessMemory( process, data, (void*)&param, sizeof(InjectionRoutineParam), 0 );
     
     HANDLE remoteThread = CreateRemoteThread(process, NULL,0,(DWORD (__stdcall *)(LPVOID))p, data, 0, &threadId);
     WaitForSingleObject(remoteThread, INFINITE);
     DWORD read;
     ReadProcessMemory(process, data, &param, sizeof(InjectionRoutineParam), &read);
     VirtualFreeEx( process, p, 0, MEM_RELEASE );
     VirtualFreeEx( process, data, 0, MEM_RELEASE );
	 FreeLibrary( kernel32 );
}


void die(char *msg)
{
     fprintf(stderr, msg);
     exit(-1);
}

int main(int argc, char **argv)
{
    char * appName ="D:\\NOTEPAD.EXE";
    STARTUPINFO startupInfo;
    ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
    PROCESS_INFORMATION processInfo;
    BOOL procOk = CreateProcess(appName,NULL,NULL,NULL,FALSE,0,NULL,NULL,&startupInfo, &processInfo);
    
    if(!procOk)
    {
       die("Unable to create process");
    }
    
    inject(processInfo.hProcess, "D:\\INJECT.DLL");
    system("PAUSE");
    return EXIT_SUCCESS;
}

is compiled separately.

I hoped that my HelloWorld() function would be called, but nothing happens. It's really weird. Does anyone have an idea ?

Just do a while(1) loop and inside read all running prosesses by using PSAPI . CreateToolhelpSnapshot(..) as far i can remember .

Next do a CreateRemoteThread for all process (you need to have suffiecient permission , u can override it). Next Run the thread by ResumeThread or RunThread ... (can't remember crrctly) Do a MSDN search.

Your file will get created

I used the following code to inject a DLL into an other process. You could make a processsnapshot and every time a process gets added inject a DLL to it. I used a different way to get the handle.

HWND WindowHandle;
	DWORD processId;
	HANDLE processHandle;

	// find tibia window
	WindowHandle = FindWindow("name of program", NULL);
    if (WindowHandle)
	{
		// get process id
		GetWindowThreadProcessId(WindowHandle, &processId);

		// get handle
		processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);

		// set program to low cpu usage
		SetPriorityClass(processHandle, PRIORITY_BELOW_NORMAL);

		// inject dll into program
		InjectLibrary((DWORD)processHandle, "nameofdll.dll"); //This dll has to be in system or system32 (don't remember)
		// close process
		CloseHandle(WindowHandle);
        }

My dll included the following code:

BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
	if(ul_reason_for_call == DLL_PROCESS_ATTACH)
	{
	// Start running in the main thread
	CreateThread(NULL, 0, (unsigned long (__stdcall *)(void *))StartNewThread, NULL, 0, NULL);
	}
	return true;
}


int StartNewThread()
{
//this thread has to keep running while you want to execute the dll

       while(true) //semi-endless loop
       {
       Sleep(300); //It shouldn't cost too much CPU
       }

return 0;
}

I hope it helped.

Greetz, Eddy

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.