## Archive for the 'C++' Category

19
May
09

### [C++] Numbers with 6 divisors where none of the divisors are primes > 5

My uncle phoned me up to day with a question:

N is a number that has exactly 6 factors.
One of the factors is 1, and another is the number itself.
None of the prime factors of N can be greater than 5
Find a method for calculating a set of vales that would suit N.

Well. To be honest, after literally hours of trying to work out how to do this, I gave up and decided to program a brute force algorithm that would do this for me:

```#include "stdafx.h"
#include "math.h"

int main()
{
//Algorithm to calculate numbers where
//Number of divisors < 7
//None of the prime divisors > 5
for(int i=1;i<100;i++) {
int dc = 0; //divisor count
bool pc = true; //prime check
for(int k=1;k<(i/2)+1;k++) { //loop through all the numbers up to (n/2)+1
if(i%k==0) { //check to see if divides with no remainder
dc++; //increase divisor count
if(dc > 5) { //if divisor count greater than 5, then quit - this number is not valid
dc++;
break;
} else { //else we need to check the divisor
if(k>5) {//if the divisor is bigger than 5, we need to check if it is prime
bool ip = true; //is prime?
for(int j = 2; j <= sqrt((double)k); j++)  //loop through the possible values
if(k % j == 0) //check remainder
ip=false;
if(ip==true) { //sorry, its too big to be prime. quit
pc=false;
break;
}
}
}
}
}
if(dc==5 && pc==true) //check number is prime valid and has 6 divisors
printf("Valid Number %d, \n", i);
}
return 0;
}```

That would produce the list of valid numbers, those being:
12 : [1, 2, 3, 4, 6, 12]
18 : [1, 2, 3, 6, 9, 18]
20 : [1, 2, 4, 5, 10, 20]
32 : [1, 2, 4, 8, 16, 32]
45 : [1, 3, 5, 9, 15, 45]
50 : [1, 2, 5, 10, 25, 50]
75 : [1, 3, 5, 15, 25, 75]

13
May
09

### [C++] CBT Hook Example

Got bored of doing revision and started on a HookLib, this is an example program where I was testing using a CBT Hook.

```#include "windows.h"

bool SetCBTHook(DWORD, HWND);
void RemoveCBTHook(); ```

Main.cpp

```#include "header.h"

#define IDC_LIST 4000

HINSTANCE	mhInstance;
HWND		mhWnd;
HWND		lvhWnd;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
break;
case WM_DESTROY:
RemoveCBTHook();
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}

BOOL RegisterClass(wchar_t szClassName[])
{
WNDCLASSEX wc;
wc.hInstance =  mhInstance;
wc.lpszClassName = (LPCWSTR)szClassName;
wc.lpfnWndProc = WindowProc;
wc.style = CS_DBLCLKS;
wc.cbSize = sizeof (WNDCLASSEX);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&wc))
return 0;
else
return 1;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreviousInstance,LPSTR lpcmdline,int nCmdShow)
{
MSG messages;
mhInstance = hInstance;
wchar_t ClassName[ ] = L"CBTHookClass";
wchar_t WindowName[ ] = L"CBTHookWindow";
RegisterClass(ClassName);
mhWnd = CreateWindowEx(WS_EX_CONTROLPARENT, ClassName, WindowName, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_MAXIMIZEBOX, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
lvhWnd = CreateWindow(L"LISTBOX",L"CBTHookListBox",WS_CHILD|WS_VISIBLE|WS_VSCROLL, 2,2,490,479,mhWnd, (HMENU)IDC_LIST,hInstance, NULL );
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return 0;
} ```

CBTHook.cpp

```#include "header.h"
#include <stdlib.h>
#include <sstream>
#include <string>

HHOOK	CBT_HOOK_ID;
HWND	hWnd;

using namespace std;

std::wstring StringToWString(const std::string& s)
{
std::wstring temp(s.length(),L' ');
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}

}

ostringstream oss;
oss << hex << (int)hwnd;
wstring Message = L" ---Window Handle: 0x" + StringToWString(oss.str());
}

//	string out;
//	ostringstream oss;
//	oss << rect.top;
//	out = oss.str();
//	oss << rect.bottom;
//	out = out + ", " + oss.str();
//	oss << rect.left;
//	out = out + ", " + oss.str();
//	oss << rect.right;
//	out = out + ", " + oss.str();
//	wstring Message = L"Window Moved/Resized: " + StringToWString(out);
//}

static LRESULT CALLBACK CBTHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode > 0) {
CBT_CREATEWND	*CBTHOOKCREATE;
RECT			*CBTRECTPTR;
RECT			CBTRECT;
wstring			Message;

switch (nCode)
{
case HCBT_ACTIVATE:
case HCBT_CREATEWND:
CBTHOOKCREATE = (CBT_CREATEWND*) lParam;
Message = L" ---Window Name: ";
Message = Message + CBTHOOKCREATE->lpcs->lpszName;
}

Message = L" ---Window Class: ";
Message = Message + CBTHOOKCREATE->lpcs->lpszClass;
}
case HCBT_DESTROYWND:
case HCBT_MINMAX:
switch(lParam)
{
case SW_HIDE:
break;
case SW_MAXIMIZE:
break;
case SW_MINIMIZE:
break;
case SW_RESTORE:
break;
case SW_SHOW:
break;
case SW_SHOWDEFAULT:
break;
case SW_SHOWMINIMIZED:
break;
case SW_SHOWMINNOACTIVE:
break;
case SW_SHOWNA:
break;
case SW_SHOWNOACTIVATE:
break;
case SW_SHOWNORMAL:
break;
}
case HCBT_MOVESIZE:
//CBTRECTPTR = (RECT*) lParam;
//memcpy(&CBTRECT, CBTRECTPTR, sizeof(RECT));
break;
}
}
return CallNextHookEx(CBT_HOOK_ID, nCode, wParam, lParam);
}

bool SetCBTHook(DWORD ThreadID, HWND ThisMainWindow) {
hWnd = ThisMainWindow;
HHOOK CBT_HOOK_ID = ::SetWindowsHookEx(WH_CBT, CBTHookProc, 0, ThreadID);
MessageBox(NULL, L"Hey", L"There", 1);
if(CBT_HOOK_ID)
return true;
else
return false;
}

void RemoveCBTHook() {
UnhookWindowsHookEx(CBT_HOOK_ID);
} ```

Its just a quick throw-together of setting a cbt hook on your window, the HookLib exports the hook function, allowing you to hook any process/the entire system.
Also note that the IsBadReadPtr is just there to ensure that the structure returned by the hook is valid, as sometimes it isnt causing the function to die.

09
May
09

After quite some time and a lot of research, I finally got it to work. The method is summarised below:

```xProcess = eXternal Process
Find xProc Window
Find Treeview in window
Get xProcess ID
Set Debug Privelages
Open xProcess
Allocate Memory in xProc
Get Root Node
Loop:
Create and fill TVITEM structure
Write TVITEM to xprocess
Send GET_ITEM to get Node name
print
Get Next Node
Free Memory
Close Handle```

I also had some trouble in some processes with trying to open them, so the code includes a setDebug function that changes your privileges and is used in the printTreeviewNodes function before attempting to open the process. Below is the code, including an example of how to use it (Using Teamspeak 2 as a target program):

```// Read External Treeview.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "commctrl.h"
#include <iostream>

using namespace std;

bool setDebug() {
HANDLE hToken;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
if(AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &tpPrevious, &cbPrevious)) {
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
if(AdjustTokenPrivileges( hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL )) {
CloseHandle(hToken);
return true;
}
}
}
}
CloseHandle(hToken);
return false;
}

void printTreeviewNodes(HWND treeview) {
DWORD pID;
if(pID) {
if(setDebug()) {
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
if(hProcess) {
/*
Memory allocation:
0---------|---------|----------------14F
TVITEM    rBuffer       pszText
(28)      (28)          (FF)
*/
DWORD remoteBuffer = (DWORD)::VirtualAllocEx(hProcess, NULL, 335, MEM_COMMIT, PAGE_READWRITE);
if(remoteBuffer) {
HTREEITEM Root = (HTREEITEM)::SendMessage(treeview, TVM_GETNEXTITEM, TVGN_ROOT, 0);
while(Root) {
TVITEM tvItem;
tvItem.hItem = Root;
tvItem.pszText = (LPWSTR)remoteBuffer + sizeof(TVITEM);
tvItem.cchTextMax = 255;
if(WriteProcessMemory(hProcess, (LPVOID)remoteBuffer, (LPCVOID)&tvItem, sizeof(TVITEM), 0)) {
SendMessage(treeview, TVM_GETITEM, 0, remoteBuffer);
wchar_t bytRtn[255];
int rAdd = remoteBuffer + sizeof(TVITEM)*2;
wcout << bytRtn << endl;
}
Root = (HTREEITEM)::SendMessage(treeview, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)Root);
}
}
VirtualFreeEx(hProcess, (LPVOID)remoteBuffer, 335, MEM_RELEASE);
}
}
CloseHandle(hProcess);
}
}
}

int _tmain(int argc, _TCHAR* argv[])
{
HWND tsmhWnd = FindWindow(L"TMainForm", L"TeamSpeak 2");
tsmhWnd = FindWindowEx(tsmhWnd, NULL, L"TPanel", NULL);
HWND tsTVhWnd = FindWindowEx(tsmhWnd, NULL, L"TTreeView", NULL);
printTreeviewNodes(tsTVhWnd);
return 0;
}```

If anybody has a better method than this or any comments, I’d be more than happy for input ^^

24
Apr
09

### [C++] :Minesweeper: In-game Toggle Mine Visibility

Minesweeper stores its minefield in memory, starting at the addressÂ  0x1005360, and is set up looking like this:

```>>>>>>>>>
>*---*-->
>-*----*>
>-**-*-->
>------->
>---*--->
>>>>>>>>>```

With the >’s representing a 1 Byte border, the *’s being mines, and -‘s being empty spaces.
Knowing this, we can effectively create a loop that reads this memory, and checks if a square is a bomb or not.

In order to calculate the size of the loop, we need to read the width and height from the game. These are stored at the two following addresses: 0x1005334 and 0x1005338. The maximum width of the board, is 0x1E, which is 0x20-2, 2 for the border. So, we now know that we can read each column by looping along the rows between 0 and nwidth, and the columns can be calculated by adding 0x20 to the address, each pass between 0 and nheight.

So, now we have the loop sorted, we just need to check if the current address holds a mine, if so, display it to the user.

```bool MinesCheat = false;

void ToggleMinesCheat()
{
int maxX = *((int*) 0x1005334);
int maxY = *((int*) 0x1005338);

for(int y = 0;y<maxY;y++) {
for (int x = 0;x<maxX;x++) {
BYTE mine = 0x8F;
if(MinesCheat)
mine = 0x8A;
if(*xmine==mine) {
if(MinesCheat)
*xmine = 0x8F;
else
*xmine = 0x8A;
}
}
}
InvalidateRect(mhWnd, NULL, 1);
UpdateWindow(mhWnd);
MinesCheat = MinesCheat^true;
}```

That will either loop through the memory displaying the mines location, by overwriting the memory with 0x8A (Visible Mine), or if the function has already been ran, will hide the mines again by writing the memory with 0x8F (hidden mine)

24
Apr
09

### [C++] :Minesweeper: Toggle Mine Visibility

winmine.StartGame+74

```010036EE   |.^\75 D7             JNZ SHORT winmine.010036C7              ;  if its not a mine, jmp back
010036F0   |.  C1E0 05           SHL EAX,5
010036F3   |.  8D8430 40530001   LEA EAX,DWORD PTR DS:[EAX+ESI+rgBlk]
010036FA       8008 80           OR BYTE PTR DS:[EAX],80                 ;  set the square to a mine
010036FD   |.  FF0D 30530001     DEC DWORD PTR DS:[cBombStart]           ;  decrease bomb count
01003703   |.^ 75 C2             JNZ SHORT winmine.010036C7              ;  jmp back if not all bombs set```

The above is part of the code that is used in generating the minefield for the game. The game randomly calculates if the square is a bomb, and then at 0x010036FA, it OR’s the value of 0x80 with the default value, 0x0F, giving 0x8F.
From reversing the game further, we know that these are the possible values for the mines:

```x0 = Blank Square (Pressed)
x1 = #1
x2 = #2
x3 = #3
x4 = #4
x5 = #5
x6 = #6
x7 = #7
x8 = #8
x9 = ? (Pressed)
xA = Mine
xB = Incorrect Mine
xC = Clicked Mine
xD = ? (Unpressed)
xE = Flag
xF = Blank Square (Unpressed)```

Where x = 0; the square is not a mine.
Where x = 4; the square was clicked on.
Where x = 8; the square is a mine.
Where x = C; the square was a clicked on mine.

Now, we can modify the assembly at 0x010036FA to set it to one of these values to show that there is a bomb there.

```bool MineVisCheat = false;

void ToggleMineVisibleCheat()
{
int *ori_OR = ((int*) 0x010036FA);
BYTE MOV[3];
if(MineVisCheat) {
MOV[0] = 0x80;
MOV[1] = 0x08;
MOV[2] = 0x80;
}
else {
MOV[0] = 0xC6;
MOV[1] = 0x00;
MOV[2] = 0x8A;
}
DWORD dwProtection;
memcpy(ori_OR, &MOV, 3);
VirtualProtect((LPVOID)0x010036FA, 1,dwProtection,&dwProtection);
MineVisCheat = MineVisCheat^true;
}```

Using the values above, this sets the opcode from OR BYTE PTR DS:[EAX],80 to MOV BYTE PTR DS:[EAX],8A. You would modify the image shown by changing the last byte of MOV to one of the values from the list.

```010036EE   |.^\75 D7             JNZ SHORT winmine.010036C7
010036F0   |.  C1E0 05           SHL EAX,5
010036F3   |.  8D8430 40530001   LEA EAX,DWORD PTR DS:[EAX+ESI+rgBlk]
010036FA       C600 8E           MOV BYTE PTR DS:[EAX],8A
010036FD   |.  FF0D 30530001     DEC DWORD PTR DS:[cBombStart]
01003703   |.^ 75 C2             JNZ SHORT winmine.010036C7```

One thing to take into account however, is that this will require you to start a new game before the effects come into place, as it overwrites the values while the grid is being drawn out.

24
Apr
09

### [C++] :Minesweeper: Toggle Timer

Local call from MainWndProc+1A3
winmine.DoTimer

```01002FE0 w>/\$  833D 64510001 00  CMP DWORD PTR DS:[fTimer],0
01002FE7       74 1E             JE SHORT winmine.01003007
01002FE9   |.  813D 9C570001 E70>CMP DWORD PTR DS:[cSec],3E7
01002FF3   |.  7D 12             JGE SHORT winmine.01003007
01002FF5       FF05 9C570001     INC DWORD PTR DS:[cSec]
01002FFB   |.  E8 B5F8FFFF       CALL winmine.DisplayTime
01003000   |.  6A 01             PUSH 1
01003002   |.  E8 E6080000       CALL winmine.PlayTune
01003007   \>  C3                RETN```

At 0x01002FE7 you have an instruction that checks to see if the game is running. If the value is equal, then it jumps over.
There would be many ways to effectively removing the timer, I have done it by changing the opcode of JE, to that of an short unconditional jump, 0xEB.

```bool TimerCheat = false;

void ToggleTimerCheat()
{
int *ori_JE = ((int*) 0x01002FE7);
int JMP;
if(TimerCheat)
JMP = 0x74;
else
JMP = 0xEB;
DWORD dwProtection;
memcpy(ori_JE, &JMP, 1);
VirtualProtect((LPVOID)0x01002FE7, 1,dwProtection,&dwProtection);
TimerCheat = TimerCheat^true;
}```

The above code will either enable or disable the timer based upon the bool TimerCheat.
After calling the function, the timer will not increase, the DoTimer function should look like:

```01002FE0 w>/\$  833D 64510001 00  CMP DWORD PTR DS:[fTimer],0
01002FE7       EB 1E             JMP SHORT winmine.01003007
01002FE9   |.  813D 9C570001 E70>CMP DWORD PTR DS:[cSec],3E7
01002FF3   |.  7D 12             JGE SHORT winmine.01003007
01002FF5       FF05 9C570001     INC DWORD PTR DS:[cSec]
01002FFB   |.  E8 B5F8FFFF       CALL winmine.DisplayTime
01003000   |.  6A 01             PUSH 1
01003002   |.  E8 E6080000       CALL winmine.PlayTune
01003007   \>  C3                RETN```
20
Apr
09

### [C++] Approximating Squares: Babylonian Method

```const double EPSILON = 1.0e-16;

double BabylonianMethod(double value, int& counter)
{
counter = 1;
double guess=value/2;
double result = ((value/guess)+guess)/2;
while(abs(result-guess)>EPSILON)
{
guess = result;
result = ((value/guess)+guess)/2;
counter++;
}
return result;
}```

Usage:

```	int counter;
double value = 10;
double res = BabylonianMethod(value, counter);
std::cout << std::setprecision(16);
std::cout << "Square root of " << value << " is " << res << "\n";
std::cout << "Number of iterations is " << counter << "\n";```

Would Output:
Square root of 10 is 3.16228
Number of iterations is 6

19
Apr
09

### [C++] Approximating Squares: Bakhshali Approximation

```double BakhshaliApproximation(double value, int n)
{
return (n+((value - n*n)/(2*n)))-(((value - n*n)/(2*n))*((value - n*n)/(2*n))/(2*(n+((value - n*n)/(2*n)))));
}```

Usage:
Where Value = the square you wish to find and N = Closest perfect square to Value.

`std::cout << BakhshaliApproximation(9.2345, 3) << "\n";`

Would Output:
3.038832022859598

which is approx = Sqrt(9.2345)

15
Apr
09

### [C++] Getting Register Values

I was asked today about how to get the values from the processor registers today, and here is the very simple answer.
It uses some inline asm to move the value of EDX into a variable.
There are 2 functions: setEDX and getEDX; which do exactly what they say.

```#include <iostream>

void setEDX(int value) {
//Moves 'value' into edx
_asm mov edx, value;
}

int getEDX() {
int value;
//Moves edx into 'value'
_asm mov value, edx;
return value;
}

int main()
{
int edxValue = getEDX() ; //Get Register
std::cout << "EDX: " << edxValue << "\n"; // Display

std::cout << "Set EDX Value: ";
int value;
std::cin >> value; //Get input
setEDX(value); //Set register

edxValue = getEDX() ; //Get Register
std::cout << "EDX: " << edxValue << "\n"; //Display

system("pause");
return 1 ;
}
```

The programs output is essentially just this:
```EDX: 1 Set EDX Value: 54321 EDX: 54321 Press any key to continue . . .```

Showing the original value, setting the value, and displaying the set value.

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
• 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;
}
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.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)

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()
{
return FALSE;

}```

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);
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)
{
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
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:

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