緩衝區溢位實戰教程系列(二):dev c++編譯彙編程式碼
*本文原創作者:kaliking,本文屬於FreeBuf原創獎勵計劃,未經許可禁止轉載
小夥伴們對我上一篇文章的反應完全出乎了我的意料,感謝大家對我的支援和認可。接下來我會精心的把這一系列課程設計好,儘量詳細的展示給大家。上篇文章我列舉了一個緩衝區溢位的小例子,並提到了dev c++、ollydbg、IDA Freeware這三款軟體,並介紹了dev c++的基本用法。今天會補充一下Dev c++的用法。
今天補充的用法主要是為了以後編寫shellcode做準備,這篇文章只講用法,大家不必深究程式碼的功能。
0×00 如何編寫彙編程式碼
下面給大家一個在dev下用匯編程式碼編譯的MessageBox的的程式碼例子,可以彈出一個提示框,今天還是不講程式碼,主要講程式碼是如何編譯的。
#include<windows.h> int main() { LoadLibrary("user32.dll"); __asm__("push 0x00000001"); //MessageBoxA的最後一個引數 入棧 __asm__("movbyteptr[ebp+0x26],0x57"); //W __asm__("movbyteptr[ebp+0x27],0x61"); //a __asm__("movbyteptr[ebp+0x28],0x72"); //r __asm__("movbyteptr[ebp+0x29],0x6e"); //n __asm__("movbyteptr[ebp+0x2a],0x69"); //i __asm__("movbyteptr[ebp+0x2b],0x6e"); //n __asm__("movbyteptr[ebp+0x2c],0x67"); //g __asm__("movbyteptr[ebp+0x2d],0x00"); //表示字元截斷,就是說程式碼截止 __asm__("leaeax,[ebp+0x26]"); //把儲存字元的起始地址賦給暫存器eax __asm__("pusheax"); //把第三個引數入棧也就是標題 __asm__("movbyteptr[ebp+0x2e],0x61"); __asm__("movbyteptr[ebp+0x2f],0x62"); __asm__("movbyteptr[ebp+0x30],0x63"); __asm__("movbyteptr[ebp+0x31],0x64"); __asm__("leaeax,[ebp+0x2e]"); __asm__("pusheax"); //把第二個引數入棧,也就是內容 __asm__("push 0x00000000"); //MessageBoxA的第一個引數 入棧 __asm__("mov eax,0x762cfdae"); //這個地址是臨時搜的MessageBox的地址 ,大家目前需要自己找。 __asm__("call eax"); return 0; }
首先要編寫彙編程式碼,我們要用__asm__()或__asm()方法包含起來,不要忘記還要用雙引號。當然你要是覺得上面一行程式碼用一個__asm__()函式麻煩,你也可以在在一個函式裡編寫所有程式碼,像下面這樣。不過要注意每行程式碼都要用雙引號包裹,還要注意彙編程式碼後邊的分號也要有哦。
__asm( "movbyteptr[ebp+0x26],0x57;" "movbyteptr[ebp+0x27],0x61;" ); //W、a
0×01 如何編譯彙編程式碼
我用的是intel風格的彙編,在dev下編譯通常會遇到問題,向下面這樣報很多錯誤。
解決方法其實很簡單就是,在編譯選項里加一個-masm=intel命令就好,具體步驟,是點選工具-編譯選項,在彈出選單中勾選“ 編譯時加入以下命令 ”,把 -masm=intel命令新增進去就好,如下圖所示:
當我們再編譯時就沒有問題了。
0×02 看看彙編程式碼寫出來MessageBox的效果
這裡給大家跑出一個小問題,大家說說為什麼abcd後面會出現“燙燙燙燙”的字樣,大家認真思考哈。
0×03 intel與AT&T的不同
因為上面提到了intel彙編,感覺有必要提一下AT&T彙編,AT&T風格彙編在dev下是直接可編譯的,如果你熟悉這種彙編風格,那麼恭喜你。
組合語言 (英語:assembly language)是一種用於電子計算機、 微處理器、微控制器,或別樣可程式設計器件個低階語言。拉弗同個裝置中,組合語言對應著弗同個機器語言指令集。
彙編風格
x86/amd64彙編指令的兩大風格分別是Intel彙編與AT&T彙編,分別被Microsoft Windows/ Visual C++與GNU/Gas採用(Gas也可使用Intel彙編風格):
大家看圖片直觀感受一下就好。
0×04 將彙編程式碼轉換成16進位制機器碼
學會了這步我們就可以提取shellcode了。
首先,要設定一個斷點位置隨意,可以在想設定斷點的地方單擊滑鼠左鍵,也可以把游標移動到想要設定的行按F4鍵:
其次,依次點選如圖的除錯。
這時候我們點選檢視cpu視窗會看到彙編程式碼,但不是我們想要的:
我們找到右下角的視窗看到傳送命令到gdb,輸入disassemble /r 就會得到16進位制程式碼與彙編程式碼對應的結果。16進位制程式碼就是我們想要的shellcode。
看我用紅框標註的位置:
本來是想把三個軟體全部講了,結果一補充就寫了這麼多。為了大家方便檢視還是保持每篇有一定的獨立性吧,大家別嫌煩,俗話說磨刀不誤砍柴工。以上就是今天的內容,咱們下期見。
*本文原創作者:kaliking,本文屬於FreeBuf原創獎勵計劃,未經許可禁止轉載