Finding virtual memory address of variable on osx - c

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):
The target is
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:
Copy or download this python script from GitHub
https://github.com/thlorenz/chromium-build/blob/master/mac/change_mach_o_flags.py
Save the python script, for example, next to your executable
If so, open Terminal and cd to where your executable is
enter chmod +x ./change_mach_o_flags.py to make the script executable
enter ./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 say 0x0000000100001020 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.

Related

Package for MSYS2 to resolve shmget Error

I have compiled a string matching tool SMART in windows using MSYS2, the tool is implemented in C programming language. The instruction was (in the the instruction set):
makefile is the bash file used for compiling the C source files of the tool. Run the command ./makefile in order to compile the smart
tool. The code of each string matching algorithm is compiled an
tested separately.
The problem now is, each algorithm is compiled properly but tested unsuccessfully.
Also, when the following command is given to execute (see how to run experimental tests):
./smart -text englishTexts
I get the following error:
shmget: Function not implemented
I doubt both issues are related/due to the failure of managing shared memory, note that author created the system on a POSIX system (whereas I am trying to run this on a Windows system). Author wrote about the Manage shared memory on LINUX:
In order to configure shared memory on linux you have to login as
root, then edit the file
/etc/sysctl.conf.
The kernel.shmax parameter defines the maximum size in bytes for a
shared memory segment. Determine the value of kernel.shmax by
performing the following:
cat /proc/sys/kernel/shmmax
33554432
The kernel.shmall parameter sets the total amount of shared memory in
pages that can be used at one time on the system. Set the value of
both of these parameters to the amount physical memory on the machine.
As in the previous case you can determine the value of kernel.shmax by
performing the following:
cat /proc/sys/kernel/shmmall
2097152
Set the values of kernel.shmax and kernel.shmall, as follows:
echo MemSize > /proc/sys/shmmax
echo MemSize > /proc/sys/shmall
where MemSize is the number of bytes. For example, to set both values
to 2GB, use the following:
echo 2147483648 > /proc/sys/kernel/shmmax
echo 2147483648 > /proc/sys/kernel/shmall
Then reboot the machine using. Shared memory can be viewed with the
ipcs command and you can delete shared memory segments with the ipcrm
command.
But there is nothing specific about Windows (though there is a paragraph for "Manage shared memory on WINDOWS VISTA").
At this point I ask your help, to inform me whether there is a package for MSYS2 to solve shmget error mentioned above? Or there are other ways to solve this problem?
Unfortunately I think you're out of luck with msys2. msys2 takes out cygserver from cygwin, which is required for shared memory.

Is it possible to create an executable file with just copying the text segment?

When you run a C program, is it possible to get its binary code (which you execute with ./foo) from its TEXT segment? If I just copy all the TEXT segment to a file, then can I execute it and run the same program? I am working with Ubuntu.
is it possible to get it binary code
If you run your program under the debugger, then you can copy the bytes from anywhere in the process space, being data or code.
then i can execute it and run the same program?
Simple answer: No!
An executable file is a lot more than just a memory dump.
If your program is static-linked and position-dependent and has no global data (note: the last is not true with any non-toy libc implementation), then in theory the text segment is sufficient to run it. However, you would need an appropriate loader to do so. Normal operating systems' executable file loaders do not load this kind of "raw text segment" as an executable because (1) is has no header information to indicate that that's what it is, or even where to start execution at (i.e. what's the entry point), and (2) it's not generally useful to do so. DOS had something akin to this with .COM files, and uClinux had FLAT binaries that were close to this but with some minimal header, but those are the closest you'll find to a "raw text segment" binary in the past 3-4 decades.
there is the link with familiar question
Is it possible to dissembler running process in Linux?
char *comp = "objdump -d /proc/1234/exe";
fflush(NULL); // always useful before system(3)
int nok = system(comp);
if (nok) {
fprintf(stderr, "compilation %s failed with %d\n", comp, nok);
exit(EXIT_FAILURE);
}
So what i want is a /proc/<PID>/exe file.

Issue Observed while using GDB

I am trying to debug my application which use one static builded library.
I want to set break points in my library so i tried to set it using below command :
break TS.cpp:600(FIle name:line no)
but it says
No source file named TS.cpp.
Make breakpoint pending on future shared library load?(y or [n])
so I presses y here (I came to know after browsing internet) but after pressing y gdb is not stopping at my break point and it completed executing program.
Why GDB is not stopped at my break point??
Any input is highly appreciated.
No source file named TS.cpp
This means one of two things:
either the file TS.cpp was not compiled with -g (or equivalently TS.o has been stripped), or
the file TS.o was not linked into the application.
Since you are seeing prints from that source, it's a safe bet that #1 is the actual root cause.
info sources command shows only my application.c and not the files of my library
That is another confirmation that #1 is the root cause.
The problem in your case is with source mapping. It normally happens when application is compiled at some other machine and you are debugging it on some other machine where source location is different.
You can specify source path using directory command of gdb. e.g. if your sources are in /home/taimoor/testApp/src, you can do following:
(gdb) directory /home/taimoor/testApp/src

How to read, understand, analyze, and debug a Linux kernel panic?

Consider the following Linux kernel dump stack trace; e.g., you can trigger a panic from the kernel source code by calling panic("debugging a Linux kernel panic");:
[<001360ac>] (unwind_backtrace+0x0/0xf8) from [<00147b7c>] (warn_slowpath_common+0x50/0x60)
[<00147b7c>] (warn_slowpath_common+0x50/0x60) from [<00147c40>] (warn_slowpath_null+0x1c/0x24)
[<00147c40>] (warn_slowpath_null+0x1c/0x24) from [<0014de44>] (local_bh_enable_ip+0xa0/0xac)
[<0014de44>] (local_bh_enable_ip+0xa0/0xac) from [<0019594c>] (bdi_register+0xec/0x150)
In unwind_backtrace+0x0/0xf8 what does +0x0/0xf8 stand for?
How can I see the C code of unwind_backtrace+0x0/0xf8?
How to interpret the panic's content?
It's just an ordinary backtrace, those functions are called in reverse order (first one called was called by the previous one and so on):
unwind_backtrace+0x0/0xf8
warn_slowpath_common+0x50/0x60
warn_slowpath_null+0x1c/0x24
ocal_bh_enable_ip+0xa0/0xac
bdi_register+0xec/0x150
The bdi_register+0xec/0x150 is the symbol + the offset/length there's more information about that in Understanding a Kernel Oops and how you can debug a kernel oops. Also there's this excellent tutorial on Debugging the Kernel
Note: as suggested below by Eugene, you may want to try addr2line first, it still needs an image with debugging symbols though, for example
addr2line -e vmlinux_with_debug_info 0019594c(+offset)
Here are two alternatives for addr2line. Assuming you have the proper target's toolchain, you can do one of the following:
Use objdump:
locate your vmlinux or the .ko file under the kernel root directory, then disassemble the object file :
objdump -dS vmlinux > /tmp/kernel.s
Open the generated assembly file, /tmp/kernel.s. with a text editor such as vim. Go to
unwind_backtrace+0x0/0xf8, i.e. search for the address of unwind_backtrace + the offset. Finally, you have located the problematic part in your source code.
Use gdb:
IMO, an even more elegant option is to use the one and only gdb. Assuming you have the suitable toolchain on your host machine:
Run gdb <path-to-vmlinux>.
Execute in gdb's prompt: list *(unwind_backtrace+0x10).
For additional information, you may checkout the following resources:
Kernel Debugging Tricks.
Debugging The Linux Kernel Using Gdb
In unwind_backtrace+0x0/0xf8 what the +0x0/0xf8 stands for?
The first number (+0x0) is the offset from the beginning of the function (unwind_backtrace in this case). The second number (0xf8) is the total length of the function. Given these two pieces of information, if you already have a hunch about where the fault occurred this might be enough to confirm your suspicion (you can tell (roughly) how far along in the function you were).
To get the exact source line of the corresponding instruction (generally better than hunches), use addr2line or the other methods in other answers.

u-boot text area overflow when adding command defines

On my mx53_loco board i have a problem:
when i add the command line help define (CONFIG_SYS_LONGHELP) in the board specific header, building complete successful but when i boot the board i find a corrupted environment (all commmands are unrecognized).
I have this problem even if i increase the size of the CONFIG_EXTRA_ENV_SETTINGS define.
So it seems to be a problem related to size of the u-boot code that overflows somewhere. (memory map re-definition?)
I would to be able to resize internal layout of u-boot correctly.
Can anyone explain me what happens or suggest a helpful link?
u-boot always reads the saved environment variables first. These environment variables are typically in non-volatile memory (NOR or NAND flash, or others). If the CRC of the saved environment variables are correct the saved env variables are used. If you changed your CONFIG_EXTRA_ENV_SETTINGS it won't be used!
The values in the CONFIG_EXTRA_ENV_SETTINGS will only be used when you reset the env vars to default and save them:
$ env default -f
$ saveenv
You should also take care of your mapping and sizes. When you add new env variables make sure CONFIG_ENV_SIZE and CONFIG_ENV_OFFSET are correct.
Please read the README file in the top-level directory of the u-boot sources.
And browse the mailing list: http://news.gmane.org/gmane.comp.boot-loaders.u-boot
Edit:
You should also verify that CONFIG_SYS_FLASH_BASE and CONFIG_SYS_MONITOR_LEN are correct. Just make sure you don't overlap the flash area covered by u-boot and the flash area where you write your env variables.

Resources