I'm learning to modifying game values using C++ but now I'm stuck.
I know how to edit for example FLOAT value of Player speed:
uintptr_t _EntitiesBase = (uintptr_t)GetModuleHandle(L"EntitiesMP.dll");
uintptr_t EntityBase = _EntitiesBase + 0x3153D0;
DWORD Run = 0xDE4;
*(FLOAT*)(*(DWORD*)EntityBase + Run) = Value;
But I don't know, how to edit values, that have much offsets (Engine.dll + 0xD52AB0 + 0x48 + 0x228), because in the end it return wrong value, not that I wanted to change
For example, in Cheat Engine, the same thing looks like this:
I added Engine.dll + 0xD52AB0 as a pointer, and next add offset 0x48 and offset 0x220 and it gives me address 2DC7E488, that contains FLOAT value, that I need to change
Do you have any ideas?
You can use ReadProcessMemory to read process memory and WriteProcessMemory to write process memory. to do this you just need to use ReadProcessMemory for every offset then write the pointer value with WriteProcessMemory:-
uintptr_t entitybase;
uintptr_t value1;
float newValue = 100000;
ReadProcessMemory(ProcessHandle, (uintptr_t)EngineDllHandle + 0xD52AB0, &entitybase, sizeof(entitybase), 0);
ReadProcessMemory(ProcessHandle, entitybase + 0x48, &value1, sizeof(value1), 0);
WriteProcessMemory(ProcessHandle, value1 + 0x220, &newValue, sizeof(entitybase), 0);
Related
I am working with the SystemC TLM library. I would like to send a payload with two integers to a module that will perform an operation on those two integers. My question is simply how to setup and decode the payload.
Doulos provided documentation on both setting up and decoding here https://www.doulos.com/knowhow/systemc/tlm2/tutorial__1/
Setup
tlm::tlm_command cmd = static_cast(rand() % 2);
if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i;
trans->set_command( cmd );
trans->set_address( i );
trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data) );
trans->set_data_length( 4 );
trans->set_streaming_width( 4 );
trans->set_byte_enable_ptr( 0 );
trans->set_dmi_allowed( false );
trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
socket->b_transport( *trans, delay );
Decode
virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay )
{
tlm::tlm_command cmd = trans.get_command();
sc_dt::uint64 adr = trans.get_address() / 4;
unsigned char* ptr = trans.get_data_ptr();
unsigned int len = trans.get_data_length();
unsigned char* byt = trans.get_byte_enable_ptr();
unsigned int wid = trans.get_streaming_width();
So it looks to me like you would send a pointer to a memory location where there are two integers written.
|----------------------------------int1-------------------------|------------------------------------int2------------------------
|ptr+0x0|ptr+0x(wid)|ptr+0x(2*wid)|ptr+0x(3*wid) | ptr+0x(4*wid)|ptr+0x(5*wid)|ptr+0x(6*wid)|ptr+0x
----------|
(7*wid)|
Is my interpretation of this documentation correct?
How could you get those first 4 memory locations [3:0] and combine them into an int32 and how could you get the second 4 [7:4] and turn them into the second integer?
So it looks to me like you would send a pointer to a memory location
where there are two integers written.
Is my interpretation of this documentation correct?
Yes
To get them back you just need to copy them:
int32_t val0, val1;
memcpy(&val0, ptr, sizeof(int32_t));
memcpy(&val1, ptr + sizeof(int32_t), sizeof(int32_t));
or something like
int32_t val[2];
memcpy(val, ptr, sizeof val);
But make sure initiator keeps memory under the pointer valid long enough e.g. it might be better to avoid using keep data on the stack. And don't forget to check if payloads data length attribute has valid value - you want to detect those issues as soon as possible.
I have struggled with a very annoying problem lately with writing to Process memory in c++... I can not write to process memory with multiple offsets! Even though there are thousands of pages explaining how you fix this problem, it still seems to not work for me. I have been searching around on google all day long, and found many examples of how to fix this problem, but it still seems to not work for me.
So, let me first explain how I am writing to process memory myself, and you could possibly correct it afterwards.
Let us say I have a base address of: 0x04AF3C94
First offsets as: 0x1C
Second offsets as: 0x20
Third as: 0x568
And fourth as: 0x134
How I am doing this myself:
DWORD offset1 = 0x1C;
DWORD offset2 = 0x20;
DWORD offset3 = 0x568;
DWORD offset4 = 0x134;
DWORD base = 0x04AF3C94;
DWORD pointer;
DWORD pointer2;
DWORD pointer3;
DWORD pointer4;
DWORD pointer5;
ReadProcessMemory(handle, LPVOID(base), &pointer, sizeof(pointer), 0);
ReadProcessMemory(handle, LPVOID(pointer + offset1), &pointer2, sizeof(pointer2), 0);
ReadProcessMemory(handle, LPVOID(pointer2 + offset2), &pointer3, sizeof(pointer3), 0);
ReadProcessMemory(handle, LPVOID(pointer3 + offset3), &pointer4, sizeof(pointer4), 0);
ReadProcessMemory(handle, LPVOID(pointer4 + offset4), &pointer5, sizeof(pointer4), 0);
int value = 500;
WriteProcessMemory(handle, LPVOID(pointer5), &value, sizeof(value), 0);
As you can see, if I have 4 offsets such as in this example, I am adding every offset one at a time to the base address, until I got one value that stores every offset added to the baseaddress.
This apparently don't work, what should I do!?
I can't reply to all with your description, but in the MSDN they say that ReadProcessMemory read memory from where it is asked to the given buffer. It means when you call...
ReadProcessMemory(handle, LPVOID(base), &pointer, sizeof(pointer), 0);
...your "pointer" will be filled with what is at the "base" address. So it will contain an address that is numericaly the value of the four bytes at address "base". This is probably not what you want, because if you didn't stored something there before, it's indeterminate. And if so, it will probably crash when you use "pointer".
If you want to read the memory at adresse "base + offset1" with that function, what you have to do is:
ReadProcessMemory(handle, LPVOID(base + offset1), some_buffer, some_buffer_size, 0);
Where some_buffer is a valid buffer you have to declare somewhere.
Hello sorry for my bad English.
I want to calculate an address with offset.
The example I have got a base address: 0x00D2038 with offset 0x1c
I have tried this.
DWORD address = 0x004D2038;
DWORD offset = 0x1c;
DWORD base = (DWORD)(address + offset);
int old_value = 0;
int value = 3000;
//Obtain new address form the address whit offset.
DWORD addr2 = ReadProcessMemory(phandle,(void*)base,&old_value,sizeof(old_value),0);
//Write Memory
WriteProcessMemory(phandle,(void*)addr2,&value,(DWORD)sizeof(value),NULL);
But it does not work.
Memory is not changed. what is my error?
According to msdn, ReadProcessMemory returns a BOOL and you use that as addr2 to WriteProcessMemory. How can the memory be changed?
Suggest search from msdn on ReadProcessMemory and WriteProcessMemory and their example and learn how to use these 2 functions.
Think you have a simple typo -- Try;
//Write Memory
WriteProcessMemory(phandle,(void*)base,&value,(DWORD)sizeof(value),NULL);
I'm working at some legacy code right now (converting some of it to C#), and I've stumbled upon a problem:
A byte array is created (length is ulcLen):
CSLAutoArray<BYTE> pMem(new BYTE[ulcLen]);
Now some stuff is put into the byte array, after which a CRC / Hash value is supposed to be written to the first four bytes (ULONG / UInt32):
__CfgCRC(pMem + sizeof(ULONG), ulcLen - sizeof(ULONG))
->
inline ULONG __CfgCRC(const void* const cpcMem, const ULONG ulcMemSize)
{
ULONG ulRes = 0;
const BYTE* const cpcUseMem = reinterpret_cast<const BYTE*>(cpcMem);
for(const BYTE* pcLook = cpcUseMem; cpcUseMem + ulcMemSize > pcLook; pcLook++)
{
ulRes ^= static_cast<ULONG>(*pcLook);
//[...]
};
return ulRes;
};
Now, is it just me, or is the static_cast reading 1/2/3 bytes over the end of the byte array, at the end of the for loop? Since pcLook (the memory pointer) is increased until it reaches the full length of the data, (ulclen + sizeof(ULONG)) ? Or am I wrong? Or does static_cast somehow not read over the end of an array ? (CSLAutoArray is some kind of managed pointer class, but as far as I see it does not interfere with this code)
*pcLook is just a BYTE so no, it's only reading 1 octet at a time. the cast just casts the BYTE and not what pcLock is pointing to.
I'm trying to change the value of an address in solitaire which provides the time.
Given the code below, the baseaddress + offset 0x97074 should point to another address with offset 0x50 and finally this address should point to the final address with offset x0C to change the timevalue.
However, solitaire crashes when I'm executing this operation.
HMODULE hModule = GetModuleHandle(nullptr);
sstream << std::hex << reinterpret_cast<unsigned int>(hModule);
str = sstream.str();
BaseAddress = reinterpret_cast<DWORD>(str.c_str());
//MessageBox(NULL, (LPCSTR) BaseAddress, "Adress", MB_OK); just some reminder
*(*(*(*(DWORD *) BaseAddress + (DWORD *) BASE_OFS_DEF ) + (DWORD *)TIME_OFS1_DEF ) + (DWORD *)TIME_OFS2_DEF) = 500;
The logic is wrong, you are dereferencing your pointers before you add the offset and casting your offsets to pointers! I think this is what you want
*(DWORD*)(*(DWORD*)(*(DWORD*)(BaseAddress + BASE_OFS_DEF) + TIME_OFS1_DEF) + TIME_OFS2_DEF) = 500;
But you should really break that down a bit to help understand what's going on, e.g.
DWORD temp1 = *(DWORD*)(BaseAddress + BASE_OFS_DEF);
DWORD temp2 = *(DWORD*)(temp1 + TIME_OFS1_DEF);
*(DWORD*)(temp2 + TIME_OFS2_DEF) = 500;