so , I will to Understand debugging , i am very new and I am not a IT student.. .I am since Three Days this exercise to Understand , but without sucess...
I working with Linux and the Program GDB:
1 #include <string.h>
2 #include <stdio.h>
3
4 void overflowed() {
5 printf("%s\n", "Execution Hijacked");
6 }
7
8 void function1(char *str){
9 char buffer[5];
10 strcpy(buffer, str); (**3**)
11 } (**2**)
12 void main(int argc, char *argv[])
13 {
14 function1(argv[1]); (**1**)
15 printf("%s\n", "Executed normally");
16 }
The Number 1 , 2 , 3 are the Program Break Punkt .
(gdb) break 14
Breakpoint 1 at 0x8048433: file overflowtest.c, line 14.
(gdb) break 10
Breakpoint 2 at 0x804840e: file overflowtest.c, line 10.
(gdb) break 11
Breakpoint 3 at 0x8048420: file overflowtest.c, line 11.
Break the line 14,10 and 11 .
than with run to given Four A
(gdb) run AAAA
Starting program: /home/georgia/overflowtest AAAA
Breakpoint 1, main (argc=2, argv=0xbfb73004) at overflowtest.c:14
14 function(argv[1]);
than with x/16xw $esp to my First Break ,line 14 , i come
(gdb) x/16xw $esp
0xbfb72f50: 0xb77e6ff4 0x08049ff4 0xbfb72f78 0x08048489
0xbfb72f60: 0xb780a7b0 0xbfb72f80 0xbfb72fd8 0xb769e775
0xbfb72f70: 0x08048470 0x08048340 0xbfb72fd8 0xb769e775
0xbfb72f80: 0x00000002 0xbfb73004 0xbfb73010 0xb77fab40
so, i to search to Understand , what on the far left is 0xbfb72f50: and all Hex back from it come, his meaning.... . Can Please anybody help me with easy Words explain , to describe it ? , Very Thanks!
The first column is the address, that is, on the first line, the value of the %esp register.
For an explanation of the stack pointer (%esp) and stack frame (%ebp) registers, consult a text on compiler construction, such as chapter 6, Activation Records, in Appel's Modern compiler implementation in ML. Relevant keywords are activation records and stack frames. Wikipedia has some basic information, too.
So , How i Understande the Memory Adress on the far left :
0xbfb72f50:
0xbfb72f60:
0xbfb72f70:
0xbfb72f80:
are the stack framen where start my Three breakpoints ,but i don't know what the Fisrt Adress to do.... , sorry about this questions , but i am not a Student from IT ....i learn self to Home....
So , answer me self:
Far left are the Memory Adress and what First back to come are the Content-addressable memory , 0xb77e6ff4 is the ESP of the main ’s stack frame . ESP marks the lowest memory address of a Stack , EBP is the highest address , Here 0xbfb72f78 .
Related
I want to programmatically convert backtrace stack addresses (eg obtained from backtrace_symbols/libunwind) to file:line:column. I'm on OSX but doubt this makes a difference.
All of these give wrong line number (line 11) for the call to fun1():
atos
addr2line
llvm-symbolizer
lldb image lookup --address using lldb's pc addresses in bt
lldb bt itself gives correct file:line:column, (line 7) as shown below.
How do I programmatically get the correct stack address such that, when using atos/addr2line/llvm-symbolizer/image lookup --address, it would resolve to the correct line number? lldb bt is doing it correctly, so there must be a way to do it. Note that if I use backtrace_symbols or libunwind (subtracted from info.dli_saddr after calling dladdr), I'd end up with the same address 0x0000000100000f74 as shown in lldb bt that points to the wrong line number 11
Note: in .lldbinit, if I add settings set frame-format frame start-addr:${line.start-addr}\n it will show the correct address (ie resolve to 0x0000000100000f6f instead of 0x0000000100000f74, which will resolve to the correct line 7). However, how do I programmatically generate start-addr from a c program without calling spawning a call to lldb -p $pid (calling lldb has other issues, eg overhead compared to llvm-symbolizer, and in fact can hang forever even with -batch).
clang -g -o /tmp/z04 test_D20191123T162239.c
test_D20191123T162239.c:
void fun1(){
}
void fun1_aux(){
int a = 0;
fun1(); // line 7
mylabel:
if(1){
a++; // line 11
}
}
int main(int argc, char *argv[]) {
fun1_aux();
return 0;
}
lldb /tmp/z04
(lldb) target create "/tmp/z04"
Current executable set to '/tmp/z04' (x86_64).
(lldb) b fun1
Breakpoint 1: where = z04`fun1 + 4 at test_D20191123T162239.c:2:1, address = 0x0000000100000f54
(lldb) r
Process 7258 launched: '/tmp/z04' (x86_64)
Process 7258 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100000f54 z04 fun1 + 4 at test_D20191123T162239.c:2:1
1 void fun1(){
-> 2 }
3
4 void fun1_aux(){
5 int a = 0;
6
7 fun1();
Target 0: (z04) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000100000f54 z04 fun1 + 4 at test_D20191123T162239.c:2:1
frame #1: 0x0000000100000f74 z04 fun1_aux + 20 at test_D20191123T162239.c:7:3
frame #2: 0x0000000100000fab z04 main(argc=1, argv=0x00007ffeefbfb748) + 27 at test_D20191123T162239.c:16:3
frame #3: 0x00007fff71c182e5 libdyld.dylib start + 1
frame #4: 0x00007fff71c182e5 libdyld.dylib start + 1
(lldb)
(lldb) image lookup --address 0x0000000100000f74
Address: z04[0x0000000100000f74] (z04.__TEXT.__text + 36)
Summary: z04`fun1_aux + 20 at test_D20191123T162239.c:11:8
echo 0x0000000100000f74 | llvm-symbolizer -obj=/tmp/z04
fun1_aux
test_D20191123T162239.c:11:8
atos -o /tmp/z04 0x0000000100000f74
fun1_aux (in z04) (test_D20191123T162239.c:11)
likewise with addr2line
It's easier to understand if you look at the disassembly for fun1_aux -- you'll see a CALLQ instruction to fun1, followed by something like a mov %rax, $rbp-16 or something like that, the first instruction of your a++ line. When you have called fun1, the return address is the instruction that will be executed when fun1 exits, the mov %rax, $rbp-16 or whatever.
This isn't intuitively how most people think of the computer working -- they expect to look at frame 1, fun1_aux, and see the "current pc value" be the CALLQ, because the call is executing. But of course, that's not correct, the call instruction has completed, and the saved pc is going to point to the next instruction.
In cases like this, the next instruction is part of the next source line, so it's a little extra confusing. Even better is if you have a function that calls a "noreturn" function like abort() -- the final instruction in the function will be a CALLQ, and if you look at the return address instruction, it may point to the next function.
So when lldb is symbolicating stack frames above frame #0, it knows to do a symbol lookup with saved_pc - 1 to move the address back into the CALLQ instruction. That's not a valid address, so it should never show you saved_pc - 1, but it should do symbol / file & line lookups based on it.
You can get the same effect for your manual symbolication by doing the same thing. The one caveat is if you have an asynchronous interrupt (_sigtramp on macOS), the frame above _sigtramp should not have its saved pc value decremented. You could be executing the first instruction of a function when the signal is received, and decrementing it would put you in the previous function which would be very confusing.
I'm trying to migrate a small c program from hpux to linux. The project compiles fine but crashes at runtime showing me a segmentation fault. I've already tried to see behind the mirror using strace and gdb but still don't understand. The relevant (truncated) parts:
tts_send_2.c
Contains a method
int sequenznummernabgleich(int sockfd, char *snd_id, char *rec_id, int timeout_quit) {
TS_TEL_TAB tel_tab_S01;
int n;
# truncated
}
which is called from within that file like this:
. . .
. . .
switch(sequenznummernabgleich(sockfd,c_snd_id,c_rec_id,c_timeout_quit)) {
/* kritischer Fehler */
case -1:
. . .
. . .
when calling that method I'm presented a segmentation fault (gdb output):
Program received signal SIGSEGV, Segmentation fault.
0x0000000000403226 in sequenznummernabgleich (sockfd=<error reading variable: Cannot access memory at address 0x7fffff62f94c>,
snd_id=<error reading variable: Cannot access memory at address 0x7fffff62f940>, rec_id=<error reading variable: Cannot access memory at address 0x7fffff62f938>,
timeout_quit=<error reading variable: Cannot access memory at address 0x7fffff62f934>) at tts_snd_2.c:498
498 int sequenznummernabgleich(int sockfd, char *snd_id, char *rec_id, int timeout_quit) {
which I just don't understand. When I'm stepping to the line where the method is called using gdb, all the variables are looking fine:
1008 switch(sequenznummernabgleich(sockfd,c_snd_id,c_rec_id,c_timeout_quit)) {
(gdb) p sockfd
$9 = 8
(gdb) p &sockfd
$10 = (int *) 0x611024 <sockfd>
(gdb) p c_snd_id
$11 = "KR", '\000' <repeats 253 times>
(gdb) p &c_snd_id
$12 = (char (*)[256]) 0xfde220 <c_snd_id>
(gdb) p c_rec_id
$13 = "CO", '\000' <repeats 253 times>
(gdb) p &c_rec_id
$14 = (char (*)[256]) 0xfde560 <c_rec_id>
(gdb) p c_timeout_quit
$15 = 20
(gdb) p &c_timeout_quit
$16 = (int *) 0xfde660 <c_timeout_quit>
I've also created an strace output. Here's the last part concerning the code shown above:
strace output
Any ideas ? I've searched the web and of course stackoverflow for hours without finding a really similar case.
Thanks
Kriz
I haven't used an HP/UX in eons but do hazily remember enough for the following suggestions:
Make sure you're initializing variables / struts correctly. Use calloc instead of malloc.
Also don't assume a specific bit pattern order: eg low byte then high byte. Ska endian-ness of the machine. There are usually macros in the compiler that will handle the appropriate ordering for you.
Update 15.10.16
After debugging for even more hours I found the real Problem. On the first line of the Method "sequenznummernabgleich" is a declaration of a struct
TS_TEL_TAB tel_tab_S01;
This is defined as following:
typedef struct {
TS_BOF_REC bof;
TS_REM_REC rem;
TS_EOF_REC eof;
int bof_len;
int rem_len;
int eof_len;
int cnt;
char teltyp[LEN_TELTYP+1];
TS_TEL_ENTRY entries[MAX_TEL];
} TS_TEL_TAB;
and it's embedded struct TS_TEL_ENTRY
typedef struct {
int len;
char tel[MAX_TEL_LEN];
} TS_TEL_ENTRY;
The problem is that the value for MAX_TEL_LEN had been changed from 512 to 1024 and thus the struct almost doubled in size what lead to that the STACK SIZE was not big enough anymore.
SOLUTION
Simply set the stack size from 8Mb to 64Mb. This can be achieved using ulimit command (under linux).
List current stack size: ulimit -s
Set stack size to 64Mb: ulimit -s 65535
Note: Values for stack size are in kB.
For a good short ref on ulimit command have a look # ss64
I'm new to reverse engeneering. I wrote the following C code to help me understand a bit more about stack frames.
#include <stdio.h>
int sum(int a, int b,int c)
{
return(a+b+c);
}
int media(int a, int b,int c)
{
int total;
total = a + b + c;
return (total/3);
}
int main ()
{
int num1,num2,num3;
char keypress[1];
num1 = 5;
num2 = 10;
num3 = 15;
printf ("\nCalling sum function\n");
sum(num1,num2,num3);
printf ("\nWaiting a keypress to call media function\n");
scanf ("%c",keypress);
media(num1,num2,num3);
printf ("\nWaiting a keypress to end\n");
scanf ("%c",keypress);
return(0);
}
As far as I know every time you call a function
a stack frame is created (see: ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_41.html). So, my goal with the above C code is to see, at least, three stack-frames.
1) main function - stack frame
2) sum function - stack frame
3) media function - stack frame
BTW: Those printfs are just to help me 'follow' the program in gdb. =)
So I guess if I compare the output of info frame after the program started with the output of info frame just after sum function is called I would get different output right? I did not got it as you can see:
Temporary breakpoint 1, main () at parastack.c:27
warning: Source file is more recent than executable.
27 num1 = 5;
(gdb) nexti
28 num2 = 10;
(gdb) info frame
Stack level 0, frame at 0x7fffffffdf00:
rip = 0x400605 in main (parastack.c:28); saved rip = 0x7ffff7a3c790
source language c.
Arglist at 0x7fffffffdef0, args:
Locals at 0x7fffffffdef0, Previous frame's sp is 0x7fffffffdf00
Saved registers:
rbp at 0x7fffffffdef0, rip at 0x7fffffffdef8
(gdb) nexti
29 num3 = 15;
(gdb) nexti
31 printf ("\nCalling sum function\n");
(gdb) nexti
0x0000000000400618 31 printf ("\nCalling sum function\n");
(gdb) nexti
Calling sum function
32 sum(num1,num2,num3);
(gdb) info frame
Stack level 0, frame at 0x7fffffffdf00:
rip = 0x40061d in main (parastack.c:32); saved rip = 0x7ffff7a3c790
source language c.
Arglist at 0x7fffffffdef0, args:
Locals at 0x7fffffffdef0, Previous frame's sp is 0x7fffffffdf00
Saved registers:
rbp at 0x7fffffffdef0, rip at 0x7fffffffdef8
(gdb) nexti
0x0000000000400620 32 sum(num1,num2,num3);
(gdb) info frame
Stack level 0, frame at 0x7fffffffdf00:
rip = 0x400620 in main (parastack.c:32); saved rip = 0x7ffff7a3c790
source language c.
Arglist at 0x7fffffffdef0, args:
Locals at 0x7fffffffdef0, Previous frame's sp is 0x7fffffffdf00
Saved registers:
rbp at 0x7fffffffdef0, rip at 0x7fffffffdef8
just after sum function is called
Your problem is that you never actually stopped inside of the sum function. You stopped after you printed that you are about to call it, and then you stepped a few instructions, but you never actually landed inside (it takes a few instructions to prepare arguments, one more to actually call, and few more inside the function to set up the frame).
You should start by setting breakpoints inside sum and media, and doing info frame when these breakpoints are hit. You'll notice that the breakpoint is set a few instructions after the beginning of the function (i.e. after function prolog). The skipped instructions are exactly the ones that set up the new frame.
After you understand how that works, you should progress to using step and next commands.
And after that you can graduate to using disas, stepi and nexti commands.
Based on my interpretation of your prose, your understanding of stack frames is slightly off. You are correct that when a function is called a stack frame is created, however, what you're missing is that when a function returns, the stack frame is popped. The stack is in the same state is was before the function began executing except that the program counter contains the address of the first instruction of the statement immediately following the function that just finished executing. So, you should not expect to see 3 stack frames after the two functions in main execute. You will only see one since you're only one frame deep into main().
As for the gdb session, as #Employed Russian points out, you never actually step into any function when printing the stack frame information.
Thanks for everyone that helped me. Below are the gdb session with shows that the stack-frame changed.
First I recompiled the C code: gcc -ggdb stack.c -o stack.bin
gdb stack.bin
(gdb) break sum
(gdb) start
(gdb) info frame
Stack level 0, frame at 0x7fffffffe1a0:
rip = 0x400653 in main (stack.c:26); saved rip 0x7ffff7a6fead
source language c.
Arglist at 0x7fffffffe190, args:
Locals at 0x7fffffffe190, Previous frame's sp is 0x7fffffffe1a0
Saved registers:
rbp at 0x7fffffffe190, rip at 0x7fffffffe198
(gdb) continue
Continuing.
Calling sum function
Breakpoint 1, sum (a=5, b=10, c=15) at stack.c:6
6 total = a + b + c;
(gdb) info frame
Stack level 0, frame at 0x7fffffffe180:
rip = 0x4005dd in sum (stack.c:6); saved rip 0x400684
called by frame at 0x7fffffffe1a0
source language c.
Arglist at 0x7fffffffe170, args: a=5, b=10, c=15
Locals at 0x7fffffffe170, Previous frame's sp is 0x7fffffffe180
Saved registers:
rbp at 0x7fffffffe170, rip at 0x7fffffffe178
Now I will search/learn more about the information in the output.
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.
I like to make GDB set a break point when a variable equal some value I set, I tried this example:
#include <stdio.h>
main()
{
int i = 0;
for(i=0;i<7;++i)
printf("%d\n", i);
return 0;
}
Output from GDB:
(gdb) break if ((int)i == 5)
No default breakpoint address now.
(gdb) run
Starting program: /home/SIFE/run
0
1
2
3
4
5
6
Program exited normally.
(gdb)
Like you see, GDB didn't make any break point, is this possible with GDB?
in addition to a watchpoint nested inside a breakpoint
you can also set a single breakpoint on the 'filename:line_number' and use a condition.
I find it sometimes easier.
(gdb) break iter.c:6 if i == 5
Breakpoint 2 at 0x4004dc: file iter.c, line 6.
(gdb) c
Continuing.
0
1
2
3
4
Breakpoint 2, main () at iter.c:6
6 printf("%d\n", i);
If like me you get tired of line numbers changing, you can add a label
then set the breakpoint on the label like so:
#include <stdio.h>
main()
{
int i = 0;
for(i=0;i<7;++i) {
looping:
printf("%d\n", i);
}
return 0;
}
(gdb) break main:looping if i == 5
You can use a watchpoint for this (A breakpoint on data instead of code).
You can start by using watch i.
Then set a condition for it using condition <breakpoint num> i == 5
You can get the breakpoint number by using info watch
First, you need to compile your code with appropriate flags, enabling debug into code.
$ gcc -Wall -g -ggdb -o ex1 ex1.c
then just run you code with your favourite debugger
$ gdb ./ex1
show me the code.
(gdb) list
1 #include <stdio.h>
2 int main(void)
3 {
4 int i = 0;
5 for(i=0;i<7;++i)
6 printf("%d\n", i);
7
8 return 0;
9 }
break on lines 5 and looks if i == 5.
(gdb) b 5
Breakpoint 1 at 0x4004fb: file ex1.c, line 5.
(gdb) rwatch i if i==5
Hardware read watchpoint 5: i
checking breakpoints
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004004fb in main at ex1.c:5
breakpoint already hit 1 time
5 read watchpoint keep y i
stop only if i==5
running the program
(gdb) c
Continuing.
0
1
2
3
4
Hardware read watchpoint 5: i
Value = 5
0x0000000000400523 in main () at ex1.c:5
5 for(i=0;i<7;++i)
There are hardware and software watchpoints. They are for reading and for writing a variable. You need to consult a tutorial:
http://www.unknownroad.com/rtfm/gdbtut/gdbwatch.html
To set a watchpoint, first you need to break the code into a place where the varianle i is present in the environment, and set the watchpoint.
watch command is used to set a watchpoit for writing, while rwatch for reading, and awatch for reading/writing.