2015年2月20日 星期五

[Embedded] 一個練習組合語言的小遊戲 -- Defusing bomb (part 2)

遊戲說明請參考  http://wiki.csie.ncku.edu.tw/embedded/Lab34。


以下記錄自己的解答方式。本篇僅紀錄 part2 的解法,透過此練習可學得如何利用 stack overflow 來執行 shellcode。

[Embedded] 一個練習組合語言的小遊戲 -- Defusing bomb (part 1)

此遊戲的設計目的是要讓使用者學會利用 gdb 與 objdump 分析執行檔,並學習 hack 程式!!!! 遊戲說明請參考  http://wiki.csie.ncku.edu.tw/embedded/Lab34。

以下記錄自己的解答方式。本篇僅紀錄 part1 的解法,簡單來說就是使用gdb找出正確輸入值,避免程式進入 explode_bomb()。

2015年2月7日 星期六

[Embedded] GDB script -- generate a basic report per core file

wikibook 針對 core dump 使用,提供了幾個有用的 script,其中有個自動產生報表的方式對我幫助很大。摘錄如下:


#!/bin/bash

#
# A script to extract core-file informations
#


if [ $# -ne 1 ]
then
echo "Usage: `basename $0` "
exit -1
else
binimg=$1
fi


# Today and yesterdays cores
cores=`find . -name '*.core' -mtime -1`

#cores=`find . -name '*.core'`


for core in $cores
do
gdblogfile="$core-gdb.log"
rm $gdblogfile

bininfo=`ls -l $binimg`
coreinfo=`ls -l $core`

gdb -batch \
-ex "set logging file $gdblogfile" \
-ex "set logging on" \
-ex "set pagination off" \
-ex "printf \"**\n** Process info for $binimg - $core \n** Generated `date`\n\"" \
-ex "printf \"**\n** $bininfo \n** $coreinfo\n**\n\"" \
-ex "file $binimg" \
-ex "core-file $core" \
-ex "bt" \
-ex "info proc" \
-ex "printf \"*\n* Libraries \n*\n\"" \
-ex "info sharedlib" \
-ex "printf \"*\n* Memory map \n*\n\"" \
-ex "info target" \
-ex "printf \"*\n* Registers \n*\n\"" \
-ex "info registers" \
-ex "printf \"*\n* Current instructions \n*\n\"" -ex "x/16i \$pc" \
-ex "printf \"*\n* Threads (full) \n*\n\"" \
-ex "info threads" \
-ex "bt" \
-ex "thread apply all bt full" \
-ex "printf \"*\n* Threads (basic) \n*\n\"" \
-ex "info threads" \
-ex "thread apply all bt" \
-ex "printf \"*\n* Done \n*\n\"" \
-ex "quit"
done

Reference:
http://en.m.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/Core_files

2015年2月6日 星期五

[Embedded] GDB script -- check stack when stack corrupt

若使用 gdb 檢查 core dump 時,發現 stack corrupt,此時該如何看到正確的 stack trace 呢?

問題情況舉例如下:(使用 stackoverflow 的例子做說明)

Program received signal SIGSEGV, Segmentation fault.
0x00000002 in ?? ()
(gdb) bt
#0  0x00000002 in ?? ()
#1  0x00000001 in ?? ()
#2  0xbffff284 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

問題解決方式:(假設系統架構為 Linux 32-bit x86)

1. 首先必須先大概了解 Linux 作業系統內的虛擬記憶體配置
例如:
stack 會位於 0xBFxxxxxx 附近
text (程式碼) 會從 0x08048000 開始增加
因此 0xbffff284可能是正確的 stack位址,而 0x00000001 與 0x00000002 並非正確的 stack 位址,此時 stack 已經亂掉。
若對於 stack 使用有疑問,可以直接參考此範例。 

2. 以上述的錯誤位址為例,這個問題有可能因為呼叫function 時,指向了錯誤的 function pointer。
An indirect call instruction just pushes the PC after the call onto the stack and then sets the PC to the target value (bogus in this case), so if this is what happened, you can easily undo it by manually popping the PC off the stack. In 32-bit x86 code you just do:

(gdb) set $pc = *(void **)$sp
(gdb) set $sp = $sp + 4

3. 另外一個可能是正確的 stack 被覆蓋了。此時基本處理原則是將整個 stack 都尋找一遍,直到找到對應的程式進入點為止 (例如:main())。
例如: (gdb) x/256wa $sp 
其基本原理為從目前的 sp register 開始,每隔一個 word(4bytes),印出對應的位址,若有對應的 symbol 會一併列印,持續尋找 256 words。

4. 若想要將 stack 狀態寫入檔案,可以參考 Loda's blog 的 GDB 筆記,其基本原理與 x/256wa $sp 相同,不過產生出的 log 較方便閱讀。摘錄如下:
file executable_file_build_with_debug_flag
set solib-search-path builtin-symbol-library-file-path
set solib-absolute-prefix builtin-symbol-library-filepath-prefix
core core_dump_file
set print symbol-filename on
set logging file stack-out.txt
set logging on
set $stack_addr=$sp
printf "Start to decode tack\n"
set $i=0
while($i<256 br=""> printf "i:%ld stack_addr:%xh\n",$i,$stack_addr
print /a *(int *) $stack_addr
set $stack_addr = $stack_addr +4
set $i = $i + 1
end
printf "End\n"
set logging off

Reference:

[Embedded] GDB script -- check deadlock caused by mutex

Gdb scripts can be used to fix bugs easily. So I collect some gdb script here as reference.
The first script is used to find the deadlock caused by mutex misuse.

Reference : Debug Hacks

1. For example: debug.cmd
set pagination offset logging file debug.log
set logging overwrite
set logging on
start
set $addr1 = pthread_mutex_lock
set $addr2 = pthread_mutex_unlock
b *$addr1
b *$addr2
while 1
   c
   if $pc != $addr1 & $pc != $addr2
      quit
   end
   printf "## addr : %08x\n", *(int *)($esp+4)
   bt
end 
NOTE: when you press ctrl+c, this script will quit.

2. Usage
$ gdb ./a.out -x debug.cmd

2015年1月24日 星期六

[Embedded] Why no core dump after segmentation fault?

1. Follow below command to set core dump generated in embedded Linux.
$ ulimit -c 1024
$ echo '/tmp/core_%e.%p' | tee /proc/sys/kernel/core_pattern

2. Why no core dump?
  • no write access to the directory 
  • use "ls" to check
  • the program changes the working directory 
  • how to check??
  • look for the core in other places too 
  • use "sysctl -a | grep core_pattern" to check
  • disk is full 
  • use "df ." to check
  • most Unix systems do not allow a setuid process to dump core 
  • use "cat /proc/sys/fs/suid_dumpable" to check,  
  • use "echo 1 > /proc/sys/fs/suid_dumpable" to change setting 
  • ulimit is set in one shell and the program is started in a different shell or environment
  • check /proc/pid/environ for current shell
  • note that only the program executed after "ulimit -c 1024" can generate core

3. We can use "kill -ABRT  pid_of_process" to generate core manually.

4. Check /proc/pid/limits for system limit
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytesMax resident set          unlimited            unlimited            bytes
Max processes             748                  748                  processes
Max open files            1024                 1024                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       748                  748                  signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

Reference:
  1. http://stackoverflow.com/questions/15272817/segmentation-fault-no-core-dump
  2. http://www.idimmu.net/2013/06/21/enable-linux-core-dump/
  3. http://www.gnu.org/software/bash/manual/bashref.html#Bourne-Shell-Builtins
  4. http://blog.csdn.net/pro_or_gram/article/details/15813879
  5. http://linuxxperts.com/enabling-core-dumps-in-embedded-systems/
  6. http://tieba.baidu.com/p/2365639005

2015年1月18日 星期日

[Embedded] Ubuntu的核心編譯

Below is the procedures to compile a linux kernel for ubuntu 

1.  get kernel source code 
$ sudo apt-get install linux-source
$ cp /usr/src/linux-source-3.13.0.tar.bz2 ~/ubuntu
$ cd ~/ubuntu
$ tar jxvf linux-source-3.13.0.tar.bz2

2. compile kernel
$ cd linux-source-3.13.0
$ make menuconfig
$ make

3. install new kernel
$ make modules_install
$ make install
$ update-initramfs -c -k

5. make sure kernel is build correctly
$ sudo ls /boot/*

6. check current kernel versuib
$ uname -r
// The original version is The new version is linux-source-3.13.0

7. After reboot
$ uname -r
// The new version is linux-source-3.13.0