Monday, April 26, 2010

summary of the assemble code map in gcc

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.  

General program bugs

  • Buffer overflow

  • Use After free:
Volatile stack
For example, return a pointer on a stack.
  • Memory leak:
mtrace

  • Double free

  • Free unallocated memory
char* string="abcdef";
free string;

  • Heap overflow
p=malloc(strnlen(mystr,MAX_LENGTH)
strncpy(p,mystr,MAX_LENGTH)

use mcheck and mprobe MALLOC_CHECK_

  • Race condition
static int count=0;

count++;
(1) Read into register
(2) increase to one
(3) write back the new value into memory

  • Deadlock
PTHREAD_MUTEX_ERROR_CHECK

  • Compiler optimization
volatile: slow, only option for hardware parameters

memory barrier
asm volatile ("" : : : "memory")
write back all the data from register back to the memory. 

  • CPU optimization
hardware memory barrier

  • Signal Handler
cannot be blocked using locks

  • Tips for troubleshooting
Write to system log /var/log/messages
(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
(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 | 0x00c331ab
dump the symobl information
objdump -Dt /usr/sbin/squid > squid.dis

Then look for 
0x00c331ab
inside squid.dis
 

Tuesday, April 20, 2010

GDB cheat sheet

Here is the cheat sheet for GDB in Linux
  • Enable the core file
% ulimit -a
% ulimit -c 500000

Set maximum core file size to 500K.

  • List all  proc information and function list
(gdb) info proc
(gdb) info functions

  • Disasseeble
(gdb) disass main

  • Display and clear breakpoints
(gdb) info breakpoints
(gdb) delete breakpoints 1
  • Watching it live
(gdb) break 188
(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.
(gdb)  watch *((int*)0xABCDEF)

As an simple example:
define cls
shell clear
end
document cls
clears screen for gdb
end

Example Macros for STL debugging


  • Handle Signal
(gdb) i handle
(gdb) i signal
(gdb) handle SIG32 nostop print pass

  • Multiple threads
(gdb) b foo.cpp:13 thread 28 if x>lim

  • Remote debugging
Server side: gdbserver:9999 -attach pid
Client side: gdb program
(gdb) handle SIGTRAP nonstop noprint pass
(gdb) target remote gdbserverip:9999

  • Store history
Convenience variables:
(gdb) set $table=*table_ptr
(gdb) show conv

Checkpoint
(gdb) checkpoint
(gdb) i checkpoint
(gdb) restart checkpoint-id


  • See Macros in program
g++ -gdwarf-2 -g3 a.cpp

  • Why the program is stopped
(gdb) i prog

  • exit a loop
(gdb) until line-no
  • print, info, show
print: print value of expression
info: show things about the program being debugged
show: show things about the debugger

Monday, April 19, 2010

Aho Corasic algorithm

Here is the implementation of the Aho Corasic algoirthm in C++. It can be used to handle the ClamAV signature. CPP file and H file

Thursday, April 15, 2010

code review lesson learned

Just had some code review and got a lot of comments:
  1.  mis-spell in comments. I should use the a spell check add-in
  2. copy and paste others code without change the styles
  3. use the const function whenever possible
  4. use std::string::empty() instead of compare with empty string
  5. include all dependent header in the header definition vs. depending on the cpp file include sequence.
  6. 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.

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);}