Hi all,

Don't currently have time for this as a video (may do tomorrow), but wanted to share it as I now have this knowledge, so what I've been working on lately is a C++ version of JAPI (hopefully), which I'm doing solely for the purpose of learning. I've never really used C++ that extensively, only to do some fundamental calculations and what not, but here is some code which may help some of you along:

Code:
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <string>
#include <Psapi.h>

using namespace std;

int _tmain(int argc, _TCHAR* argv [])
{
	// First off we grab a handle to Tibia via FindWindow()
	HWND hwnd = FindWindow(L"TibiaClient", NULL);
	// Dump the handle to console
	cout << "HWND: " << hwnd << endl;
	// These variables are self explanitory except cbNeeded, which I still don't fully get... Ah well
	DWORD cbNeeded;
	DWORD processID;
	DWORD address = 0x3BE1E0;
	// This is the MODULES handle, for the Tibia.exe module in the Tibia process (long story, basically we get a window, find the process linked to it, find the modules in 
	//the process, then we finally have the handle - which is also the base address!)
	HMODULE hModule;
	// Declare a wstring to hold the location of the Tibia client, bare in mind this won't always be the same, 32 bit will not have (x86)!
	wstring fileName = L"C:\\Program Files (x86)\\Tibia\\Tibia.exe";
	// A buffer to hold the value we read
	int buffer;
	// This gets the process ID of the process linked to the handle we obtained using FindWindow - Getting the ID from the window handle
	GetWindowThreadProcessId(hwnd, &processID);
	// Dump it to console
	cout << "Process ID: " << processID << endl;
	// This will get us a handle to the process itself, allowing us to enumerate it's modules!
	HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, processID);
	// Dump it to the console
	cout << "Process Handle: " << handle << endl;
	// Declare an array to store the modules in
	HMODULE hMods[1024];
	// Check the enumeration is legit (if the process doesn't exist or whatever, it will fail at this point!
	if (EnumProcessModules(handle, hMods, sizeof(hMods), &cbNeeded))
	{
		// Inform the user that the enumeration worked fine, useful for debugging
		cout << "Enumerated: " << "Success!" << endl;
		// Cycle through the list of enumerations
		for (int i = 0; i < (cbNeeded / sizeof(hwnd)); i++)
		{
			// Tell the user which cycle we are on, so we can monitor easily
			cout << "Round " << i << ": ";
			// Declare a TCHAR to hold the module name (szModName) of the required length
			TCHAR szModName[MAX_PATH];
			// If we can get the module file name, if the module denies us access it will fail here
			if (GetModuleFileNameEx(handle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
			{
				// Print the module name (stored as wstring, hence wcout instead of cout), and it's address from hMods
				cout << "Module Name: ";
				wcout << szModName;
				cout << ". Entry Number: " << hMods[i];
				// If the modules name is the same as the path we declared earlier then assign hModule to that module, and add the base address to the address to read.
				if (szModName == fileName)
				{
					hModule = hMods[i];
					address += (DWORD)hMods[i];
				}

			}
			// Inform the user we finished the loop
			cout << ". " << endl;
		}
		// Inform the user of the module handle (to confirm it is correct against the above list)
		cout << "Module Handle: " << hModule << endl;
	}
	// Attempt to read memory, this will print 1 if success, 2 if failure
	cout << "Read Success: " << ReadProcessMemory(handle, (void*)address, &buffer, sizeof(buffer), 0) << endl;
	// Print the last error, incase of failure.
	cout << "Last error: " << GetLastError() << endl;
	// Print the data we read
	cout << "Read: " << buffer << endl;
	// Clean up a little
	CloseHandle(handle);
	// Inform the user that we've finished and wait for input.
	cout << "End" << endl;
	cin.get();
	return 0;
}
Any comments or suggestions on how to make this easier are appreciated, I will make a tutorial about this tomorrow, explaining more as to why I took this route.

Thanks