2

I'm new to c programming. There is a use case: I need to change value in a specific memory address.

int main(){

    int *p;
    p = 0x111;
    *p = 100;
    return 0; 
}

However, I cannot compile the above code. It shows the following problem.

test.c:10:7: warning: incompatible integer to pointer conversion assigning to 'int *' from 'int' [-Wint-conversion]
    p = 0x111;
      ^ ~~~~~
1 warning generated.

I tried casting like following:

int main(){

    int *p;
    p = (int *) 0x111;
    *p = 100;
    return 0; 
}

It can compile, however, when I run it, it shows segmentation fault.

My Question:

  1. Is there a way that I can forcedly compile and run this code? I know there is wild pointer problem. However, it's a common use case to manipulate memory. For example, when I play a local game. Somehow, I know the specific memory address of my player's health point when the game is running, e.g. address = 0x123. How to just change the value in 0x123?

  2. If I cannot use above way to manipulate value in any specific memory address, is there other standard way to realize my use case?

PS: By the way, I found the example way to realize my use case.

You can refer to the source code: https://github.com/haseeb-heaven/GTLibc/

How do game trainers change an address in memory that's dynamic?

https://www.youtube.com/watch?v=cRCnN987gd8&ab_channel=HaseebMir

maplemaple
  • 1,297
  • 6
  • 24
  • 1
    You'd need to cast it to a pointer. However, note that if that address is "outside" the scope of your application. Then you'll receive a segfault for trying to access and address you're not allowed to access. – vallentin Nov 19 '20 at 07:49
  • 2
    You can't do this in an operating system with protected memory addressing, which is basically all of them now. In addition to this, the address space for one process is *completely different* from another, they're not even on the same planet. Pointers from one process are completely meaningless when used directly in another. Unless this is code for something like DOS it won't work. – tadman Nov 19 '20 at 07:53
  • What is your platform? – Jabberwocky Nov 19 '20 at 07:53
  • @Jabberwocky I'm using mac osx. Apple clang version 11.0.0 (clang-1100.0.33.17) – maplemaple Nov 19 '20 at 07:54
  • 3
    @maplemaple then you can't do that. What are you _actually_ trying to achieve? – Jabberwocky Nov 19 '20 at 07:56
  • 3
    Does this answer your question? [Reading Other Process' Memory in OS X?](https://stackoverflow.com/questions/10668/reading-other-process-memory-in-os-x) – tadman Nov 19 '20 at 07:56
  • @Jabberwocky This is my use case: when I play a local game. Somehow, I know the specific memory address of my player's health point when the game is running, e.g. address = 0x123. How to just change the value in 0x123? – maplemaple Nov 19 '20 at 08:02

2 Answers2

2

Given a valid pointer to an object in a memory address, indirect through the pointer and assign a value:

int health_points = 1337;  // an object in some memory address
int* ptr = &a;             // pointer to the value in that memory address
*ptr = 0;                  // the value is modified

Is there a way that I can forcedly compile and run this code?

Your program is ill-formed. There may be a way to let a compiler successfully compile it if the compiler provides a relevant language extension, but it is typically a bad idea to rely on such extensions because it would trap you into using that one compiler.

Instead of trying to force a compiler accept a broken program, I recommend fixing the program.

how to change value in a specific memory address?

Firstly, the memory in that address must be allocated. The language implementation takes care of allocating all memory and there is no standard way to specify what address is allocated.

However, some language implementations may specify certain addresses as accessible. This is typical on embedded systems. If this is the case, then you can convert an integer value to a pointer using a cast:

std::uintptr_t address = 0x111; // see documentation whether this is a valid address
int* ptr = reinterpret_cast<int*>(address);

If your language implementation doesn't specify that the address is accessible, then there are no guarantees about accessing it. On modern operating systems which manage virtual memory, the best case scenario is a segfault.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Note OP asked about C in the text and the C++ tag has been removed, so the C++ in this answer is now in applicable, both in the C++ sample code and in the assertions about ill-formedness, which does not apply in C. – Eric Postpischil Nov 19 '20 at 12:19
0

Let me make you understand how applications reads address of another application or self.

  1. Self address.

The address you are reading has be above base address which is 0x0040000 for executable image so it should look like this 0x0040000 + 0x0040 where 0x0040 is the offset from base address. And if you accessing region other than .text(Read only) the you have to change the permission of the region first using VirtualProtect method as shown here

  1. External application address.

If you want to read address from external application lets say your game then first you have to get the Application Handle which is just and identifier for your application and then use ReadProcessMemory as shown here similarly you can write also using WriteProcessMemory as shown here

Just always make sure you don't access other than .text section without changing its permission region otherwise your program could crash.

Haseeb Mir
  • 928
  • 1
  • 13
  • 22