Using gdb to decode hex data to struct - gdb

I have a hex stream of hex data that is printed like
0x3a45 0x1234 0x0352 (in real far longer)
I know that it is content in a struct. Is there a way in gdb to map this on the struct? Gdb seems only to accept single values for doing this.
Like:
(gdb) print (myStruct) 0x3a45 0x1234 0x0352
$1 = { a = 3a, b = 45, f = 0x1234, c = 03, e = 52}
In this case it's very simple but there is complex struct and the hex string is far larger.

I think there are a couple viable ways to do this in gdb.
The simplest way is to write the data into the inferior's memory somehow. It might look something like:
(gdb) set $mem = malloc(50) # number of bytes
(gdb) set $mem[0] = 0x72
(gdb) set $mem[1] = 0xff
# etc - you can find faster ways to do this
(gdb) print *(struct whatever *) $mem
Filling the memory is a pain, but this can be scripted. For example you can write a little shell script to convert the raw bytes into a sequence of set commands and then source it. Or you can just write a new gdb command in Python that automates it all.
gdb also has an extension to let one create an array on the command line, and do a kind of "reinterpret cast" on it. I found this method a bit less handy, because I could only make the array feature create arrays of int, not char. But anyhow, consider this little program:
struct x {
int a;
long b;
};
int main() {
struct x x = { 23, 97 };
return 0;
}
I start gdb and stop on the return, then examine the memory:
(gdb) p sizeof(int)
$1 = 4
(gdb) p sizeof(x)
$2 = 16
(gdb) x/4xw &x
0x7fffffffe240: 0x00000017 0x00007fff 0x00000061 0x00000000
(That second word is garbage because it is in the struct padding...)
Now we can recreate x by hand from the raw data:
(gdb) print {struct x}{0x17, 0x7fff, 0x61, 0}
$3 = {
a = 23,
b = 97
}
This expression uses two extensions to C expressions that gdb provides. First, {0x17, 0x7fff...} is a way to write an array. Second, {struct x} is a kind of "reinterpret cast" - it reinterprets the raw bytes of the value as named type.

Related

How to view binary content of a C++ integer in gdb?

int main()
{
int a = 0;
}
I compile: g++ -std=c++14 -g test.cpp
Run program in gdb:
gdb ./a.out
(gdb) break main
(gdb) run
(gdb) next
What I have tried:
(gdb) print /t &a
That prints 11111111111111111111111111111111101110101111100
That doesn't look like the right number, I was expecting 0000....0000. How can I print binary values from the memory location of the integer variable a ?
You are trying to print the address of a which is in the stack frame of main and has nothing to do with its value. Try:
print /t a
Use p /x to print something in hex. Let us look after a has been set to 0.
(gdb) n
28 return(0);
(gdb) p a
$6 = 0
ok
(gdb) p /x a
$7 = 0x0
ok in hex
(gdb) p /x &a
$8 = 0x7fffffffe3dc
address of a in automatic memory (on the stack).
(gdb) p /t &a
$9 = 11111111111111111111111111111111110001111011100
looks like binary, and slightly different on my machine than yours. good.
(gdb) print /t &a
That prints 11111111111111111111111111111111101110101111100
That doesn't look like the right number?
33 1's at the front, and the last 4 bits are 0xc.
Mine looks correct compared to hex. 0x7fffffffe3dc.
I suspect yours is too.
If you were expecting a bunch of 0's. that would be the value of a, not the address of a
(gdb) p /t a
$10 = 0
gdb shrunk the results - 0 is indeed a bunch of 0's.
You could also see it using a gui like: https://github.com/cyrus-and/gdb-dashboard which I recommend if you don't have a lot of experience with gdb. Also a simple cheat sheet will be helpful to have at hand: http://darkdust.net/files/GDB%20Cheat%20Sheet.pdf

pointer to a variable is not updating variable when dereferenced

This is a debugging problem I've been trying to solve. I know the bit mask I need to apply to make b equal a. I inspected with gdb to find the difference between a and b. The variables b and a are char[] types and set prior to reaching the 'bug'.
#include <string.h>
int main() {
char a[1] = "a";
char b[1] = "b";
int *x;
x = (int *) b;
// bug in next line
*x = *x & 0xffffffff;
return memcmp(a, b, 1);
}
Until a equals b, I can't solve the problem. The only constraint given is that the bug is in the line noted, no other code is to be changed. There is no rule saying I can't add lines after the bug, though and before the memcmp().The issue I find is that nothing I do to the bit mask changes the value of b, ever. I've set breakpoints and inspected the value of x and *x before and after the bug, but x seems to not change.
Breakpoint 1, main () at test.c:9
9 *x = *x & 0xffffffff;
(gdb) print (int) a
$1 = -6922
(gdb) print (int) b
$2 = -6921
(gdb) print (int) x
$3 = -6921
(gdb) step
Breakpoint 2, main () at test.c:10
10 return memcmp(a, b, 1);
(gdb) print (int) a
$4 = -6922
(gdb) print (int) b
$5 = -6921
(gdb) print (int) x
$6 = -6921
I don't see how this can be solved the way requested, by modifying the constant in the line where the bug is. Any help to understand how to use x to update b using a bitwise mask would be appreciated.
x is a pointer; casting it to an int simply gives you the address as a decimal number.
a and b are both arrays, which will decay to a pointer when you do operations that require a pointer. By casting them to int you're again getting the address of the variable. The address doesn't change with the operation you're performing, even when the contents at that address changes.
Since a and b are both smaller than an int, your code is likely to mess up in ways that are extremely painful. Even if they were the right size, this isn't guaranteed to do the right thing.
You are trying to change the address of b but in
*x = *x & 0xffffffff;
You are changing the value because you are dereferencing x. Yyou need to apply the manipulation to x itself like
x = x & 0xffffffff;
And then you need to reassign x into b.
This will run afoul of the strict aliasing rules.

Array of pointer not giving proper output as it suppose?

Hi i have array of two pointers int *p[2] and i am trying to store 3 address of integer lets take &i,&j,&k as below code At *p[0]
i am getting garbage why here garbage ?it should be at p[2]? At *p[1] i am getting value it is ok but At *p[2] i am getting value here i should get garbage?
#include<stdio.h>
int main()
{
int i=10,j=20,k=30;
int *p[2]; // here p is array of 2 pointers
p[0]=&i; // but here i am storing
p[1]=&j; // 3 address of variable i,j,k
p[2]=&k;
printf("p[0]=%d\n",*p[0]); // why garbage here ?
printf("p[1]=%d\n",*p[1]); // here 20
printf("p[2]=%d\n",*p[2]); // here 30 why here ?
}
printf("p[2]=%d\n",*p[2]); // here 30 why here ?
Because p has two elements, not three. You can access elements 0 and 1, but accessing 2 is undefined behavior. Any number can be printed, or your program could crash when you invoke undefined behavior.
I am getting value here i should get garbage?
30 is as good a garbage value as any other number.
**EDIT (in response to an edit of the question) When you assign p[2] = &k you write to a location that is not allocated to your program. However, if the write operation completes without a crash, the new value would stay in memory.
Since the memory to which you wrote an address of k does not belong to your program, the system may write a new value into it. However, it wouldn't do it with 100% certainty: it may not write a new value into that memory at all. This is precisely what appears to be happening in your case: the value of &k written into p[2] illegally "survives" past two invocations of printf, producing 30 as the result.
u are using int *p[2], which is an array of size 2. only p[0] and p[1] are valid. remember the index of an array in c++ starts with 0 not 1. using p[2] would end up with something strange.
you are having array of two pointers int *p[2]. But you are trying to print the next element using pointer-
printf("p[2]=%d\n",*p[2]);
It results in undefined behavior. Anything can happen. But you are getting 30 some times you may get garbage values.
For your program i am getting-
root#ubuntu:~/c/array/string# ./a.out
p[0]=10
p[1]=20
p[2]=-13543595 // note this value. Undefined Behaviour
root#ubuntu:~/c/array/string#
first of all you need
int *p[3].
secondly since you used
int *p[2]
p[2] wasn't kept aside for this array. so what was there at p[2]? in my case it was variable k.
mine was 64 bit system with 64 bit pointers.
my output
p[0]=10
p[1]=20
p[2]=32767
and look at the gdb dump especially the addresses of k and p[2]
(gdb) p p[0]
$7 = (int *) 0x7fffffffe02c
(gdb) p p[1]
$8 = (int *) 0x7fffffffe028
(gdb) p p[2]
$9 = (int *) 0x7fffffffe024
(gdb) p &i
$10 = (int *) 0x7fffffffe02c
(gdb) p &j
$11 = (int *) 0x7fffffffe028
(gdb) p &k
$12 = (int *) 0x7fffffffe024
(gdb) p &p
$14 = (int *(*)[2]) 0x7fffffffe010
(gdb) x/32 0x7fffffffe010
0x7fffffffe010: -8148 32767 -8152 32767
0x7fffffffe020: -8156 32767 20 10
in your case it must have been the address of i.

gdb - get variable name of register

In GDB, info registers or info all-registers will show you all of the register symbol names and their values.
Question:
How do I get the variable name (i.e. from the source code) that is stored in that register? (or a line number in source code, or anything)
For example:
int my_reg = /* something */;
float another_reg = /* something else */;
...
Then perhaps, info all-registers will return:
R0 0x0 0
R1 0xfffbf0 16776176
R2 0x0 0
R3 0x0 0
R4 0x6 6
How do I determine which register (R0? R2? R4?) is "associated" with my_reg?
If you have access to the debug symbols (and understand how to read them - that is, you have some code that parses the debug symbols), it is possible to trace exactly which register corresponds to which register. However, this is quite possibly changing from one line to the next, as the compiler decides to move things around for one reason or another (e.g. some calculation starts with R1, and ends up with the result in R2, because that's better than trying to retain the value in R1 [or we need the original value in R1 too - think array[x++] - now we have the new value of x, hopefully in a register, and the value of the old x that we need to use for indexing, also needed to be in a register to add to the base-address of array.
Not all variables end up in registers (depending on processor, and "what registers are available").
The debugger WILL know where each variable is at any given time - but sometimes it can be a big confused, e.g:
int array[10000];
...
for(int i = 0; i < 10000; i++)
{
array[i] = rand();
}
may translate to something like this during optimization:
int array[10000];
int *ptr = array;
int *ptr2 = &array[10000];
while(ptr < ptr2)
{
*ptr++ = rand();
}
Now try printing i... ;)
There might be one register, multiple registers, or even no registers associated with any given C variable at any given point in time. You'll have to inspect the disassembly to see what's going on.
Why not just print my_reg to see the value?
l *$pc will list the source code around the current instruction being executed.

Can I set a breakpoint on 'memory access' in GDB?

I am running an application through gdb and I want to set a breakpoint for any time a specific variable is accessed / changed. Is there a good method for doing this? I would also be interested in other ways to monitor a variable in C/C++ to see if/when it changes.
watch only breaks on write, rwatch let you break on read, and awatch let you break on read/write.
You can set read watchpoints on memory locations:
gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface
but one limitation applies to the rwatch and awatch commands; you can't use gdb variables
in expressions:
gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.
So you have to expand them yourself:
gdb$ print $ebx
$13 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()
Edit: Oh, and by the way. You need either hardware or software support. Software is obviously much slower. To find out if your OS supports hardware watchpoints you can see the can-use-hw-watchpoints environment setting.
gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.
What you're looking for is called a watchpoint.
Usage
(gdb) watch foo: watch the value of variable foo
(gdb) watch *(int*)0x12345678: watch the value pointed by an address, casted to whatever type you want
(gdb) watch a*b + c/d: watch an arbitrarily complex expression, valid in the program's native language
Watchpoints are of three kinds:
watch: gdb will break when a write occurs
rwatch: gdb will break wnen a read occurs
awatch: gdb will break in both cases
You may choose the more appropriate for your needs.
For more information, check this out.
Assuming the first answer is referring to the C-like syntax (char *)(0x135700 +0xec1a04f) then the answer to do rwatch *0x135700+0xec1a04f is incorrect. The correct syntax is rwatch *(0x135700+0xec1a04f).
The lack of ()s there caused me a great deal of pain trying to use watchpoints myself.
I just tried the following:
$ cat gdbtest.c
int abc = 43;
int main()
{
abc = 10;
}
$ gcc -g -o gdbtest gdbtest.c
$ gdb gdbtest
...
(gdb) watch abc
Hardware watchpoint 1: abc
(gdb) r
Starting program: /home/mweerden/gdbtest
...
Old value = 43
New value = 10
main () at gdbtest.c:6
6 }
(gdb) quit
So it seems possible, but you do appear to need some hardware support.
Use watch to see when a variable is written to, rwatch when it is read and awatch when it is read/written from/to, as noted above. However, please note that to use this command, you must break the program, and the variable must be in scope when you've broken the program:
Use the watch command. The argument to the watch command is an
expression that is evaluated. This implies that the variabel you want
to set a watchpoint on must be in the current scope. So, to set a
watchpoint on a non-global variable, you must have set a breakpoint
that will stop your program when the variable is in scope. You set the
watchpoint after the program breaks.
In addition to what has already been answered/commented by asksol and Paolo M
I didn't at first read understand, why do we need to cast the results. Though I read this: https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html, yet it wasn't intuitive to me..
So I did an experiment to make the result clearer:
Code: (Let's say that int main() is at Line 3; int i=0 is at Line 5 and other code.. is from Line 10)
int main()
{
int i = 0;
int j;
i = 3840 // binary 1100 0000 0000 to take into account endianness
other code..
}
then i started gdb with the executable file
in my first attempt, i set the breakpoint on the location of variable without casting, following were the results displayed
Thread 1 "testing2" h
Breakpoint 2 at 0x10040109b: file testing2.c, line 10.
(gdb) s
7 i = 3840;
(gdb) p i
$1 = 0
(gdb) p &i
$2 = (int *) 0xffffcbfc
(gdb) watch *0xffffcbfc
Hardware watchpoint 3: *0xffffcbfc
(gdb) s
[New Thread 13168.0xa74]
Thread 1 "testing2" hit Breakpoint 2, main () at testing2.c:10
10 b = a;
(gdb) p i
$3 = 3840
(gdb) p *0xffffcbfc
$4 = 3840
(gdb) p/t *0xffffcbfc
$5 = 111100000000
as we could see breakpoint was hit for line 10 which was set by me. gdb didn't break because although variable i underwent change yet the location being watched didn't change (due to endianness, since it continued to remain all 0's)
in my second attempt, i did the casting on the address of the variable to watch for all the sizeof(int) bytes. this time:
(gdb) p &i
$6 = (int *) 0xffffcbfc
(gdb) p i
$7 = 0
(gdb) watch *(int *) 0xffffcbfc
Hardware watchpoint 6: *(int *) 0xffffcbfc
(gdb) b 10
Breakpoint 7 at 0x10040109b: file testing2.c, line 10.
(gdb) i b
Num Type Disp Enb Address What
6 hw watchpoint keep y *(int *) 0xffffcbfc
7 breakpoint keep y 0x000000010040109b in main at testing2.c:10
(gdb) n
[New Thread 21508.0x3c30]
Thread 1 "testing2" hit Hardware watchpoint 6: *(int *) 0xffffcbfc
Old value = 0
New value = 3840
Thread 1 "testing2" hit Breakpoint 7, main () at testing2.c:10
10 b = a;
gdb break since it detected the value has changed.