Consider the following code in mono/domain.c:
static MonoDomain *mono_root_domain = NULL;
...
MonoDomain* mono_get_root_domain (void)
{
return mono_root_domain;
}
My task is to read the struct data pointed by the mono_root_domain pointer in runtime from another process. (Attaching, reading, locating dylibs, etc. from this other process is solved already)
Looking into the generated libmono dylib I can find the corresponding symbol:
This symbol points to the address of 0x2621A8 which in the local relocation section (__DATA, __bss):
This points to the address of 0x1A7690 (__TEXT, __symbol_stub):
so 0x1A7DF8 (__TEXT, __stub_helper):
At this point I am completely lost of how to retrieve the actual pointer to the MonoDomain struct. Any help is appreciated.
For security reasons and to prevent buffer overflow attacks and other exploits, you can't know that, because of a security measure called PIE or ASLR (address space layout randomization). However, this can be disabled for debugging purposes. LLDB and GDB do/did it in order to debug executables. The way this can be done with a CLI app is as follows:
cd
to where your executable ischmod +x ./change_mach_o_flags.py
to make the script executable./change_mach_o_flags.py --no-pie ./YourExecutable
Now the addresses of your executable should not be randomized anymore. Because of that, to calculate the addresses of your static / global variables is possible. To do that, do the following in Terminal (I am assuming you are using a 64-bit machine):
otool -v -l ./YourExecutable | open -f
(this will generate a file text with the commands inside your executable of how to layout DATA, TEXT, etc. in memory)Look for the section you are interested in. Look at the
addr
field. If it contains let's say0x0000000100001020
then the variable will be placed exactly there with ASLR disabled.I am not sure if this works with dylibs but you can try it. Now I ran out of time, but I can try at home and see if this is doable with dylibs.