Reading memory pointed by register with GDB
I would try something like the following commands (under gdb
)
p (int*)$esp
x /20x $esp
p ((int*)$esp)[3]
How to print value pointed by register
Rax 0x7fffffdd90
Now inwant to know where rax. Is pointîg to
You already know that: it points to (stack) memory location at address 0x7fffffdd90
.
i want to print [rax]
x/gx $rax
or
print *(int**)$rax
I want to do somthing like set $eax = [$rax]
set $rax = *(int**)$rax
Using gdb to check register's values
To see the values of the registers just use
print $rax
info register $rax
info register
In your case it seems rax
contains the number 0x17
and the debugger cannot access this location. Please make sure that rax
contains a valid address pointing to an integer.
You should use print
instead of display
if you want to take a quick view. Dont abuse the display
command. You can use it if you need a kind of watchdog for an expression.
Here you find a quick reference
http://www.yolinux.com/TUTORIALS/GDB-Commands.html
hope it helps.
dereferencing a register gdb
The x
command will be the easiest way to display values in memory. Try, for instance:
(gdb) x/32b $ebp
If this doesn't work (especially if you get an error that "value can't be converted to integer"), you're probably debugging a 64-bit executable. x86-64 registers have different names; use $rbp
instead.
The characters after the slash in the x
command control how many values are displayed, and what format is used. x/s
will attempt to read a string from that address, for instance. If you don't use anything, gdb will use whatever you last used.
While it isn't strictly necessary to answer your question, I've fixed up some of the other commands you were trying to run:
p *((char *) $ebp) <- treat $ebp as a character pointer and display what it points to
p *((char *) $ebp + 4) <- with an offset
p ((char *) $ebp)[4] <- same thing as above, except using array syntax
The $
character is only needed when referring to registers, or to gdb variables. You don't need it for anything else.
How do I read the value of all registers with gdb?
info registers
prints out registers values for me which is what you are asking I think:
(gdb) info registers
rax 0x7ffff7731ec8 140737344904904
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffd618 140737488344600
rsi 0x7fffffffd608 140737488344584
rdi 0x1 1
rbp 0x0 0x0
rsp 0x7fffffffd528 0x7fffffffd528
r8 0x7ffff7730300 140737344897792
r9 0x7ffff7dec250 140737351959120
r10 0x7fffffffd390 140737488343952
r11 0x7ffff73d0b50 140737341360976
r12 0x400be0 4197344
r13 0x7fffffffd600 140737488344576
r14 0x0 0
r15 0x0 0
rip 0x402330 0x402330 <main>
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)
How can one see content of stack with GDB?
info frame
to show the stack frame info
To read the memory at given addresses you should take a look at x
x/x $esp
for hex x/d $esp
for signed x/u $esp
for unsigned etc. x uses the format syntax, you could also take a look at the current instruction via x/i $eip
etc.
How to set a gdb watchpoint to a value stored in register?
GDB doesn't let you explicitly dereference void *
pointers such as $rsp
. It doesn't know the size or the format of the pointed-to value.
Do watch *(char *)$rsp
or watch *(int *)$rsp
, etc., instead to watch for a change in what the register points to. (Either by memory writes, or by the register changing to point somewhere else.)
Using watch -l *(int*)$rsp
will watch for changes to that 4-byte memory location, even if $rsp
later changes. (Snapshotting the address).
On x86 CPUs, watch -l
can use a hardware watchpoint, unlike without -l
where it's monitoring for a change in evaluating the whole expression.
How do I get gdb to tell me memory characteristics a given address
gdb has no concept of dynamic allocation and no idea about freed memory. It can tell whether an address is mapped into the process address space or not:
gdb> info files
gdb> maintenance info sections
but since your program has crashed with a SIGSEGV, you already know it has tried to access an unmapped address.
Other tools can detect access to freed memory. valgrind
is normally your friend, but not for post-mortem debugging. You need to run the program under valgrind
to gain insight to its behaviour.
A segfault while dereferencing a pointer seldom means that the pointer is pointing to a freed memory. More often than not, it is the pointer itself that resides in freed memory that got reused and overwritten. So
int** ptrarr = new int*[5];
ptrarr[3] = new int(5);
// later
delete [] ptrarr;
// later still after many memory allocations
int* ptr = ptrarr[3]; // ptrarr points to freed memory; UB but no segfault
// ptr contains a seemingly random value
int num = *ptr; // possible segfault
It is very hard to extract this kind of information from a post-mortem dump of a non-instrumented executable. You need to be familiar with the internal working of malloc
and new
, be able to chase their internal data structures, and map out their arena by hand. This is not a trivial task. Using a version of the standard library with preserved debugging symbols will help.
Failing that, you may try and map out your program's memory, including static/global variables, stack variables, all allocated data structures pointed to by the above, and all allocated data structures pointed to by pointers in other allocated data structures. I know about no tools that are able to do this automatically from a post-mortem dump, though in theory such tools are possible.
Having mapped the program memory, or perhaps some part of it, you can try and find out if an unrelated object of a different type sits at the address where your invalid pointer resides. If so, you may conclude that one of the two objects might be freed memory that was illegally accessed after being freed.
Related Topics
Linux Device Driver Unsafe Fxsave/Fxrstor Bug - Any Precedents
Detect If Interface Is in Promiscuous Mode with C
Run 'Perf Stat' on The Output of 'Perf Record'
How to Install and Run Tacotron2 on Ubuntu Wsl
Proxmox with Opnsense as Firewall/Gw - Routing Issue
How to 'Chmod -R +W' with Ant, Files and Folders
Linux Directory Starting with Dot
Emacs/Xterm Color Annoyance on Linux
How to Set The Current Directory of a Debugged Process
How to Compile Redis So That I Can Upload and Run It on Shared Hosting
Reading Memory Pointed by Register with Gdb
Replace Strings with Evaluated String Based on Matched Group (Elegant Way, Not Using for .. In)
How to Have Postgresql Not Collapse Punctuation and Spaces When Collating Using a Language
How to Make Linux Ignore a Keyboard While Keeping It Available for My Program to Read
.Lis Files Generated While Compiling Pro*C Code in Linux
-Bash: /Usr/Bin/Virtualenvwrapper.Sh: No Such File or Directory