Reading and writing with a DLL injection C++ - c++

I've run into a bit of a problem and I'm not sure how to do what I am trying to do.
I am using C++ to inject a DLL into an application and I want to alter an address. The problem is that I'm not quite sure how to target it - let me explain...
I know how to use pointers:
int x;
int *myPointer;
myPointer = &x;
*myPointer = 5;
std::cout << x << endl; // 5
And I know that you can point to pointers:
int x;
int *myPointer;
int **myPointer2;
myPointer = &x;
myPointer2 = &myPointer;
**myPointer = 5;
std::cout << x << endl; // 5
I am trying to make a basic game hack by injecting a DLL into a game, and then setting the ammo to a fixed value on a keypress. The injection is working, the keypress is working, but I get a crash whenever I try and access the memory.
I have used Cheat Engine to get the static address for the variable I want to change, along with 3 offsets.
The address info in Cheat Engine looks like this:
Address: 0288A520 = 19
Type: 4 bytes
0 [0288A520 + 0] -> 0288A520
14 [0288A520 + 14] -> 0288A520
384 [0288A3D0 + 384] -> 02881A30
ac_client.exe+109B74 -> 0288A3D0
The value 19 is the one I want to modify in my DLL.
If I close the game and re-open it, I get the correct values coming through using these pointers, but now my issue is I'm not sure how to implement this in C++. How do I represent this static address in C++?
My main thread currently looks like this...
DWORD WINAPI Main_Thread(LPVOID lpParam)
{
while(1)
{
if(GetAsyncKeyState(VK_HOME)) {
// Output value here???
}
Sleep(100);
}
}
Any help is greatly appreciated.

I've got it working. The things I had been trying before were happening because I had an incorrect base address.
My solution can be seen below.
Defining addresses
#define BASE_ADDR 0x00400000
#define AMMO_ADDR 0x00109B74
#define AMMO_OFS1 0x00000384
#define AMMO_OFS2 0x00000014
Get address function
DWORD getAddress(DWORD baseAddress, DWORD offsets[], int offsetCount)
{
DWORD address; // Where the final address will be stored
address = *(DWORD*)(BASE_ADDR + baseAddress); // Add the base address to the modules base address.
// Loop through each offset
for(int i = 0; i < offsetCount; i++) {
address = *(DWORD*)(address + offsets[i]);
}
return address;
}
Changing the value
DWORD ammoOffsets[] = {AMMO_OFS1, AMMO_OFS2};
DWORD ammoAddress = getAddress(AMMO_ADDR, ammoOffsets, 2);
int* ammoPointer = (int*) ammoAddress;
*ammoPointer = 20;

Related

Is there a way to resize a module, inside a process, or extend one to be longer in memory?

I am curious to know if it is possible to extend a process module, like a dll, to be larger.
As an example, I inject test.dll into test.exe, I make test.dll + 0x1000 bytes larger, these new bytes now have PAGE_EXECUTE privileges and I can modify them however I like.
I want to be able to do this only after injecting the dll, not by adding fake code to the dll to overwrite, as I will likely have no control over the execution of the actual test subject.
I have already tried to use VirtualAlloc on the end of the dll's sections to increase its size, but it hasn't worked, I usually get ERROR_BAD_ADDRESS, I made sure to verify the process had enough space after the dll to allocate to and commit to.
uint64_t module_contents = (uint64_t)GetModuleHandleA(NULL);
IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)module_contents;
IMAGE_NT_HEADERS64* nt_header = (IMAGE_NT_HEADERS*)(module_contents + dos_header->e_lfanew);
IMAGE_SECTION_HEADER* section = (IMAGE_SECTION_HEADER*)(nt_header + 1);
for (unsigned short i = 0; i < nt_header->FileHeader.NumberOfSections; i++) {
if (!section->SizeOfRawData && section->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
char name[8];
memcpy(name, section->Name, sizeof(name));
if (std::string(name).find("text") == std::string::npos) {
//std::cout << name << std::endl;
break;
}
}
section++;
}
std::cout << VirtualAlloc((void*)(module_contents + section->VirtualAddress + section->Misc.PhysicalAddress), 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE) << std::endl;
The expected result of this is to fill in and commit to the empty space after the module's sections, which I verify has not been committed to both by the cout & with Cheat Engine to look at the memory region. The result I get is an error message of 0x1E7, or ERROR_INVALID_ADDRESS. I have gotten other error messages like ERROR_INVALID_PARAMETER, when using a smaller size like 0x1.
Any help with this is appreciated!

Pointer From Cheat Engine To C++

I am looking for a way to pass a pointer address from cheat engine to a line of code.
The Cheat Engine address is P-> 0C86D240.
The Line of Code is as follows:
WriteProcessMemory(handle,(LPVOID)P->0C86D240,).
In the end i would like to change the pointer address' value.
Update: i changed P-> to 0x0C86D240 and i was able to write memory for THAT session of the game. When closed then opened again the hex number was different
P->0C86D240 in Cheat Engine means that the entry is a chain of pointers which finally resolves to the address 0x0C86D240. If you double click this part in Cheat Engine, you will see a popup dialog showing you what this pointer chain consists of. For example, let's call the starting pointer P0 and a series of offsets called offset0, offset1, offset2, .... A pointer chain is to take the value at the address P0 + offset0, use that as your next pointer P1, then take the value at the address P1 + offset1, use that as your next pointer P2 ... this chain will finally give you the address 0C86D240. If you reset your game, you hope your P0 will not change but everything afterwards will change dynamically (i.e. P1, P2, P3,...) and track all the way down to the desired value.
If you know how the pointer chain works, it is then trivial to convert this to C++. You just need to take note of the base pointer and all offsets (as shown in the popup dialog by double-clicking the P->0C86D240 part.) Then, track down until you use up all offset values.
You write a function which walks the multilevel pointer, each step it de-references the pointer and adds the relative offset.
For this example I will use a simple assault cube cheat I've made
FindDMAAddy function (Find Dynamic Memory Allocation Address):
uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, std::vector<unsigned int> offsets)
{
uintptr_t addr = ptr;
for (unsigned int i = 0; i < offsets.size(); ++i)
{
ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
addr += offsets[i];
}
return addr;
}
The main code:
uintptr_t moduleBase = GetModuleBaseAddress(procId, L"ac_client.exe");
//Get Handle to Process
HANDLE hProcess = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, procId);
//Resolve base address of the pointer chain
uintptr_t dynamicPtrBaseAddr = moduleBase + 0x10f4f4;
std::cout << "DynamicPtrBaseAddr = " << "0x" << std::hex << dynamicPtrBaseAddr << std::endl;
//Resolve our ammo pointer chain
std::vector<unsigned int> ammoOffsets = { 0x374, 0x14, 0x0 };
uintptr_t ammoAddr = FindDMAAddy(hProcess, dynamicPtrBaseAddr, ammoOffsets);
std::cout << "ammoAddr = " << "0x" << std::hex << ammoAddr << std::endl;
You can find a more complete version of my answer here but you seemed to already know the rest.
Step 1: Search the value you want to change with cheat engine.
Step 2: If you have found the right address do right click on it and make a pointer scan for this address. Now you should get many base-addresses with some offsets.
Step 3: Close your game and repeat Step 1. Now copy the new address and click on rescan pointerscan (in the window that opened from step 2).Paste the new address in the rescan address field and rescan. Then you should only get the right base-addresses + offsets.
Step 4: To always find the right address do: readprocessmemory(baseaddress+offset)
fist of all I can't figure out what the P-> means maybe remove that and make the value a 0x for hex
When closed then opened again the hex number was different
I guess that you are talking about the game if I'm wrong then don't continue reading
so the address you get from cheat engine is probably a dynamic one meaning that every time you close or open it that value will change sense the program will be allocated another place in the memory
so what should you do.....
you could find the static address this process is a bit complicated I will advise you to watch a tutorial https://www.youtube.com/watch?v=hfWOAFsYnFA
Cheat engine tutorial built into the program covers multilevel Pointers. Do your work first. If you have the pointer already found, you have the address you are looking for: A static address that points to the address containing the value you want to modify.

Problems with pointers and memory adresses

I wonder why this code doesn't work:
#include <iostream>
using namespace std;
int main()
{
int *pointer = (int*)0x02F70BCC;
cout<<*pointer;
return 0;
}
In my opinion it should write on the screen value of 0x02F70BCC,
instead of this my programm crashes.
I know that memory with adress 0x02F70BCC stores value of 20.
But like I said no matter what it just doesn't want to show correct number.
Please help me guys, detailed explanation would be very nice of you.
It doesn't work, because you won't get access to every location in memory you want. Not every location in memory is valid, you may want to read about Virtual Address Space.
Some addresses are reserved for device drivers and kernel mode operations. Another range of addresses (for example 0xCCCCCCCC and higher) may be reserved for uninitialized pointers.
Even if some location is valid, operating system may still deny access to write to/read from certain location, if that would cause undefined behaviour or violate system safety.
EDIT
I think you might be interested in creating some kind of "GameHack", that allows you to modify amount of resources, number of units, experience level, attributes or anything.
Memory access is not a simple topic. Different OSes use different strategies to prevent security violations. But many thing can be done here, after all there is a lot software for doing such things.
First of all, do you really need to write your own tool? If you just want some cheating, use ArtMoney - it is a great memory editor, that I have been using for years.
But if you really have to write it manually, you need to do some research first.
On Windows, for example, I would start from these:
ReadProcessMemory
WriteProcessMemory
Also, I am quite certain, that one of possible techniques is to pretend, that you are a debugger:
DebugActiveProcess.
EDIT 2
I have done some research and it looks, that on Windows (I assume this is your platform, since you mentioned gaming; can't imagine playing anything on crappy Linux), steps required to write another process' memory are:
1. Enumerate processes: (EnumProcesses)
const size_t MAX_PROC_NUM = 512;
DWORD procIDs[MAX_PROC_NUM] = { 0 };
DWORD idsNum = 0;
if(!EnumProcesses(procIDs, sizeof(DWORD) * MAX_PROC_NUM, &idsNum))
//handle error here
idsNum /= sizeof(DWORD); //After EnumProcesses(), idsNum contains number of BYTES!
2. Open required process. (OpenProcess,GetModuleFileNameEx)
const char* game_exe_path = "E:\\Games\\Spellforce\\Spellforce.exe"; //Example
HANDLE game_proc_handle = nullptr;
DWORD proc_access = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE; //read & write memory, query info needed to get .exe name
const DWORD MAX_EXE_PATH_LEN = 1024;
for(DWORD n = 0 ; n < idsNum ; ++idsNum)
{
DWORD current_id = procIDs[n];
HANDLE current_handle = OpenProcess(proc_access, false, current_id);
if(!current_handle)
{
//handle error here
continue;
}
char current_path[MAX_EXE_PATH_LEN];
DWORD length = GetModuleFileNameEx(current_handle, nullptr, current_path, MAX_EXE_PATH_LEN);
if(length > 0)
{
if(strcmp(current_path, game_exe_path) == 0) //that's our game!
{
game_proc_handle = current_handle;
break;
}
}
CloseHandle(current_handle); //don't forget this!
}
if(!game_proc_handle)
//sorry, game not found
3. Write memory (WriteProcessMemory)
void* pointer = reinterpret_cast<void*>(0x02F70BCC);
int new_value = 5000; //value to be written
BOOL success = WriteProcessMemory(game_proc_handle, pointer, &new_value, sizeof(int), nullptr);
if(success)
//data successfully written!
else
//well, that's... em...
This code is written just 'as is', but I see no errors, so you can use it as your starting point. I also provided links for all functions I used, so with some additional research (if necessary), you can achieve what you are trying to.
Cheers.
When you use,
cout<<*pointer;
the program tries to dereference the value of the pointer and writes the value at the address.
If you want to print just the pointer, use:
cout << pointer;
Example:
int main()
{
int i = 20;
int* p = &i;
std::cout << *p << std::endl; // print the value stored at the address
// pointed to by p. In this case, it will
// print the value of i, which is 20
std::cout << p << std::endl; // print the address that p points to
// It will print the address of i.
}

How do I use a game's base pointer to edit a value in C++?

Okay I've followed a couple of tutorials on how to find the base/static pointer of a game's value with cheat engine (hp, strength, experience, gold, etc). To test this I tried it on Microsoft's Spider Solitaire and it worked. I got the base pointer for the amount of moves ("zetten" as you will see in my dutch version of Spider Solitaire), and made it reference to another pointer which referenced to the actual value (assuming that's how it's called).
That's basically what it looks like. So now I've got the base pointer which would be SpiderSolitaire.exe+B5F78 and it uses 2 offsets to get to the actual address of the value. This is the code that I use to edit memory values with in C++:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <strsafe.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
long address = 0x??????;
int newvalue = 200000;
DWORD newvaluesize = sizeof(newvalue);
HWND hWnd = FindWindow(0, L"Spider Solitaire");
HANDLE pHandle;
DWORD pid;
if(hWnd != 0) {
cout << "Found windowx.\n";
GetWindowThreadProcessId(hWnd, &pid);
pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
}
else {
cout << "Can't find window\n";
}
if(pHandle !=0) {
WriteProcessMemory(pHandle, (LPVOID)address, &newvalue, newvaluesize, 0);
cout << "Written to memory successfully\n";
getchar();
}
else {
cout << "Couldn't get handle.\n";
getchar();
}
CloseHandle(pHandle);
return 0;
}
So I have all the information I need, except I don't know how to implement base pointers and offsets and whatnot into the C++ program. I tried using
long address = SpiderSolitaire.exe+B5F78+e8+10
but that didn't work (SpiderSoliteire.exe is a string anyway so I didn't expect it to work). I've tried searching for tutorials or something on the internet, but those only show how to directly alter a value in 1 memory address, not how to alter a value by referencing it through 2 pointers. How do I do this? How do I implement this base pointer, and the 2 offsets into my C++ program so that I can edit the memory value?
I tried same thing and they said to that i need to write my own OS for that. Some said i need to be in ring-0 area. I say you can use asm (assembler)
mov [address],register
comand
Gcc, VC++ 10 , Digital Mars has some asm{} block definitions inside.
You have to figure out where the process is loaded, which can vary. See this earlier question for details. It does more than you need; you just need the base address part.

Accessing and modifying thread data problem in c++

I have problems to access and modify my multiple thread data. Is there are any proper way to do this?
Here is my full code:
#include <stdio.h>
#include <windows.h>
// Create thread data structure
struct data
{
int a;
float b;
char *c;
};
DWORD WINAPI threadfn(LPVOID lpParam)
{
printf("Address of thread data:\n");
for(int i=0; i<sizeof(lpParam); i++)
printf("%X\n", (int*)lpParam + i);
// Print out initial values
printf("\nInitial values:\n");
printf("a: %d\n", *((int*)lpParam));
printf("b: %.2f\n", *((float*)lpParam + 1));
printf("c: %s\n", *((int*)lpParam + 2));
// Modify thread data values
*(int*)lpParam = 200;
*((float*)lpParam + 1) = 25.80;
*((char*)lpParam + 2) = "Es la una";
return 0;
}
int main()
{
HANDLE hThread;
data thread;
// Set initial thread data values
thread.a = 10; // Integer data type
thread.b = 15.60; // Float data type
thread.c = "Que hora es?"; // String data type
hThread = CreateThread(NULL, 0, threadfn, &thread, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
// Print out thread value after modification
printf("\nAfter thread modifications:\n");
printf("a: %d\n", thread.a);
printf("b: %.2f\n", thread.b);
printf("c: %s\n", thread.c);
getchar();
return 0;
}
And this is my output:
Address of thread data:
28FF20
28FF24
28FF28
28FF2C
Initial values:
a: 10
b: 15.60
c: Que hora es?
After thread modifications:
a: 7405768
b: 25.80
c: Que hora es?
As you can see, the 'c' value is same. How do i modify string value?
What on earth are you doing?! All the casting of lpData is very, very wrong. If you have to do that much casting to accomplish something, you are probably not doing it the right way.
Anyway, your code should look like this:
DWORD WINAPI threadfn(LPVOID lpParam)
{
printf("Address of thread data:\n");
data *lpData = (data *)(lpParam);
for(int i=0; i<sizeof(lpParam); i++)
printf("%X\n", (int*)lpParam + i);
// Print out initial values
printf("\nInitial values:\n");
printf("a: %d\n", lpData->a);
printf("b: %.2f\n", lpData->b);
printf("c: %s\n", lpData->c);
// Modify thread data values
lpData->a = 200;
lpData->b = 25.80;
lpData->c = "Es la una";
return 0;
}
You should be using (data *)(lpParam) because it basically reverses what's happening when you call CreateThread. Personally, think the stupid P notation for type names is more of a hinderance than a help because it obscures what's actually happening. Hungarian notation in general has this problem IMHO.
In your main function, you have this code:
hThread = CreateThread(NULL, 0, threadfn, &thread, 0, NULL);
The 4th argument to CreateThread is a void * (aka a PVOID). The type of the expression &thread is data *. This means that the data * is being implicitly converted to a void *. If you make that conversion explicit, the code looks like this:
hThread = CreateThread(NULL, 0, threadfn, (void *)(&thread), 0, NULL);
So, in order to 'undo' what was done, you need to 'reverse' the cast. You need to turn the void * back into a data *, which means than in threadfn you need the code data *lpData = (data *)(lpParam);.
Additionally, you are courting disaster by setting c to point at constant character strings since you didn't declare it as a const char *. I'm surprised the compiler isn't giving you an error. The disaster happens when you do something like data.c[0] = 'f';. When you do that you will be trying to modify memory that may very well be flagged as read-only and cause your program to crash. And that's the kindest thing that could happen.
You're not accessing your structure members properly from within the spawned thread. Consider this:
*(int*)lpParam = 200;
It means convert the lpParam to an int*, then access the integer at that address. That works fine, but:
*((float*)lpParam + 1) = 25.80;
Converts lpParam to a float*, then adds sizeof(float*) bytes to it, then dereferences it. That only works if sizeof(int) happens to be the same as sizeof(float)... which is common enough but not guaranteed.
*((char*)lpParam + 2) = "Es la una";
This is a real worry though: this considers lpParam a char*, then adds two BYTES to it, which probably positions it half way into the four bytes used by the integer member of the struct (assuming a 32 bit app), then writes over the single character at that address with a truncated value (the least significant byte/char) from the char pointer to your new string [incorporating correction thanks to Chris's comment].
Instead:
data* p = (data*)lpParam;
p->a = ...;
p->b = ...;
p->c = ...;
The basic point here is that the thread function takes a void* argument, so you lose the type information. The first thing you want to do with it when your thread starts running is restore that type information so the compiler can check what you're doing is safe and sensible.
Your pointer arithmetic is off.
c is at offset 8 in the struct.
However:
*((char*)lpParam + 2) = "Es la una";
You cast lpParam to a char*. Char's have a size of 1 byte (on Windows at least.) You add two to the pointer, so you are writing to offset 2 bytes in the struct.
Your other pointer arithmetic happens to work since you cast lpParam to a float*, meaning (float*)lpParam + 1 writes to offset 4 in the struct.
As Omnifarius suggested, just cast lpParam to a pointer to the thread data structure and access the members through that.