When trying the following in C :
g_string_printf(qbuf,"INSERT INTO inbox (number, smsdate, text) VALUES ('%s','%04d-%02d-%02d %02d:%02d:%02d', '%s')",
xmx.remote.number,
xmx.smsc_time.year,
xmx.smsc_time.month,
xmx.smsc_time.day,
xmx.smsc_time.hour,
xmx.smsc_time.minute,
xmx.smsc_time.second,
xmx.user_data[0].u.text);
I see the following crash:
Program received signal SIGSEGV, Segmentation fault.
0x00984809 in g_string_truncate () from /lib/libglib-2.0.so.0
(gdb)
Why would this happen? Is there any initiation before calling g_string_printf() ?
From frame 2:
(gdb) frame 2
#2 0x08049ba8 in fetching_phone (unit=0x807cd80) at main.c:152
152 g_string_printf(qbuf,"INSERT INTO inbox (number, smsdate, text) VALUES ('%s','%04d-%02d-%02d %02d:%02d:%02d', '%s')",
(gdb) ptype xmx.remote.number
type = char [40]
(gdb) ptype xmx.smsc_time.year
type = int
(gdb) ptype xmx.smsc_time.month
type = int
(gdb) ptype xmx.smsc_time.day
type = int
(gdb) ptype xmx.smsc_time.hour
type = int
(gdb) ptype xmx.smsc_time.minute
type = int
(gdb) ptype xmx.smsc_time.second
type = int
(gdb) ptype xmx.user_data[0].u.text
type = unsigned char [1601]
(gdb)
But, I still can't find where the problem is.
You probably have a bad pointer for the '%s' fields.
As you are running gdb, here is what you can do:
(gdb) bt
...trace...
# see the frame # of your call to g_string_printf()
(gdb) frame 5 # considering it was 5
(gdb) print xmx.remote.number
(gdb) print xmx.user_data[0].u.text
(gdb) print *xmx.remote.number
(gdb) print *xmx.user_data[0].u.text
or you can also check types (is xmx.remote.number a pointer ?)
(gdb) ptype xmx.remote.number
Did you initialize qbuf?
GString *qbuf = g_string_new("");
Related
Is there any way to extract variables that are being passed to a particular function as parameters in a given c code?
For an example,
main()
{
int a = 10;
float b = 2.0f;
funcA(a,b);
}
Need is to extract the information that variable a & variable b are passed to funcA in a given C code.
Is there a way to extract these information using gdb and it's function breakpoints?
when you are in any function typing frame will give you parameters information of function.
Below are some other commands you can use to get to know more about local variables and parameters.
info locals
frame
info args
more gdb commands
sample :
(gdb) b main
Note: breakpoint 1 also set at pc 0x40053e.
Breakpoint 2 at 0x40053e: file main.c, line 6.
(gdb) r
Starting program: /home/a.out
Breakpoint 1, main () at main.c:6
6 int a = 10;
(gdb) n
7 float b = 2.0f;
(gdb) info locals
a = 10
b = 0
x = 0
(gdb) frame
#0 main () at main.c:7
7 float b = 2.0f;
(gdb) next
9 int x = funcA(a,b);
(gdb) step
funcA (a=10, b=2) at main.c:16
16 int sum = 0;
(gdb) frame
#0 funcA (a=10, b=2) at main.c:16
16 int sum = 0;
(gdb) info args
a = 10
b = 2
(gdb) info locals
sum = 0
(gdb) p a
$1 = 10
(gdb) print b
$2 = 2
(gdb)
i need the address of a particular array, i obtained other array's addresses with success but in this one i got stuck.. here is the main code:
int main(int argc, char** argv) {
string[0] = 0;
char polpetta[]="secret-file";
char buf[50] ;
printf("me Can I read the secret file?! \n\n");
if (argc > 2) {
vuln(argv[1]);
strcpy(buf, argv[2]) ;
} else {
printf("You forgot to read me!!!\n");
}
return 0;
}
ok i put the breakpoint after the first printf:
(gdb) b* 0x080485f3
Breakpoint 1 at 0x80485f3
(gdb) r 12 12
Starting program: /home/andrew/Desktop/Software-Security-Lab/rop/rop-vuln
me Can I read the secret file?!
Breakpoint 1, 0x080485f3 in main ()
(gdb) p &buf
$1 = (char **) 0xb7fb9ef0 <buf>
(gdb) p &polpetta
No symbol "polpetta" in current context.
ok i obtained with success the address of buf... but not the address of polpetta! so i tried with different methods:
(gdb) p $polpetta
$2 = void
(gdb) p &$polpetta
Attempt to take address of value not located in memory.
(gdb) p polpetta
No symbol "polpetta" in current context.
(gdb) info locals
No symbol table info available.
(gdb) p *polpetta
No symbol "polpetta" in current context.
what the hell?? i also tried to repeat this routine at different breakpoints inside the main function...
thanks for your kindness!
When I executed the following code:
AVFrameSideData* avfsd=NULL;
avfsd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);
if(avfsd->data != NULL)
printf("avfsd->data != NULL\n");
I got a segmentation fault. It seemed to me that avfsd is not allowed to access data field. But when I look up the documentation of AVFrameSideData, I found:
typedef struct AVFrameSideData {
enum AVFrameSideDataType type;
uint8_t *data;
int size;
AVDictionary *metadata;
} AVFrameSideData;
why can't I access unint8_t *data through: avfsd->data? Frankly, avfsd is not Null. The following is some debugging infomation:
(gdb) print avfsd
$5 = <optimized out>
(gdb) print *avfsd
value has been optimized out
(gdb) print avfsd->data
value has been optimized out
(gdb) print frame->side_data
$6 = (AVFrameSideData **) 0x1bc4000
Btw, is the data here the data of motion vector of the frame? Why is it so short: see what I got from gdb:
(gdb) print frame->side_data[0]->type
$2 = AV_FRAME_DATA_MOTION_VECTORS
(gdb) print frame->side_data[0]->data
$1 = (uint8_t *) 0x1c32540 "\377\377\377\377\020\020\006"
I thought motion vector should be kind of a long chain. But from above...why is it that short?
I see some value in some place, but unsure where it has originated in my program. How do I figure out where this value initially comes from?
I expect the following event types to be logged:
A value originated from constant, arithmetical expression or syscall - the initial event;
The value was assigned to (or retrieved from) some variable;
The value was passed as an argument or returned from some function;
The value was stored to (or retrieved from) some struct;
By annotating source code with something specific, I triggered the history dump for this value.
For example, for this sample code:
#include <stdlib.h>
struct SomeStruct {
int a;
int b;
};
struct SomeStruct *globalvar;
int f1(struct SomeStruct* par) {
return par->a;
}
int f2(struct SomeStruct* par, int q) {
par->a = q;
return par->b;
}
void trace_value(int g) {} /* dummy */
int main(void) {
int f = 31337;
globalvar = malloc(sizeof(*globalvar));
f2(globalvar, f);
struct SomeStruct q = *globalvar;
int g = f1(&q);
trace_value(g);
return 0;
}
it should return something like
value 31337 originated from constant at fate.c:18
assigned to variable at fate.c:18
retrieved from variable at fate.c:21
passed as argument to function at fate.c:21
received as arument to a function at fate.c:12
assigned to struct field at fate.c:13
copied as a part of struct at fate.c:22
retrieved from struct field at fate.c:9
returned from function at fate.c:10
assigned to variable at fate.c:23
retrieved from variable at fate.c:25
traced at fate.c:25
How do I do this or something similar? I expect Valgrind or GDB or some combination should be able to do this.
Combined idea1 of using reverse gdb and idea2 from MarkPlotnick's comment of using gdb watchpoints. Here is the demo session, more complete than in original answer:
$ gcc -ggdb -Dtrace_value=exit fate.c -o fate
$ gdb -quiet -args ./fate
Reading symbols from /home/vi/code/_/fate...done.
(gdb) break main
Breakpoint 1 at 0x8048482: file fate.c, line 18.
(gdb) r
Starting program: /home/vi/code/_/fate
warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Breakpoint 1, main () at fate.c:18
18 int f = 31337;
(gdb) record
(gdb) break 25
(gdb) # traced at fate.c:25
Breakpoint 2 at 0x80484d2: file fate.c, line 25.
(gdb) c
Continuing.
Breakpoint 2, main () at fate.c:25
25 trace_value(g);
(gdb) # retrieved from variable at fate.c:25
(gdb) watch g
Hardware watchpoint 3: g
(gdb) reverse-continue
Continuing.
Hardware watchpoint 3: g
Old value = 31337
New value = 134513899
0x080484ce in main () at fate.c:23
23 int g = f1(&q);
(gdb) # assigned to variable at fate.c:23
(gdb) # returned from function at fate.c:10
(gdb) reverse-step
f1 (par=0xffffd670) at fate.c:10
10 }
(gdb) list
5
6 struct SomeStruct *globalvar;
7
8 int f1(struct SomeStruct* par) {
9 return par->a;
10 }
11
12 int f2(struct SomeStruct* par, int q) {
13 par->a = q;
14 return par->b;
(gdb) # retrieved from struct field at fate.c:9
(gdb) print par
$3 = (struct SomeStruct *) 0xffffd670
(gdb) print ((struct SomeStruct *) 0xffffd670)->a
$4 = 31337
(gdb) watch ((struct SomeStruct *) 0xffffd670)->a
Hardware watchpoint 4: ((struct SomeStruct *) 0xffffd670)->a
(gdb) reverse-continue
Continuing.
Hardware watchpoint 4: ((struct SomeStruct *) 0xffffd670)->a
Old value = 31337
New value = -134716508
0x080484ba in main () at fate.c:22
22 struct SomeStruct q = *globalvar;
(gdb) # copied as a part of struct at fate.c:22
(gdb) print globalvar->a
$5 = 31337
(gdb) watch globalvar->a
Hardware watchpoint 5: globalvar->a
(gdb) reverse-continue
Continuing.
Hardware watchpoint 5: globalvar->a
Old value = 31337
New value = 0
0x0804846f in f2 (par=0x804a008, q=31337) at fate.c:13
13 par->a = q;
(gdb) # assigned to struct field at fate.c:13
(gdb) # received as arument to a function at fate.c:12
(gdb) list
8 int f1(struct SomeStruct* par) {
9 return par->a;
10 }
11
12 int f2(struct SomeStruct* par, int q) {
13 par->a = q;
14 return par->b;
15 }
16
17 int main() {
(gdb) bt
#0 0x0804846f in f2 (par=0x804a008, q=31337) at fate.c:13
#1 0x080484b0 in main () at fate.c:21
(gdb) reverse-finish
Run back to call of #0 0x0804846f in f2 (par=0x804a008, q=31337) at fate.c:13
0x080484ab in main () at fate.c:21
21 f2(globalvar, f);
(gdb) # passed as argument to function at fate.c:21
(gdb) # retrieved from variable at fate.c:21
(gdb) watch f
Hardware watchpoint 6: f
(gdb) reverse-finish
"finish" not meaningful in the outermost frame.
(gdb) reverse-continue
Continuing.
Warning:
Could not insert hardware watchpoint 6.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) watch f
Hardware watchpoint 7: f
(gdb) reverse-continue
Continuing.
No more reverse-execution history.
main () at fate.c:18
18 int f = 31337;
(gdb) # assigned to variable at fate.c:18
(gdb) # value 31337 originated from constant at fate.c:18
All expected messages in the question statement correspond to some info you have seen in gdb output (as shown in comments).
I believe it could be accomplished manually (i.e. running on gdb session) in runtime by technique called "reverse debugging". I haven't tried it yet, but GDB version 7.0 documentation claims, that it is supported on some platforms.
The method would be something like:
localize single step where variable is used in the last place (that is, your "starting point")
analyze source code (so you need debugging symbol and code section available) of stack frame (e.g. by list), so you get how this value is obtained (or possibly modified) witihin (e.g. from parameter passed to function)
step back to previous stack frame and repeat from previous step unless you find its origin
Here is some proof-of-concept session for your sample code. I edited it a bit, as trace_value function was undefined. Note that record command may heavily slow down program's execution.
$ gdb -q a.out
Reading symbols from /home/grzegorz/workspace/a.out...done.
(gdb) b main
Breakpoint 1 at 0x400502: file fate.c, line 22.
(gdb) run
Starting program: /home/grzegorz/workspace/a.out
Breakpoint 1, main () at fate.c:22
22 int f = 31337;
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.5.x86_64
(gdb) record
(gdb) b trace_value
Breakpoint 2 at 0x4004f8: file fate.c, line 19.
(gdb) c
Continuing.
Breakpoint 2, trace_value (g=31337) at fate.c:19
19 void trace_value(int g){}
(gdb) info args
g = 31337
(gdb) reverse-finish
Run back to call of #0 trace_value (g=31337) at fate.c:19
0x0000000000400550 in main () at fate.c:29
29 trace_value(g);
(gdb) bt
#0 0x0000000000400550 in main () at fate.c:29
(gdb) list 29
24 globalvar = malloc(sizeof(*globalvar));
25 f2(globalvar, f);
26 struct SomeStruct q = *globalvar;
27 int g = f1(&q);
28
29 trace_value(g);
30
31 return 0;
32 }
Few things maybe require some explanation. You need to set breakpoint for main at first, as this is when the program execution begins, then enable session recording by record command. Then set second breakpoint at trace_value function and use continue command (c in short). This allows you to record whole execution up to moment when trace_value is entered. You may think of it as this "starting point", described above.
This of course not the full story. As I described earlier you need to analyze source code of current stack frame an then decide what to do next. You may use reverse-step or reverse-finish command accordingly to current situation.
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.