I am trying to create a DLL which can be executed with RunDLL32. I know that RunDLL32 is running correctly because if I execute the following command, it pops up a message box:
rundll32 printui.dll,PrintUIEntry/.
However I cannot get it to execute a DLL that I created, which looks like this:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(0, L"Hello1", 0, 0);
break;
case DLL_THREAD_ATTACH:
MessageBox(0, L"Hello2", 0, 0);
break;
case DLL_THREAD_DETACH:
MessageBox(0, L"Hello3", 0, 0);
break;
case DLL_PROCESS_DETACH:
MessageBox(0, L"Hello4", 0, 0);
break;
}
return TRUE;
}
The code compiles fine (In Visual Studio 2017, Release mode, x64) but when I execute
RunDLL32 MyDLL.dll
Nothing happens. There are no error messages, not output, and no message boxes. Why is that?
Since your are compiling a 64bit DLL, make sure you are running the 64bit version of RunDll32:
rundll32.exe equivalent for 64-bit DLLs
Per this page:
If you pass the wrong type of DLL to Rundll32, it may fail to run without returning any error message.
Even if you could get RunDLL32 to load your DLL, you can't safely call MessageBox() in DllMain() at all.
You need to export a function for RunDLL32 to execute besides your DllMain. You can call MessageBox() in that function, eg:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" __declspec(dllexport) void CALLBACK MyFunctionW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
MessageBoxW(hwnd, lpszCmdLine, L"Hello", MB_OK);
}
rundll32 my.dll,MyFunction "hello world"
Related
I made in C++, DLL Injector and DLL file which one will be inject to process.
But how can I test my injector correct inject my dll file? Is possible send some logs from DLL file after inject to process?
Process and DLL file is 32bit.
There are probably better way but a message box and beep is provably sufficient
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hInstance = hModule;
DisableThreadLibraryCalls(hModule); //disable unwanted thread notifications to reduce overhead
//CreateThread(NULL, NULL, Engine, NULL, NULL, NULL);
_beginthreadex(NULL, NULL, Engine, NULL, NULL, NULL);
Beep(750, 500);
MessageBox(NULL, "Hello!!\r\nInjected", "Injected", MB_OK);
//MessageBox(NULL, L"Hello!!\r\nInjected", L"Injected", MB_OK); //unicode
break; //break attach
case DLL_PROCESS_DETACH:
break;
}
return true;
}
How I will be able to create a native dll that I can execute with rundll32.exe without specifying an entry point:
Example :
C: \> rundll32.exe mydll.dll
I created a DLL project on visual studio but I don't know where to put my code:
DLL project template generated by Visual Studio
// dllmain.cpp : Définit le point d'entrée de l'application DLL.
#include "pch.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;
}
my code that I want to run with the dll :
#include <stdio.h>
#include <stdlib.h>
// enable cross compiling
#ifdef __linux__
#include <sys/mman.h>
#elif _WIN32 || _MINGW_
#include <windows.h>
#endif
void main()
{
const char shellcode[] = "\x48\x83\xec\x48\x48\x83\xe4\xf0\x4c\x8d\x44\x24\x28\x48\x8d\x15\xda\x01\x00\x00\x48\x8d\x0d\xc6\x01\x00\x00\xe8\x64\x00\x00\x00\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x30\x48\x8d\x15\xca\x01\x00\x00\x48\x8d\x0d\xa9\x01\x00\x00\xe8\x47\x00\x00\x00\x48\x8d\x0d\xc3\x01\x00\x00\xff\x54\x24\x28\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x38\x48\x8d\x15\xb9\x01\x00\x00\x48\x8d\x0d\xa7\x01\x00\x00\xe8\x1f\x00\x00\x00\x4d\x31\xc9\x4c\x8d\x05\xcb\x01\x00\x00\x48\x8d\x15\xa8\x01\x00\x00\x48\x31\xc9\xff\x54\x24\x38\x48\x31\xc9\xff\x54\x24\x30\x48\x81\xec\x68\x01\x00\x00\x48\x89\x5c\x24\x28\x48\x89\x6c\x24\x30\x48\x89\x7c\x24\x38\x48\x89\x74\x24\x40\x4c\x89\x64\x24\x48\x4c\x89\x6c\x24\x50\x4c\x89\x74\x24\x58\x4c\x89\x7c\x24\x60\x65\x4c\x8b\x1c\x25\x60\x00\x00\x00\x4d\x8b\x5b\x18\x4d\x8d\x5b\x10\x4d\x89\xdf\x4d\x8b\x1b\xfc\x49\x8b\x7b\x60\x48\x89\xce\xac\x84\xc0\x74\x26\x8a\x27\x80\xfc\x61\x7c\x03\x80\xec\x20\x38\xc4\x75\x08\x48\xff\xc7\x48\xff\xc7\xeb\xe5\x4d\x8b\x1b\x4d\x39\xfb\x75\xd6\x48\x31\xc0\xe9\xb1\x00\x00\x00\x49\x8b\x5b\x30\x44\x8b\x63\x3c\x49\x01\xdc\x49\x81\xc4\x88\x00\x00\x00\x45\x8b\x2c\x24\x4d\x85\xed\x75\x08\x48\x31\xc0\xe9\x8e\x00\x00\x00\x4e\x8d\x1c\x2b\x45\x8b\x74\x24\x04\x4d\x01\xee\x41\x8b\x4b\x18\x45\x8b\x53\x20\x49\x01\xda\xff\xc9\x4d\x8d\x24\x8a\x41\x8b\x3c\x24\x48\x01\xdf\x48\x89\xd6\xa6\x75\x08\x8a\x06\x84\xc0\x74\x09\xeb\xf5\xe2\xe5\x48\x31\xc0\xeb\x55\x45\x8b\x63\x24\x49\x01\xdc\x66\x41\x8b\x0c\x4c\x45\x8b\x63\x1c\x49\x01\xdc\x41\x8b\x04\x8c\x4c\x39\xe8\x7c\x36\x4c\x39\xf0\x73\x31\x48\x8d\x34\x18\x48\x8d\x7c\x24\x68\xa4\x80\x3e\x2e\x75\xfa\xa4\xc7\x07\x44\x4c\x4c\x00\x4d\x89\xc6\x48\x8d\x4c\x24\x68\x41\xff\xd1\x4d\x89\xf0\x48\x8d\x4c\x24\x68\x48\x89\xf2\xe9\x08\xff\xff\xff\x48\x01\xd8\x49\x89\x00\x48\x8b\x5c\x24\x28\x48\x8b\x6c\x24\x30\x48\x8b\x7c\x24\x38\x48\x8b\x74\x24\x40\x4c\x8b\x64\x24\x48\x4c\x8b\x6c\x24\x50\x4c\x8b\x74\x24\x58\x4c\x8b\x7c\x24\x60\x48\x81\xc4\x68\x01\x00\x00\xc3\x4b\x45\x52\x4e\x45\x4c\x33\x32\x2e\x44\x4c\x4c\x00\x4c\x6f\x61\x64\x4c\x69\x62\x72\x61\x72\x79\x41\x00\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x55\x53\x45\x52\x33\x32\x2e\x44\x4c\x4c\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\x48\x69\x20\x66\x72\x6f\x6d\x20\x69\x6e\x6a\x65\x63\x74\x65\x64\x20\x73\x68\x65\x6c\x6c\x63\x6f\x64\x65\x21\x00\x53\x68\x65\x6c\x6c\x63\x6f\x64\x65\x54\x6f\x4a\x53\x63\x72\x69\x70\x74\x20\x50\x6f\x43\x20\x00";
PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
DWORD threadID;
HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID);
WaitForSingleObject(hThread, INFINITE);
}
The entry point parameter of rundll32 is not optional, you MUST specify an entry point, otherwise rundll32 won't know which function to call. There is no "default" entry point.
To be callable by rundll32, you must export a function with one of the following signatures:
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR pszCmdLine, int nCmdShow)
void CALLBACK EntryPointA(HWND hwnd, HINSTANCE hinst, LPSTR pszCmdLine, int nCmdShow)
void CALLBACK EntryPointW(HWND hwnd, HINSTANCE hinst, LPWSTR pszCmdLine, int nCmdShow)
For example:
#include "pch.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.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) void CALLBACK myFunc(HWND, HINSTANCE, LPSTR, int)
{
const char shellcode[] = "\x48\x83\xec\x48\x48\x83\xe4\xf0\x4c\x8d\x44\x24\x28\x48\x8d\x15\xda\x01\x00\x00\x48\x8d\x0d\xc6\x01\x00\x00\xe8\x64\x00\x00\x00\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x30\x48\x8d\x15\xca\x01\x00\x00\x48\x8d\x0d\xa9\x01\x00\x00\xe8\x47\x00\x00\x00\x48\x8d\x0d\xc3\x01\x00\x00\xff\x54\x24\x28\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x38\x48\x8d\x15\xb9\x01\x00\x00\x48\x8d\x0d\xa7\x01\x00\x00\xe8\x1f\x00\x00\x00\x4d\x31\xc9\x4c\x8d\x05\xcb\x01\x00\x00\x48\x8d\x15\xa8\x01\x00\x00\x48\x31\xc9\xff\x54\x24\x38\x48\x31\xc9\xff\x54\x24\x30\x48\x81\xec\x68\x01\x00\x00\x48\x89\x5c\x24\x28\x48\x89\x6c\x24\x30\x48\x89\x7c\x24\x38\x48\x89\x74\x24\x40\x4c\x89\x64\x24\x48\x4c\x89\x6c\x24\x50\x4c\x89\x74\x24\x58\x4c\x89\x7c\x24\x60\x65\x4c\x8b\x1c\x25\x60\x00\x00\x00\x4d\x8b\x5b\x18\x4d\x8d\x5b\x10\x4d\x89\xdf\x4d\x8b\x1b\xfc\x49\x8b\x7b\x60\x48\x89\xce\xac\x84\xc0\x74\x26\x8a\x27\x80\xfc\x61\x7c\x03\x80\xec\x20\x38\xc4\x75\x08\x48\xff\xc7\x48\xff\xc7\xeb\xe5\x4d\x8b\x1b\x4d\x39\xfb\x75\xd6\x48\x31\xc0\xe9\xb1\x00\x00\x00\x49\x8b\x5b\x30\x44\x8b\x63\x3c\x49\x01\xdc\x49\x81\xc4\x88\x00\x00\x00\x45\x8b\x2c\x24\x4d\x85\xed\x75\x08\x48\x31\xc0\xe9\x8e\x00\x00\x00\x4e\x8d\x1c\x2b\x45\x8b\x74\x24\x04\x4d\x01\xee\x41\x8b\x4b\x18\x45\x8b\x53\x20\x49\x01\xda\xff\xc9\x4d\x8d\x24\x8a\x41\x8b\x3c\x24\x48\x01\xdf\x48\x89\xd6\xa6\x75\x08\x8a\x06\x84\xc0\x74\x09\xeb\xf5\xe2\xe5\x48\x31\xc0\xeb\x55\x45\x8b\x63\x24\x49\x01\xdc\x66\x41\x8b\x0c\x4c\x45\x8b\x63\x1c\x49\x01\xdc\x41\x8b\x04\x8c\x4c\x39\xe8\x7c\x36\x4c\x39\xf0\x73\x31\x48\x8d\x34\x18\x48\x8d\x7c\x24\x68\xa4\x80\x3e\x2e\x75\xfa\xa4\xc7\x07\x44\x4c\x4c\x00\x4d\x89\xc6\x48\x8d\x4c\x24\x68\x41\xff\xd1\x4d\x89\xf0\x48\x8d\x4c\x24\x68\x48\x89\xf2\xe9\x08\xff\xff\xff\x48\x01\xd8\x49\x89\x00\x48\x8b\x5c\x24\x28\x48\x8b\x6c\x24\x30\x48\x8b\x7c\x24\x38\x48\x8b\x74\x24\x40\x4c\x8b\x64\x24\x48\x4c\x8b\x6c\x24\x50\x4c\x8b\x74\x24\x58\x4c\x8b\x7c\x24\x60\x48\x81\xc4\x68\x01\x00\x00\xc3\x4b\x45\x52\x4e\x45\x4c\x33\x32\x2e\x44\x4c\x4c\x00\x4c\x6f\x61\x64\x4c\x69\x62\x72\x61\x72\x79\x41\x00\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x55\x53\x45\x52\x33\x32\x2e\x44\x4c\x4c\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\x48\x69\x20\x66\x72\x6f\x6d\x20\x69\x6e\x6a\x65\x63\x74\x65\x64\x20\x73\x68\x65\x6c\x6c\x63\x6f\x64\x65\x21\x00\x53\x68\x65\x6c\x6c\x63\x6f\x64\x65\x54\x6f\x4a\x53\x63\x72\x69\x70\x74\x20\x50\x6f\x43\x20\x00";
PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (shellcode_exec) {
RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
DWORD dwOldProtect;
if (VirtualProtect(shellcode_exec, sizeof shellcode, PAGE_EXECUTE, &dwOldProtect)) {
FlushInstructionCache(GetCurrentProcess(), shellcode_exec, sizeof shellcode);
DWORD threadID;
HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID);
if (hThread) {
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
}
VirtualFree(shellcode_exec, 0, MEM_RELEASE);
}
}
C: \> rundll32.exe mydll.dll,myFunc <optional parameters here>
And just FYI, you don't actually need the worker thread at all, you can just execute the shell code directly like any other function:
__declspec(dllexport) void CALLBACK myFunc(HWND hwnd, HINSTANCE hinst, LPSTR pszCmdLine, int nCmdShow)
{
const char shellcode[] = "\x48\x83\xec\x48\x48\x83\xe4\xf0\x4c\x8d\x44\x24\x28\x48\x8d\x15\xda\x01\x00\x00\x48\x8d\x0d\xc6\x01\x00\x00\xe8\x64\x00\x00\x00\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x30\x48\x8d\x15\xca\x01\x00\x00\x48\x8d\x0d\xa9\x01\x00\x00\xe8\x47\x00\x00\x00\x48\x8d\x0d\xc3\x01\x00\x00\xff\x54\x24\x28\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x38\x48\x8d\x15\xb9\x01\x00\x00\x48\x8d\x0d\xa7\x01\x00\x00\xe8\x1f\x00\x00\x00\x4d\x31\xc9\x4c\x8d\x05\xcb\x01\x00\x00\x48\x8d\x15\xa8\x01\x00\x00\x48\x31\xc9\xff\x54\x24\x38\x48\x31\xc9\xff\x54\x24\x30\x48\x81\xec\x68\x01\x00\x00\x48\x89\x5c\x24\x28\x48\x89\x6c\x24\x30\x48\x89\x7c\x24\x38\x48\x89\x74\x24\x40\x4c\x89\x64\x24\x48\x4c\x89\x6c\x24\x50\x4c\x89\x74\x24\x58\x4c\x89\x7c\x24\x60\x65\x4c\x8b\x1c\x25\x60\x00\x00\x00\x4d\x8b\x5b\x18\x4d\x8d\x5b\x10\x4d\x89\xdf\x4d\x8b\x1b\xfc\x49\x8b\x7b\x60\x48\x89\xce\xac\x84\xc0\x74\x26\x8a\x27\x80\xfc\x61\x7c\x03\x80\xec\x20\x38\xc4\x75\x08\x48\xff\xc7\x48\xff\xc7\xeb\xe5\x4d\x8b\x1b\x4d\x39\xfb\x75\xd6\x48\x31\xc0\xe9\xb1\x00\x00\x00\x49\x8b\x5b\x30\x44\x8b\x63\x3c\x49\x01\xdc\x49\x81\xc4\x88\x00\x00\x00\x45\x8b\x2c\x24\x4d\x85\xed\x75\x08\x48\x31\xc0\xe9\x8e\x00\x00\x00\x4e\x8d\x1c\x2b\x45\x8b\x74\x24\x04\x4d\x01\xee\x41\x8b\x4b\x18\x45\x8b\x53\x20\x49\x01\xda\xff\xc9\x4d\x8d\x24\x8a\x41\x8b\x3c\x24\x48\x01\xdf\x48\x89\xd6\xa6\x75\x08\x8a\x06\x84\xc0\x74\x09\xeb\xf5\xe2\xe5\x48\x31\xc0\xeb\x55\x45\x8b\x63\x24\x49\x01\xdc\x66\x41\x8b\x0c\x4c\x45\x8b\x63\x1c\x49\x01\xdc\x41\x8b\x04\x8c\x4c\x39\xe8\x7c\x36\x4c\x39\xf0\x73\x31\x48\x8d\x34\x18\x48\x8d\x7c\x24\x68\xa4\x80\x3e\x2e\x75\xfa\xa4\xc7\x07\x44\x4c\x4c\x00\x4d\x89\xc6\x48\x8d\x4c\x24\x68\x41\xff\xd1\x4d\x89\xf0\x48\x8d\x4c\x24\x68\x48\x89\xf2\xe9\x08\xff\xff\xff\x48\x01\xd8\x49\x89\x00\x48\x8b\x5c\x24\x28\x48\x8b\x6c\x24\x30\x48\x8b\x7c\x24\x38\x48\x8b\x74\x24\x40\x4c\x8b\x64\x24\x48\x4c\x8b\x6c\x24\x50\x4c\x8b\x74\x24\x58\x4c\x8b\x7c\x24\x60\x48\x81\xc4\x68\x01\x00\x00\xc3\x4b\x45\x52\x4e\x45\x4c\x33\x32\x2e\x44\x4c\x4c\x00\x4c\x6f\x61\x64\x4c\x69\x62\x72\x61\x72\x79\x41\x00\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x55\x53\x45\x52\x33\x32\x2e\x44\x4c\x4c\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\x48\x69\x20\x66\x72\x6f\x6d\x20\x69\x6e\x6a\x65\x63\x74\x65\x64\x20\x73\x68\x65\x6c\x6c\x63\x6f\x64\x65\x21\x00\x53\x68\x65\x6c\x6c\x63\x6f\x64\x65\x54\x6f\x4a\x53\x63\x72\x69\x70\x74\x20\x50\x6f\x43\x20\x00";
PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (shellcode_exec) {
RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
DWORD dwOldProtect;
if (VirtualProtect(shellcode_exec, sizeof shellcode, PAGE_EXECUTE, &dwOldProtect)) {
PTHREAD_START_ROUTINE proc = (PTHREAD_START_ROUTINE) shellcode_exec;
proc(NULL);
}
VirtualFree(shellcode_exec, 0, MEM_RELEASE);
}
}
I've got a Win32 exe which I want to convert into an injectable Dll file.
This is what I tried:
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwAttached, LPVOID lpvReserved)
{
if (dwAttached == DLL_PROCESS_ATTACH) {
CreateThread(NULL, 0, &WinMain, NULL, 0, NULL); //This doen't work...
}
return 1;
}
I don't know how to make it call WinMain on attach.
How do I do it the right way. Thanks for your help.
Try this :
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwAttached, LPVOID lpvReserved)
{
if (dwAttached == DLL_PROCESS_ATTACH) {
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WinMain, NULL, 0, NULL); //starts the routine in anew thread
}
return 1;
}
I am trying to hook win32 API function "CreateFile" using MS Detours, but when I test it by opening a *.doc file using MS Word, The CreateFile call for DLLs and font files and directories loaded by MS Word are redirected to my detoured function but not for that *.doc file, but when I open a *.txt file using notepad the CreateFile call for that *.txt file comes to my detoured function.
I am using following code for hooking CreateFile:
static HANDLE (WINAPI *Real_CreateFile)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) = CreateFile;
HANDLE WINAPI Routed_CreateFile(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
OutputDebugString(lpFileName);
return Real_CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
LONG Error;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
OutputDebugString(L"Attaching MyDLL.dll");
OutputDebugString(strInfo);
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_CreateFile, Routed_CreateFile);
Error = DetourTransactionCommit();
if (Error == NO_ERROR)
OutputDebugString(L"Hooked Success");
else
OutputDebugString(L"Hook Error");
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
OutputDebugString(L"De-Attaching MyDLL.dll");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_CreateFile, Routed_CreateFile);
Error = DetourTransactionCommit();
if (Error == NO_ERROR)
OutputDebugString(L"Un-Hooked Success");
else
OutputDebugString(L"Un-Hook Error");
break;
}
return TRUE;
}
Thanks in advance.
I think you are missing a break after this:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break; // Not interested in thread messages
case DLL_PROCESS_DETACH:
Are you just detaching the detour before it is called? Maybe opening a .doc creates a new thread but a .txt doesn't, triggering this code path.
It looks like you're not initializing your Real_CreateFile function pointer properly. I'm guessing you're setting it to your module's import table entry for CreateFile.
Instead, initialize it to GetProcAddress(GetModuleHandle("kernel32"),"CreateFileW");
Hello everyone,
I am making a VC++ 2008 project in pure Win32 API which uses common controls. Now the problem that I am facing is if I explicitly link to the comctl32.dll(version 6.0.) in the WinSXS folder using the LoadLibrary API function, my main window does not even display. But if I use the #pragma comment in my code as such -:
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
and add the comctl32.lib to my project dependencies then run it then I get my expected output. But if I link manually to the comctl32.dll in the WinSXS using LoadLibrary API function and then get the procedure address of InitCommonControls using the GetProcAddress Api function and then call it my main window does not even display. Why is this happening?
By definition I should be able to load my dll manually locate the required procedure that I want to use and execute it, but for some reason this is not happening here.
this is the code that I am using -:
#include <Windows.h>
#include <CommCtrl.h>
#include "resource.h"
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DialogFunc(HWND, UINT, WPARAM, LPARAM);
char szWinName[]="Timer Main Window";
HWND hDlg=NULL;
HINSTANCE hInst;
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst,
LPSTR lpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
HMODULE hmod=NULL;
void (*InitCommonControls)(void)=NULL;
wndclass.cbSize=sizeof(WNDCLASSEX);
wndclass.hInstance=hThisInst;
wndclass.lpszClassName=szWinName;
wndclass.lpfnWndProc=WindowFunc;
wndclass.style=0;
wndclass.hIcon=LoadIcon(hThisInst,MAKEINTRESOURCE(IDI_ICON1));
wndclass.hIconSm=LoadIcon(hThisInst,MAKEINTRESOURCE(IDI_ICON2));
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.lpszMenuName=NULL;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH) GetStockObject(LTGRAY_BRUSH);
if(!RegisterClassEx(&wndclass)) return 0;
/*Initialize the common controls for WinXP look and feel*/
hmod=LoadLibrary("C:\\WINDOWS\\WinSxS\\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.6028_x-ww_61e65202\\comctl32.dll");
if (!hmod)
{ MessageBox(NULL,"dll not loaded","error",MB_ICONERROR);
}
InitCommonControls=(void (*)(void)) GetProcAddress(hmod,
"InitCommonControls");
if(InitCommonControls==NULL){
MessageBox(NULL,"no entry point","error",MB_ICONERROR);
}
(*InitCommonControls)();
//FreeLibrary(hmod);
//hmod=NULL;
hInst=hThisInst;
hwnd=CreateWindow(
szWinName,
"Auto Timer (Work in progress)",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hThisInst,
NULL
);
while(GetMessage(&msg, NULL, 0, 0)>0)
{ if (!hDlg||!IsDialogMessage(hDlg,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wparam,
LPARAM lparam)
{
switch(message){
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
hDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_FORMVIEW),
hwnd,(DLGPROC)DialogFunc);
break;
default:
return DefWindowProc(hwnd,message,wparam,lparam);
}
return 0;
}
BOOL CALLBACK DialogFunc(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam)
{
switch(message)
{
case WM_INITDIALOG:
SendMessage(hwnd,WM_SETICON, ICON_SMALL ,
(LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON2)));
break;
case WM_CTLCOLORSTATIC:
return (INT_PTR)GetStockObject(WHITE_BRUSH);
case WM_CLOSE:
DestroyWindow(hwnd);
hDlg=NULL;
PostQuitMessage(0);
return TRUE;
}
return FALSE;
}
If anyone wants the entire project please give me your mail id and I will send the entire project to them. I want to know exactly why this is happening not whether I should do it or not.Thank You.
The working case
Your manifest refences the Microsoft.Windows.Common-Controls assembly. This assembly is a collection of one or more DLLs and COM objects, it is not a .Net assembly. When your application is launched Windows creates an activation context. Any references to a DLL or COM object that is described in the assembly are redirected to the requested version. The activation context remains active during calls into comctl32.dll, so any calls it makes to DLLs or COM objects will also be redirected.
The not-working case
You load a specific version of comctl32.dll from \Windows\Sxs\. This references other DLLs or COM objects but, in the absence of an activation context, the wrong ones are loaded. And your application doesn't work.
Conclusion
I don't know if this is the specific problem in your case, but in general anything that lives in \Windows\Sxs is intended to run in a particular activation context, and you can't expect it to work outside of that context. Even if it did happen to work, it might break in the future. Don't do this.