0

In code C we can have the following snippet to create a reference to a relative address in memory.

int *value = (int*)0x0061FF0C;

Since I haven't found a C-like way, I used inline assembly to get the value, but it's just the value, not the reference.

unsafe fn read_from_adress(adress:u32) -> i32 {
   let mut data = 0;
   asm!{
       "mov {}, [{}]", 
       out(reg) data,
       in(reg) adress, 
   };
   return data;
}


let var: i32 = read_from_adress(0x0061FF0C);

In rust I can't find an equivalent and simple way as in C.

I tried this snippet and to no avail.

let value = &mut 0x0061FF0C;

Is there a way equivalent to C ?

obs: Getting relative address values is being done with dll injection. In both C and Rust

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
rick
  • 554
  • 6
  • 18
  • This is not what "relative" means. – ecm Oct 02 '22 at 17:37
  • What I mean by "relative" is about a program's memory locations. So it would be something like: module_base_address + address = relative_address, as this is not the absolute address in memory. Maybe I'm not expressing myself correctly. But is this the idea of a relative address? – rick Oct 02 '22 at 17:56
  • Dereferencing `0x0061FF0C` as an `(int*)` is in no way relative to the module base address. It is an absolute address. On modern x86 the 32- or 64-bit address is generally an offset, used in the (obsolete) segmentation scheme to yield a linear virtual address, which is then paged to gain a physical address. (Most selectors will be set up to point to flat 4 GiB or 16 EiB segments starting at address zero on modern systems so the offset equals the linear address.) – ecm Oct 02 '22 at 18:07
  • Thank you for the explanation. But then for understanding purposes. I get the base address of a program's module and do "module_base_address" + "offset(0x0061FF0C)" = address_in_memory_program. Would that still be an absolute address? Because what I do when using "0x0061FF0C" is do module_base(0) + "0x0061FF0C" The base address is 0 because it was dll injection. – rick Oct 02 '22 at 18:24
  • If you use `0x0061FF0C` as a displacement from a module base address then the number is relative, the result is absolute. However, generally no module can have a base address of zero so if you're adding zero then the number is used effectively as an absolute address. – ecm Oct 02 '22 at 18:36
  • 1
    Are you asking how to get Rust to use a RIP-relative address in 64-bit code to reach a known constant absolute address from wherever the linker puts your code? Like in [How to write an absolute target for a near direct relative call/jmp in MASM](https://stackoverflow.com/q/50058523) which shows how to do it in YASM syntax for a jump. In GAS syntax (like Rust inline asm), you might use `mov eax, [rip + 0x0061FF0C - next_instruction]`, where `next_instruction:` is a label right after the `mov` load. Should be possible to write that with `{}` placeholders for Rust to fill in. – Peter Cordes Oct 02 '22 at 21:56
  • Thanks for the reply, and it seems to me to be the light of what I want to understand. Because about the address 0x0061FF0C being absolute is making me confused. For example, if I run 2 programs simultaneously and access their address spaces, I could use the same "relative address" (0x0061FF0C) in both to get the value of a variable. Maybe what I'm saying is about -Virtual Address Space: https://learn.microsoft.com/pt-br/windows/win32/memory/virtual-address-space – rick Oct 03 '22 at 18:53

1 Answers1

1

The equivalent Rust code of your C code is:

let value = unsafe { *(0x0061FF0C as *const i32) };

However, as noted in the comments, the address is not relative but absolute.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • 1
    I made this modification so that I could create a reference to the address and change the value later. I hope it's correct, but it works. "let mut value = unsafe { (0x0061FF0C as *mut i32) }; " *value = 2; – rick Oct 02 '22 at 18:35
  • @RicardoSpinola Yes, it is correct. – Chayim Friedman Oct 02 '22 at 18:35