-3

I have been trying to make a universal DLL to where I can inject it into a process & a window would pop up. I have all required functions such as WinMain (I named mine Initiate and called it manually), DllWindowProcedure, and DllMain. However, after compilation, there is one warning and no errors - I believe it is a logical error. If you spot any issues, or anything I can improve, please let me know!

Warning:

1>Main.cpp(43): warning C4060: switch statement contains no 'case' or 'default' labels

Code:

#include <Windows.h>

HINSTANCE InjectedModuleHandle;

LRESULT CALLBACK DllWindowProcedure(HWND, UINT, WPARAM, LPARAM);

DWORD WINAPI DllThreadProcedure(void * Data)
{
    MessageBoxA(NULL, (LPCSTR)"Welcome to Flames v1.1!", (LPCSTR)"Startup Message", NULL);
    MSG Messages;
    WNDCLASSEX WindowClass;
    WindowClass.hInstance = InjectedModuleHandle;
    WindowClass.lpszClassName = L"DllWindowClass";
    WindowClass.lpfnWndProc = DllWindowProcedure;
    WindowClass.style = CS_DBLCLKS;
    WindowClass.cbSize = sizeof(WNDCLASSEX);
    WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WindowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WindowClass.lpszMenuName = NULL;
    WindowClass.cbClsExtra = 0;
    WindowClass.cbWndExtra = 0;
    WindowClass.hbrBackground = (HBRUSH)RGB(255, 255, 255);
    RegisterClassEx(&WindowClass);
    HWND Window = CreateWindowEx(0, L"DllWindowClass", L"Flames v1.1 - By XenoSaga3000", (WS_SYSMENU | WS_MINIMIZEBOX), 200, 200, 500, 450, FindWindow(NULL, L"ROBLOX"), CreateMenu(), InjectedModuleHandle, NULL);
    ShowWindow(Window, SW_SHOWNORMAL);
    while (GetMessage(&Messages, NULL, 0, 0))
    {
        TranslateMessage(&Messages);
        DispatchMessage(&Messages);
    };
    return 1;
};

LRESULT CALLBACK DllWindowProcedure(HWND Window, UINT Message, WPARAM WParameter, LPARAM LParameter)
{
    switch (Message)
    {
        case WM_COMMAND:
            switch(WParameter)
            {
                //Check for commands here.
            };
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(Window, Message, WParameter, LParameter);
    };
    return 0;
};

bool APIENTRY DllMain(HMODULE DllInstance, DWORD Reason, LPVOID Reserved)
{
    if(Reason == DLL_PROCESS_ATTACH)
    {
        InjectedModuleHandle = DllInstance;
        CreateThread(0, NULL, DllThreadProcedure, NULL, NULL, NULL);
    };
    return TRUE;
};
Levi Branch
  • 5
  • 2
  • 5

1 Answers1

2

You can look at this blog for an example for your case.

One of the differences is that it uses DllMain's provided HINSTANCE as the instance handle for the window class. GetModuleHandle(NULL) returns the instance handle of the calling process instead of the DLL.

Note that Windows API calls like CreateThread from DllMain are not recommended, see here.

Community
  • 1
  • 1
Ton Plooij
  • 2,583
  • 12
  • 15
  • @Levi Branch, apparently there are different opinions on that. Did the blog sample fix your issue? – Ton Plooij May 04 '16 at 19:38
  • 1
    @TonPlooij: The wording of [Dynamic-Link Library Best Practices](https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971.aspx) (*"should never [...] call `CreateThread`"*) is the source of confusion. What this really is trying to say is, that synchronization inside DllMain can lead to deadlocks. And when you do create a thread, you almost always implement some sort of synchronization. Creating a thread itself really is fine, since you can safely assume that *kernel32.dll* is always mapped into a running process. – IInspectable May 04 '16 at 19:49
  • @Ton Pooij I haven't tried it yet but I suspect it will. – Levi Branch May 04 '16 at 20:15
  • @TonPlooij I've rewritten my code based off the example with still no avail. Updated the thread. – Levi Branch May 04 '16 at 20:40
  • Also I forgot to mention, but the message box shows & the window doesn't if that helps narrow the issue. @TonPlooij – Levi Branch May 04 '16 at 20:44
  • Your code does not show a RegisterClassEx for your windows class. You should also check in the FindWindow for the parent succeeds and provides a correct handle. I suggest to follow the sample code as close a possible. – Ton Plooij May 04 '16 at 20:58
  • Also, your WNDCLASSEX omit CS_GLOBALCLASS. – user2120666 May 04 '16 at 21:15
  • Also your wchar_t * PString = reinterpret_cast(LpParameter); is wrong because you pass ANSI string. – user2120666 May 04 '16 at 21:20
  • Updated code again. Still no avail, only the message box works. – Levi Branch May 04 '16 at 21:27
  • I must note I did not follow the FindWindow advice because the DLL is meant for that specific process & I plan on having specific instructions for using it. Also, I was unable to do the CS_GLOBALCLASS because I have no idea where to find it. – Levi Branch May 04 '16 at 21:29
  • If you want your dll for only one process, omit CS_GLOBALCLASS is fine. But how you test your dll? – user2120666 May 04 '16 at 21:36
  • @user2120666: `CS_GLOBALCLASS` makes available a registered class to all **modules** in a process. You seem to imply that this class style would somehow allow a window class to be registered system-wide. This is not the case. – IInspectable May 04 '16 at 22:44
  • @user2120666 I inject it into RobloxPlayerBeta.exe, the actual target. – Levi Branch May 04 '16 at 22:50
  • Anyways, my problem is that I have no idea what CS_GLOBALCLASS is or how to implement it, so my DLL will never be fixed :( – Levi Branch May 04 '16 at 22:51
  • WindowClass.style = CS_DBLCLKS | CS_GLOBALCLASS; – user2120666 May 05 '16 at 06:58