What affects the size of the value of a memory address?

What affects the size of the value of a memory address?

I look at the memory address of the rust process and it has a very large value(e.g. 3092365760128). But this is not a problem, the rust process reads and writes these memory addresses normally.
But when the rust calls some scripting tool DLLs, the scripts crash frequently with the message "Critical Error: Invalid memory read/write.", which seems to be because the rust process' memory address is too large. If the DLL is used in other software, it usually has a small memory address (e.g. 10561576)
10561576 is really a huge difference compared to 3092365760128.

What causes this difference? Is there a way to make it smaller?

The loader and the OS.
The address you see is a virtual address and has nothing to do with the actual physical address. The loader decides how to map various parts of the process into memory, while the OS decides which virtual addresses are assigned to your process. (on WIndows, the details may differ but the idea is essentially this).

It's usually not so simple. For starters, if the DLL and your Rust process are independent processes, then they have separate virtual address spaces, unless you specifically set up shared pages. So, a blind read from the DLL will cause a crash since one process is not usually allowed to read the address space of another process.

Have you read the code of the other software? Maybe they are written to invoke the DLL with shared pages?

That's about all I can say without further context.

1 Like

Thanks.
You can understand it as python.dll, which runs its own PY code, but it belongs to the rust process.

I didn't read the address of the DLL through rust, I printed the memory address of itself using python code.

Same code:
Load python.dll with python.exe, the memory address of one of its variables is usually "10561576 "
Loading python.dll with rust.exe, which usually has a variable with a memory address of "3092365760128"

I think this is clearly not normal.

Can you share the code with which you are loading python.dll? Both in Python and in Rust?

I should emphasize that rust just loads a python.dll thread and does not interact with it in any way, let alone read or write memory addresses.
The "memory read/write error" is an internal error in the python thread.

Okay. python.dll is just a better example. I'm using AutoHotkey.dll
https://github.com/HotKeyIt/ahkdll-v2-release/raw/master/x64w/AutoHotkey.dll

Because all its internal memory addresses are huge, any function that reads "PTR" can be used for the example. For example "MsgBox strptr('')"

Yes, it is during loading when the addresses of many variables in your DLL is decided.
So, how are you loading the DLL in Rust? What code are you using?




fn main() {
	unsafe {
		let code = r#"
MsgBox  strptr('')
		"#.to_string();

		let mut path = r"D:\AutoHotkey.dll".to_string();

		let lib = LoadLibraryW(encode(path.as_str()).as_ptr());
		let NewThread = std::mem::transmute::<_, extern "C" fn(*const u16, *const u16, *const u16) -> u32>(GetProcAddress(lib, "NewThread\0".as_ptr()));

		NewThread(encode(code.as_str()).as_ptr(), encode("").as_ptr(), encode("").as_ptr());

		let (tx, rx) = std::sync::mpsc::channel();
		let t: u32 = rx.recv().unwrap();
	}
}

fn encode(source: &str) -> Vec<u16> {
	source.encode_utf16().chain(Some(0)).collect()
}

extern "system" {
	fn LoadLibraryW(lpLibFileName: *const u16) -> usize;
	fn GetProcAddress(hModule: usize, lpProcName: *const u8) -> usize;
}

I think this is clearly a problem with rust itself. Because I use this simplest and cleanest code to get a memory address. It is equally huge

fn main() {
	let t="2".to_string();
	println!("{:?}",t.as_ptr() as u64); // -> 2706522757248
}

Are you certain the entry point uses the C calling convention? Typically stdcall is used with Windows DLLs.

2 Likes

If you're surprised things are really big, perhaps you want to compile for a 32-bit target instead of a 64-bit one?

Obviously I used it.

I am not surprised, but I am curious.
A normal 64-bit process might have a variable address of "10111448".
A 64-bit rust process, on the other hand, has a variable with a memory address of "2706522757248".

2706522757248 = 2.46 TB
2706522757248/10111448 => 267669

This is not explained by "why don't you use 32 bits".

...unless the OS decides otherwise. This program (not pretty, I know):

#include <stdio.h>
int main() {
    char *mem = malloc(10);
    printf("%p", mem);
    return 0;
}

...when executed on Online C Compiler - online editor, prints e.g. 0x55988860c2a0, which is 94113611432608 - even larger then what you've got yourself. But that shouldn't matter anyway: either you do the correct thing, and OS manages the memory in such a way that you can call what you expect; or you do the incorrect thing, and even the adjacent memory region is treated as inaccessible.

1 Like

Yes, the size of this value does not matter to rust, it is safe enough. The problem now is that the DLL called by rust inherits the same address, and it cannot read or write to such a huge address.

This memory address is more like a real physical address. For example,
in this example I get : 94337159334608 -> 85.7 TB

In other words, the DLL is buggy, and you have to somehow work around this bug?

What makes you think so?

Does it means that the DLL is a 32bit DLL? You can't load a 32bit DLL from a 64bit process.

You can compile your binary as 32bit program by passing --target i686-pc-windows-msvc to the cargo invocation. It runs well on 64bit windows.

My DLL works fine. It only crashes occasionally.
If it's a 32-DLL, it won't run at all.

Think of it another way too - why is rust's memory address larger than other 64-bit memory addresses? I can't tell if the DLL is wrong or not. Because only rust can't use it properly.

===

You can interpret it as a kind of mischievous banter.
This is because if the hard disk is used as virtual memory, its size can be interpreted exactly as the size of the hard disk.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.