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.

header.h

#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.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;
	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 );
	SetCBTHook(GetCurrentThreadId(), mhWnd);
	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; 
}

void AddItem(LPCWSTR text) {
	SendDlgItemMessage(hWnd, 4000, LB_ADDSTRING, 0, (LPARAM)text);
}

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

//void AddRECT(RECT rect) {
//	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:
				AddItem(L"Window Activated");
			case HCBT_CREATEWND:
				CBTHOOKCREATE = (CBT_CREATEWND*) lParam;
				AddItem(L"Window Created");
				Message = L" ---Window Name: ";
				if(!IsBadReadPtr(CBTHOOKCREATE->lpcs, 1)) {
					if(!IsBadReadPtr(CBTHOOKCREATE->lpcs->lpszName, 1))
						Message = Message + CBTHOOKCREATE->lpcs->lpszName;
				}
				AddItem(Message.c_str());

				Message = L" ---Window Class: ";
				if(!IsBadReadPtr(CBTHOOKCREATE->lpcs, 1)) {
					if(!IsBadReadPtr(CBTHOOKCREATE->lpcs->lpszClass, 1))
						Message = Message + CBTHOOKCREATE->lpcs->lpszClass;
				}
				AddItem(Message.c_str());
				AddHWND(wParam);
			case HCBT_DESTROYWND:
				AddItem(L"Window Destroyed");
			case HCBT_MINMAX:
				switch(lParam)
				{
				case SW_HIDE:
					AddItem(L"Window Hidden");
					break;
				case SW_MAXIMIZE:
					AddItem(L"Window Maximized");
					break;
				case SW_MINIMIZE:
					AddItem(L"Window Minimized");
					break;
				case SW_RESTORE:
					AddItem(L"Window Restored");
					break;
				case SW_SHOW:
					AddItem(L"Window Shown");
					break;
				case SW_SHOWDEFAULT:
					AddItem(L"Window Shown Default");
					break;
				case SW_SHOWMINIMIZED:
					AddItem(L"Window Shown Minimized");
					break;
				case SW_SHOWMINNOACTIVE:
					AddItem(L"Window Shown Minimized (Not Active)");
					break;
				case SW_SHOWNA:
					AddItem(L"Window Shown (Not Active)");
					break;
				case SW_SHOWNOACTIVATE:
					AddItem(L"Window Shown (Not Active)");
					break;
				case SW_SHOWNORMAL:
					AddItem(L"Window Shown");
					break;
				}
				AddHWND(wParam);
			case HCBT_MOVESIZE:
				//CBTRECTPTR = (RECT*) lParam;
				//memcpy(&CBTRECT, CBTRECTPTR, sizeof(RECT));
				//AddRECT(CBTRECT);
				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

[C++] Read External Treeview

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
	Read string from xprocess memory
	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;
	GetWindowThreadProcessId(treeview, &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.mask = TVIF_TEXT;
						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;
							if(ReadProcessMemory(hProcess, (LPCVOID)rAdd, (LPVOID)&bytRtn, 255, 0)) {
								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);
	int address = 0x1005361;

	for(int y = 0;y<maxY;y++) {
		for (int x = 0;x<maxX;x++) {
			BYTE *xmine = (BYTE*) address+x;
			BYTE mine = 0x8F;
			if(MinesCheat)
				mine = 0x8A;
			if(*xmine==mine) {
				if(MinesCheat)
					*xmine = 0x8F;
				else
					*xmine = 0x8A;
			}
		}
		address = address + 0x20;
	}
	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:
Mines Revealed

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;
	VirtualProtect((LPVOID)0x010036FA, 1, PAGE_EXECUTE_READWRITE,&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;
	VirtualProtect((LPVOID)0x01002FE7, 1, PAGE_EXECUTE_READWRITE,&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