A number can also be prepended to the format of the examine command
to examine multiple units at the target address.
source: hacking the art of exploration
(gdb) x/2x $eip
0x8048384 <main+16>: 0x00fc45c7 0x83000000
(gdb) x/x $eip
0x8048384 <main+16>: 0x00fc45c7
I know that the second examine command returns the memory address that eip is currently locating. What about the first one which returns two memory address?
The examine command of gdb has the following syntax:
x/[n][f][u]
where n, f and u are optional and n is the length, f the format and u the unit size.
Possible formats are:
s (null terminated string)
i (machine code instruction)
x (hexadecimal value)
If no unit size can be one of the following values:
b (bytes)
h (2 bytes)
w (4 bytes)
g (8 bytes)
where w is the default.
Therefore x/2x prints 2 hexadecimal values with a size of 4 bytes from your code segment.
Related
I want to use breakpoint in the UPtest function to stop at 0x000000000040124c.
run 111 222 333
I need to display the 32 records at the top of the stack.
x / 32wx $ esp, but show Cannot access memory at address 0xffffffffffffe0a0.
I want to find the return address of the main program, how do I change it to display it?Like the picture below.
The problem you're having is that the $esp register is 32-bit, but addresses on your target are 64-bit. When you do x/32wx $esp GDB is reading the $rsp register, which has the value 0x7fffffffffffe0a0 and masking this to 32-bits, so 0xffffe0a0, then it is sign extending this to 64-bit, giving 0xffffffffffffe0a0.
Try x/32wx $rsp and you should have more luck.
I have the following src:
1 #include<stdio.h>
2
3 int main(void) {
4 int i= 1337; // breakpoint after this value is assigned
!5 return 0;
6 }
In the asm from gdb I get:
!0x00000000004004f1 main+4 movl $0x539,-0x4(%rbp)
And I verified that $0x539 = 1337. How can I see the memory address where the value 1337 is stored? The value of the rbp memory address shows:
rbp 0x00007fffffffeb20
My thought was the rbp register would show the value 0x539, so where would I be able to find that in gdb (what command to use, etc)?
One interesting things I found was in doing:
>>> print i
$16 = 1337
>>> print &i
$17 = (int *) 0x7fffffffeb1c # how is this arrived at?
0x00007fffffffeb20 - 0x4 == 0x7fffffffeb1c
on x86 almost all constants will be addressed as a relative offset from a register. In this case the register is rbp [the frame address], and the relative offset is -4 bytes. i.e. the constant appears prior to the first instruction in main.
x64 addressing modes typically involve one of 3 possibilities:
a zero byte offset from a register address
a signed 8bit offset from a register address
a signed 32bit offset from a register address
(there is a 4th addressing mode, which is to load the value from a register - just for completeness!). In general, a compiler would prefer to emit those modes in the order I have listed them above (because they result in the Op code + an offset which will be either: 0bytes, 1byte, or 4bytes respectively - so the smaller the offset, the smaller the generated machine code will be).
I am trying to find out how to print an integer value (I saw that it is x/d) but I am missing something.
So, my code is the following
1 #include <stdio.h>
2 main(){
3 int a;
4 int b;
5 int c;
6 int d;
7 int multiplied;
8 a = 5;
9 b = 6;
10 c = 7;
11 d = adding(a,b,c);
12 multiplied = multiply(a,b,c);
13 printf("The value of d is %d \n",d);
14 printf("The multiplied values are %d \n", multiplied);
15 }
16 int adding(a,b,c){
17 int e;
18 e = a+b+c;
19 return e;
20 }
21 int multiply(a,b,c){
22 int f = a*b*c;
23 return f;
24 }
// I compiled with -q and I want to print the values of the variables (from their addresses) So...
(gdb) disassemble main
0x080483ed <+9>: mov DWORD PTR [esp+0x2c],0x5
0x080483f5 <+17>: mov DWORD PTR [esp+0x28],0x6
0x080483fd <+25>: mov DWORD PTR [esp+0x24],0x7
0x08048405 <+33>: mov eax,DWORD PTR [esp+0x24] <code>
I put some breakpoints in main / multiply / adding and then I was trying to do the following thing.
I used
print $esp+0x24
and
(gdb) x/4d 0xbffff47c but im not getting the right answers back.
I used the 4d because I thought that an integer is 4 bytes (or maybe again im missing something) but the results arent showing the value 5.
Can you please help me? Thanks and sorry for the bad output / format of gdb.. seriously i cant understand whats wrong
(gdb) print $esp+0x2c
$2 = (void *) 0xbffff494
(gdb) print $esp+0x28
$3 = (void *) 0xbffff490
(gdb) print $esp+0x24
$4 = (void *) 0xbffff48c
(gdb) x/d 0xbffff494
0xbffff494: -1208180748
(gdb) x/d 0xbffff490
0xbffff490: -1208179932
(gdb) x/d 0xbffff48c
0xbffff48c: 134513881
Also this happens ofcourse after the first breakpoint of main and actually the same values are coming all the time in all breakpoints (except the one before main...)
Another interesting thing that I found is the following... Im sure that the first values are garbages. But why it considers 0x5 as an address when it should print the actual value?
Breakpoint 1, main () at functioncalling.c:10
10 a = 5;
(gdb) x/s a
0xb7fc9ff4: "|M\025"
(gdb) cont
Continuing.
Breakpoint 3, adding (a=5, b=6, c=7) at functioncalling.c:21
21 e = a+b+c;
(gdb) x/s a
0x5: <Address 0x5 out of bounds>
I compiled your program with -g and no optimization, and set a breakpoint before line 11. My stack addresses are a bit different from yours, which isn't surprising given the variety of systems out there.
(gdb) print $esp+0x2c
$2 = (void *) 0xbffff44c
This is printing the address of a. To confirm:
(gdb) print &a
$4 = (int *) 0xbffff44c
Use x/wd to show a 4-byte integer in decimal.
(gdb) x/wd $esp+0x2c
0xbffff44c: 5
x/4d will show 4 values (4 is the repeat count) starting at the address. If you omit the size letter w here, the x command will default to the size previously used.
(gdb) x/4d $esp+0x2c
0xbffff44c: 5 134513856 0 -1073744680
There's your 5. As for the 3 other numbers, they are things further up the stack.
(gdb) x/4a $esp+0x2c
0xbffff44c: 0x5 0x80484c0 <__libc_csu_init> 0x0 0xbffff4d8
Your next question:
Another interesting thing that I found is the following... Im sure that the first values are garbages. But why it considers 0x5 as an address when it should print the actual value?
Breakpoint 3, adding (a=5, b=6, c=7) at functioncalling.c:21
21 e = a+b+c;
(gdb) x/s a
0x5: <Address 0x5 out of bounds>
The x command, when given a program's variable as its argument, retrieves its value and uses that as the address. x/s a means to retrieve the value in a and use it as the starting address of a NUL-terminated string. If a were of type char * and contained a suitable value, x/s would print sensible output. To print a's actual value, give the x command the argument &a.
(gdb) x/wd &a
0xbffff44c: 5
This may seem counterintuitive. Just consider the x command to operate just like the C statement printf(fmt, *(argument)) would. The argument to the x command is almost always a literal memory address or an address expression involving the stack pointer, base pointer, or pc registers.
Say I have attached gdb to a process and within the its memory layout there is a file and line number which I would like the memory address of. How can I get the memory address of line n in file x? This is on Linux x86.
(gdb) info line test.c:56
Line 56 of "test.c" starts at address 0x4005ae <main+37>
and ends at 0x4005ba <main+49>.
additionally with python you may be able to use the 'last' attribute from
Symbol-Tables-In-Python this currently requires a very recent version of gdb from cvs, but i imagine will have general availability in 7.5
(gdb) py x = gdb.find_pc_line(gdb.decode_line("test.c:56")[1][0].pc); gdb.execute("p/x " + str(x.pc)); gdb.execute("p/x " + str(x.last))
$15 = 0x4005ae
$16 = 0x4005b9
I tried to get idt address in my driver, I made function in asm which returns what idtr contains:
.data
myData dq 0
.code
Function PROC
sidt myData
mov rax, myData
ret
Function ENDP
END
But the address which I get is weird, for example in windbg:
r idtr
idtr=fffff80000b95080
However my driver shows:
idtr = f80000b950800fff
I read that on x64 IDTR contains 64-bit base address of IDT table. I would appreciate if anyone explain why my output is not the same as from WinDbg.
This is what the Intel docs say about the SIDT instruction:
In 64-bit mode, the operand size is fixed at 8+2 bytes. The instruction stores 8-byte base and 2-byte limit values.
and:
DEST[0:15] <- IDTR(Limit);
DEST[16:79] <- IDTR(Base);
This means your myData variable needs to be 10 bytes long, and the instructions stores the limit in the first 2 bytes and base address in the next 8 bytes. This also explains why your value matches with WinDbg's value after the first ffff bytes.