Posts Tagged ‘CreateWindow

29
Mar
09

[C++] Creating a Window from a DLL

Currently I’ve been working on a project that requires me to inject a DLL to an external program, and create a window under that process.
Looking on the web, there are really very few resources explaining how to do this.

I don’t know if this is the ‘correct’ way to do this, but it works.
The basic idea behind it:

  • On inject
    • Create new thread
  • On new thread
    • Register window class
    • CreateWindowEx + ShowWindow
    • GetMessage and send them to a WndProc

Right so, starting off.
Create a new Windows DLL and add windows.h as an include
Now on the DLLMain, the entrypoint for the DLL, you want to add the code to create a new thread:

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call,LPVOID lpReserved)
{
	if(ul_reason_for_call==DLL_PROCESS_ATTACH) {
		inj_hModule = hModule;
		CreateThread(0, NULL, ThreadProc, (LPVOID)L"Window Title", NULL, NULL);
	}
	return TRUE;
}

Im passing our new windows title as the lParam for the tread, this is not necessary – and in this situation, silly.
Now we have a new thread, which has its start routine at ThreadProc
You will also need to create a new variable where we can store our modules handle:

HINSTANCE  inj_hModule;          //Injected Modules Handle

So now, lets set up our window.
We are going to create a function to register our window:

BOOL RegisterDLLWindowClass(wchar_t szClassName[])
{
    WNDCLASSEX wc;
    wc.hInstance =  inj_hModule;
    wc.lpszClassName = (LPCWSTR)szClassName;
    wc.lpfnWndProc = DLLWindowProc;
    wc.style = CS_DBLCLKS;
    wc.cbSize = sizeof (WNDCLASSEX);
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.lpszMenuName = NULL;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    if (!RegisterClassEx (&wc))
		return 0;
}

This function will register whatever class name is passed to it, again, in this situation it is unnecessary, you could just write:

wc.lpszClassName = (LPCWSTR)L"InjectedDLLWindowClass";

Now, we are going to make a function to create a menu for our window, to check that the messages are being received
Firstly, define two IDs for our menu

#define MYMENU_EXIT         (WM_APP + 101)
#define MYMENU_MESSAGEBOX   (WM_APP + 102)

Now the code for creating menus is fairly simple, we will just create 2 basic popup menus with two test buttons on, one to close the window, and one to display a messagebox.

HMENU CreateDLLWindowMenu()
{
	HMENU hMenu;
	hMenu = CreateMenu();
	HMENU hMenuPopup;
	if(hMenu==NULL)
           return FALSE;
	hMenuPopup = CreatePopupMenu();
	AppendMenu (hMenuPopup, MF_STRING, MYMENU_EXIT, TEXT("Exit"));
	AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hMenuPopup, TEXT("File")); 

	hMenuPopup = CreatePopupMenu();
	AppendMenu (hMenuPopup, MF_STRING,MYMENU_MESSAGEBOX, TEXT("MessageBox")); 
	AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hMenuPopup, TEXT("Test")); 
	return hMenu;
}

That returns a handle to our new menu, which we can pass to the CreateWindowEx function.
So, now lets deal with out ThreadProc, the start routine for the thread.
To begin with, I cast the lParam from a LPVOID – which contains our window name – back to a wchar_t
I then use the CreateDLLWindowMenu function and RegisterDLLWindowClass to be used in CreateWindowEx
Then just create the window, show it and handle the messages:

DWORD WINAPI ThreadProc( LPVOID lpParam )
{
	MSG messages;
	wchar_t *pString = reinterpret_cast<wchar_t * > (lpParam);
	HMENU hMenu = CreateDLLWindowMenu();
	RegisterDLLWindowClass(L"InjectedDLLWindowClass");
	prnt_hWnd = FindWindow(L"Window Injected Into ClassName", L"Window Injected Into Caption");
	HWND hwnd = CreateWindowEx (0, L"InjectedDLLWindowClass", pString, WS_EX_PALETTEWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, prnt_hWnd, hMenu,inj_hModule, NULL );
	ShowWindow (hwnd, SW_SHOWNORMAL);
	while (GetMessage (&messages, NULL, 0, 0))
	{
		TranslateMessage(&messages);
        	DispatchMessage(&messages);
	}
	return 1;
}

Since I wanted this window to have a parent, I used FindWindow to locate the handle, and passed that to the CreateWindowEx, you would need to add another HWND to your globals:

HWND       prnt_hWnd;            //Parent Window Handle

Now we need to set up our WndProc for the new window, this is stated in the RegisterDLLWindowClass:

wc.lpfnWndProc = DLLWindowProc;

So we create the WndProc and handle the messages that we will receive from the Menu (Exit and MessageBox)

LRESULT CALLBACK DLLWindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
		case WM_COMMAND:
               switch(wParam)
               {
                    case MYMENU_EXIT:
						SendMessage(hwnd, WM_CLOSE, 0, 0);
                        break;
                    case MYMENU_MESSAGEBOX:
						MessageBox(hwnd, L"Test", L"MessageBox",MB_OK);
                        break;
               }
               break;
		case WM_DESTROY:
			PostQuitMessage (0);
			break;
		default:
			return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}

Now if you were to inject this DLL into another process, you would get something that looked like this:
injectedwindow

Below is the complete code listing.
Continue reading ‘[C++] Creating a Window from a DLL’

Advertisements