GDB qemu-arm cannot access memory - gdb

While tracing syscal impelmentaiton in the kernel, I'd liek to get soem args on some function but I keep having some "cannot access memory" messages.
Here's a trace in GDB, with a breakpoint on execve.
Breakpoint 1, __se_sys_execve (filename=-1095651928, argv=-1095651992, envp=540336) at fs/exec.c:2063
2063 SYSCALL_DEFINE3(execve,
(gdb) print (char *)-1095651928
$1 = 0xbeb1ada8 <error: Cannot access memory at address 0xbeb1ada8>
Any clue ? I've put "set mem inaccessible-by-default off" command also but didn't helped.
Thanks in advance.

Related

How can I use a variable name instead of addresses when debugging valgrind runs with gdb?

Let's say I'm debugging with valgrind and gdb by doing:
$ valgrind --vgdb-error=0 ./magic
...and then in a second terminal:
$ gdb ./magic
...
(gdb) target remote | /usr/lib/valgrind/../../bin/vgdb
If I want to examine the defined-ness of some memory, I can use:
(gdb) p &batman
$1 = (float *) 0xffeffe20c
(gdb) p sizeof(batman)
$2 = 4
(gdb) monitor get_vbits 0xffeffe20c 4
ffffffff
Using three commands to do one thing is kind of annoying, especially since I usually want to do this a few times for many different variables in the same stack frame. But if I try the obvious thing, I get:
(gdb) monitor get_vbits &batman sizeof(batman)
missing or malformed address
Is it possible to get gdb to evaluate &batman and sizeof(batman) on the same line as my monitor command?
But if I try the obvious thing, I get: missing or malformed address
This is from GDB doc (http://sourceware.org/gdb/onlinedocs/gdb/Connecting.html#index-monitor-1210) for the monitor cmd:
monitor cmd
This command allows you to send arbitrary commands
directly to the remote monitor. Since gdb doesn't care about the
commands it sends like this, this command is the way to extend gdb—you
can add new commands that only the external monitor will understand
and implement.
As you can see "gdb doesn't care about the commands it sends like this". It probably means that the command after monitor is not processed in any way and sent AS IS.
What you can do to evaluate your variable on the same line is to use user defined commands in gdb (http://sourceware.org/gdb/onlinedocs/gdb/Define.html). Define your own comand and use the eval gdb command to prepare your command with necessary values (http://sourceware.org/gdb/current/onlinedocs/gdb/Output.html#index-eval-1744):
define monitor_var
eval "monitor get_vbits %p %d", &$arg0, sizeof($arg0)
end
And then use it like this:
(gdb) monitor_var batman

Dump memory in lldb

As stated on this site. When I want to dump memory in gdb.
The start point is 0x1000 and end 0x2000.
For lldb start is 0x1000 and end 0x1200 .
Is there a reason for this or is just a mistake ?
Main question is: How do I dump a memory area from 0x1000 to 0x2000 in lldb?
The following works fine for me:
(lldb) memory read --outfile /tmp/mem.txt 0x6080000fe680 0x6080000fe680+1000
Dumps 1000 bytes of memory, from the given start address, in hex format, to /tmp/mem.txt. Use --binary for binary format.
You could also use 'count' to state how many bytes you want to dump:
(lldb) memory read --outfile /tmp/mem.txt --count 1000 0x6080000fe680
If you are in Xcode debugging environment and have a variable named 'note1', you can also use:
(lldb) memory read --outfile /tmp/mem.bin note1 note1+100
Reads at the actual location 0x1000 fail in Xcode for me ("memory read failed"), must be protected in some way.
As to the difference between 0x1200 and 0x2000 in the documentation, I think it's simply a small mistake.

GDB Patching results in "Cannot access memory at address 0x

I have a program that I need to patch using GDB. The issue is there is a line of code that makes a "less than or equal test" and fails causing the program to end with a Segmentation fault. The program is already compiled and I do not have the source so I cannot change the source code obviously. However, using GDB, I was able to locate where the <= test is done and then I was able to locate the memory address which you can see below.
(gdb) x/100i $pc
... removed extra lines ...
0x7ffff7acb377: jle 0x7ffff7acb3b1
....
All I need to do is change the test to a 'greater than or equal to' test and then the program should run fine. The opcode for jle is 0x7e and I need to change it to 0x7d. My assignment gives instructions on how to do this as follows:
$ gdb -write -q programtomodify
(gdb) set {unsigned char} 0x8040856f = 0x7d
(gdb) quit
So I try it and get...
$ gdb -write -q player
(gdb) set {unsigned char} 0x7ffff7acb377 = 0x7d
Cannot access memory at address 0x7ffff7acb377
I have tried various other memory addresses and no matter what I try I get the same response. That is my only problem, I don't care if it's the wrong address or wrong opcode instruction at this point, I just want to be able to modify the memory.
I am running Linux Mint 14 via VMware Player
Thank
Cannot access memory at address 0x7ffff7acb377
You are trying to write to an address where some shared library resides. You can find out which library that is with info sym 0x7ffff7acb377.
At the time when you are trying to perform the patch, the said shared library has not been loaded yet, which explains the message you get.
Run the program to main. Then you should be able to write to the address. However, you'll need to have write permission on the library to make your write "stick".

How to find a function's memory address with lldb?

In GDB, I can use "info line func_name" to get the memory address of func_name, and then use "set $PC=memory_address" to start debugging this function. How do I do the same within lldb? Thanks in advance!
The command in lldb is "image lookup". I think an example of "info func" <-> "image lookup" was recently added to the lldb/gdb command page - http://lldb.llvm.org/lldb-gdb.html
e.g.
(lldb) im loo -n puts
1 match found in /usr/lib/system/libsystem_c.dylib:
Address: libsystem_c.dylib[0x0000000000011d9a] (libsystem_c.dylib.__TEXT.__text + 69850)
Summary: libsystem_c.dylib`puts
(lldb)
although this is only showing you the offset in libsystem_c.dylib here (0x11d9a) -- to see the actual load address you would need to use the "-v" option to image lookup which will show the range of addresses that puts covers. Or you could do this more directly with the back tick notation in lldb,
(lldb) reg read pc
rip = 0x0000000100000f2b a.out`main + 11 at a.c:3
(lldb) reg write pc `(void(*)())puts`
(lldb) reg read pc
rip = 0x00007fff99ce1d9a libsystem_c.dylib`puts
OK I had to cast puts() because lldb needed a function prototype here - not super convenient, but if it's one of your own functions that isn't needed:
(lldb) reg write pc `main`
(lldb) reg read pc
rip = 0x0000000100000f20 a.out`main at a.c:2

Linux Kernel Text Symbols

When I look through a linux kernel OOPS output, the EIP and other code address have values in the range of 0xC01-----. In my System.map and objdump -S vmlinux output, all the code addresses are at least above 0xC1------. My vmlinux has debug symbols included (CONFIG_DEBUG_INFO).
When I debug over a serial connection (kgdb), and I load gdb with gdb ./vmlinux, again I have the same issue that I cannot reconcile $eip with what I have in System.map and objdump output. When I run where in gdb, I get a jumbled mess on the stack:
#0 0xC01----- in ?? ()
#1 0xC01----- in ?? ()
#2 0xC01----- in ?? ()
...
Can anyone make any suggestions on how to resolve this/these issues? My main concern is how I actually map an eip value from an OOPS to System.map or objdump -S vmlinux. I know that the OOPS will give me the function name and offset into the object code, but I am more concerned about the previously mentioned issue and why gdb can't correctly display a stack backtrace.
Looks like the OOPS is because you jumped into a place that's not a function.
This would easily cause a crash, and would also prevent the debugger from resolving the address as a symbol.
You can check this by disassembling the area around this EIP. If I'm correct, it won't make sense as machine code.
There are generally two causes for such things:
1. Function call using a corrupt function pointer. In this case, the stack frame before the last should show the caller. But you don't have this frame, so it may be the other reason.
2. Stack overrun - your return address is corrupt, so you've returned to a bad location. If it's so, the data ESP points to should contain the address in EIP. Debugging stack overruns is hard, because the most important source of information is missing. You can try to print the stack in "raw" format (x/xa addr), and try to make sense of it.