The gcc function call stack layout looks like this (from high address to low address):
Grand Parent ebp ----> Parameters ----> parent return address ---> parent ebp ---> Local variables
Assume that you will call
m=foo("abcdef")
And it will be disassembled as
a) push 0x422dfsf ; This is the address store "abcdef"
b) call foo; when this is called, the parent instruction address in c) will be on the stack
c) add 0x4 %esp; pop up the parameter pushed into after call
e) mov %eax, 0xfffffffc(%ebp); the return value is in the %eax, and it will be assigned to the local variable
In foo() function
a) push %ebp; save parent ebp
b) move %esp, %ebp; now point to new ebp
c) sub 0x4, %eps; move ebps to allocate the space for local variables.
...
d) move 0xfffffffc(%ebp), %eax; store the function return result into the %eax
e) leave
f) ret; change the eps to point to the parameters at 8(%ebp), set eip (instruction pointer) to parent return address 4(%ebp), set ebp to parent ebp.
Monday, April 26, 2010
General program bugs
- Buffer overflow
- Use After free:
For example, return a pointer on a stack.
- Memory leak:
- Double free
- Free unallocated memory
free string;
- Heap overflow
strncpy(p,mystr,MAX_LENGTH)
use mcheck and mprobe MALLOC_CHECK_
- Race condition
count++;
(1) Read into register
(2) increase to one
(3) write back the new value into memory
- Deadlock
- Compiler optimization
memory barrier
asm volatile ("" : : : "memory")
write back all the data from register back to the memory.
- CPU optimization
- Signal Handler
- Tips for troubleshooting
(bash) logger -p err "test"
syslog()
change syslog level by modify the /etc/syslog.conf
disable assert() using NDEBUG
Function to print backtrace
#include
int backtrace(int **buffer, int size)
POSIX threads trace toolkit
use ar to create static library and ln to create a dynamic library
Thursday, April 22, 2010
Rebuild backtrace of GDB
Sometimes the GDB had a corrupt backtrace, which has to be rebuilt. Here is an example:
find out the stack base pointer
examine 2048 bytes in hex format for the memory around that address
(gdb) x/2048h 0xbf9ef358
objdump -Dt /usr/sbin/squid > squid.dis
Then look for
find out the stack base pointer
(gdb) info reg ebp
ebp 0xbf9ef358 0xbf9ef358
examine 2048 bytes in hex format for the memory around that address
(gdb) x/2048h 0xbf9ef358
0xbf9ef358: 0xbf9ef388 0x00d94cf7 0x0a85e988 0x00000024 0xbf9ef368: 0xbf9ef388 0x00d94d8a 0x00000000 0x05000000 0xbf9ef378: 0x00000000 0x0a85e994 0x00000000 0x0a86dacc 0xbf9ef388: 0xbf9ef418 0x00c331ab 0x0a85e994 0x00000015 0xbf9ef398: 0x00000000 0xb7800000 0x0992f188 0xbf9ef40c
So you have stack:
StackFrame | Instruction Pointer | Pointer ------------------------ 0xbf9ef388 | 0x00d94cf7
0xbf9ef418 | 0x00c331abdump the symobl information
objdump -Dt /usr/sbin/squid > squid.dis
Then look for
0x00c331abinside squid.dis
Tuesday, April 20, 2010
GDB cheat sheet
Here is the cheat sheet for GDB in Linux
% ulimit -c 500000
Set maximum core file size to 500K.
(gdb) info functions
(gdb) delete breakpoints 1
(gdb) commands 1
print variable
continue
end
Note: break at 188 lines and then set a group of commands at break point 1.
define cls
shell clear
end
document cls
clears screen for gdb
end
Example Macros for STL debugging.
(gdb) i signal
(gdb) handle SIG32 nostop print pass
Client side: gdb program
(gdb) handle SIGTRAP nonstop noprint pass
(gdb) target remote gdbserverip:9999
(gdb) set $table=*table_ptr
(gdb) show conv
Checkpoint
(gdb) checkpoint
(gdb) i checkpoint
(gdb) restart checkpoint-id
info: show things about the program being debugged
show: show things about the debugger
- Enable the core file
% ulimit -c 500000
Set maximum core file size to 500K.
- List all proc information and function list
(gdb) info functions
- Disasseeble
- Display and clear breakpoints
(gdb) delete breakpoints 1
- Watching it live
(gdb) commands 1
print variable
continue
end
Note: break at 188 lines and then set a group of commands at break point 1.
- Break when a specific address is accessed. Refer to this article.
- Define in macro and alias in ~/.gdbinit A good article about it.
define cls
shell clear
end
document cls
clears screen for gdb
end
Example Macros for STL debugging.
- Handle Signal
(gdb) i signal
(gdb) handle SIG32 nostop print pass
- Multiple threads
- Remote debugging
Client side: gdb program
(gdb) handle SIGTRAP nonstop noprint pass
(gdb) target remote gdbserverip:9999
- Store history
(gdb) set $table=*table_ptr
(gdb) show conv
Checkpoint
(gdb) checkpoint
(gdb) i checkpoint
(gdb) restart checkpoint-id
- See Macros in program
- Why the program is stopped
- exit a loop
- print, info, show
info: show things about the program being debugged
show: show things about the debugger
Monday, April 19, 2010
Aho Corasic algorithm
Thursday, April 15, 2010
code review lesson learned
Just had some code review and got a lot of comments:
- mis-spell in comments. I should use the a spell check add-in
- copy and paste others code without change the styles
- use the const function whenever possible
- use std::string::empty() instead of compare with empty string
- include all dependent header in the header definition vs. depending on the cpp file include sequence.
- pay more attention to resource release, return true/false path even if most did not matter.
Tuesday, April 13, 2010
Detect OpenSSL errors
I want to detect detail openSSL client certificate error after call SSL_accept(). This can be found from the reason:
Unknown Client CA: SSL_R_TLSV1_ALERT_UNKNOWN_CA
No Client Certificate: SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE
Certificate expired: SSL_R_NO_CERTIFICATE_RETURNED
The interesting is when client certificate is expired, it did not return SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED, instead, it returns SSL_R_NO_CERTIFICATE_RETURNED.
Unknown Client CA: SSL_R_TLSV1_ALERT_UNKNOWN_CA
No Client Certificate: SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE
Certificate expired: SSL_R_NO_CERTIFICATE_RETURNED
The interesting is when client certificate is expired, it did not return SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED, instead, it returns SSL_R_NO_CERTIFICATE_RETURNED.
Monday, April 5, 2010
A simple self replicate code (quine)
Here is a simple self replicate C code:
main(){char* s="main(){char* s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
main(){char* s="main(){char* s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
Subscribe to:
Posts (Atom)