ソフトウェアを美味しく 解析する方法 Security Ark

Slides:



Advertisements
Similar presentations
1 B10 CPU を作る 1 日目 解説 TA 高田正法
Advertisements

C 言語講座 第 7 回 ポインター. メモリとアドレス(ポインターの前 に) コンピュータのメモリには 1 バイトずつ 0 番地、 1 番地、 2 番地・・・というように 住所が割り当てられている この住所をアドレスという。 メモリはデータをしまうもので それを引き出すためには メモリに番号(アドレス)を振っておけばよいな.
2006/10/26 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
コンパイラ 2012年10月25日
ISD実習E 2009年6月29日 LISPシステム入門 (第5回) 関数ポインタ eval システム関数.
プログラミング言語としてのR 情報知能学科 白井 英俊.
坂井 修一 東京大学 大学院 情報理工学系研究科 電子情報学専攻 東京大学 工学部 電気工学科
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
第4回 個人の動画配信補足のためのWeb構築
2006年度 計算機システム演習 第4回 2005年5月19日.
侵入検知システム(IDS) 停止 IDS サーバへの不正アクセスが増加している
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
アルゴリズムとデータ構造1 2009年6月25日
第4回放送授業.
  【事例演習6】  数式インタプリタ      解 説     “インタプリタの基本的な仕組み”.
プログラムはなぜ動くのか.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
オペレーティングシステム i386アーキテクチャ(2)
2016年度 プログラミングⅠ ~ 内部構造と動作の仕組み(1) ~.
コンパイラ 2011年10月27日
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
セキュリティ(3) 05A2013 大川内 斉.
コンピュータ系実験Ⅲ 「ワンチップマイコンの応用」 第1週目 アセンブリ言語講座
プログラミング言語入門.
アルゴリズムとデータ構造 補足資料11-1 「mallocとfree」
アルゴリズムとデータ構造 2010年6月28日
アルゴリズムとデータ構造1 2005年6月28日
第7回 プログラミングⅡ 第7回
TA 高田正法 B10 CPUを作る 3日目 SPIMの改造 TA 高田正法
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
高度プログラミング演習 (08).
A Provably Sound TAL for Back-end Optimization について
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
コンパイラ資料 実行時環境.
第2回課題 配布した通り.氏名・学生番号を忘れないこと.
オブジェクト指向プログラミングと開発環境
情報とコンピュータ 静岡大学工学部 安藤和敏
先週の復習: CPU が働く仕組み コンピュータの構造 pp 制御装置+演算装置+レジスタ 制御装置がなければ電卓と同様
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
コンピュータアーキテクチャ 第 4 回.
2017年度 プログラミングⅠ ~ 内部構造と動作の仕組み(1) ~.
ポインタとポインタを用いた関数定義.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
コンピュータアーキテクチャ 第 3 回.
情報基礎演習B 後半第2回 担当 岩村 TA 谷本君.
コンピュータアーキテクチャ 第 5 回.
計算機アーキテクチャ1 (計算機構成論(再)) 第二回 命令の種類と形式
コンピュータアーキテクチャ 第 4 回.
第5回 プログラミングⅡ 第5回
第4回 CPUの役割と仕組み2 命令の解析と実行、クロック、レジスタ
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
コンピュータアーキテクチャ 第 5 回.
プログラムの開発手順 1.プログラム設計(仕様の決定) 2.コーディング(ソースファイルの作成) 3.アセンブル(オブジェクトファイル
ca-9. 数の扱い (コンピュータアーキテクチャとプロセッサ)
オブジェクト指向言語論 第二回 知能情報学部 新田直也.
X64 函数呼び出し規約 長谷川啓
コンパイラ 第12回 実行時環境 ― 変数と関数 ― 38号館4階N-411 内線5459
2014年度 プログラミングⅠ ~ 内部構造と動作の仕組み(1) ~.
参考:大きい要素の処理.
プログラミング演習I 2003年6月11日(第9回) 木村巌.
プログラミング演習II 2004年11月 2日(第3回) 理学部数学科・木村巌.
情報処理Ⅱ 小テスト 2005年2月1日(火).
C#プログラミング実習 第1回.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
6.5 最終コード生成 (1)コードの形式 ①絶対2進コード(AB : absolute binary) 命令後のオペランドが絶対番地指定。
Presentation transcript:

ソフトウェアを美味しく 解析する方法 Will@ Security Ark http://security.symphonic-net.com/

自己紹介 世を忍ぶ仮の姿はとある大学の学生 しょぼいソフトウェアの開発や解析などを少々 金穴につき、ただ今大学の生協にてバイト中 全く関係ないが二日前まで長野でスノボーしてた さらに関係ないが金もないのに今年は何故か   三回もスノボーに行った。

解析とは リバースエンジニアリングとは、機械を分解 したり、製品の動作を観察したり ソフトウェアの動作を解析するなどして 製品の構造を分析し、そこから製造方法や 動作原理、設計図、ソースコードなどを 調査する事である。 http://ja.wikipedia.org/wiki/リバースエンジニアリング          取 り 敢 え ず    今回はソフトウェアのReverse engineeringということで

解析の目的 脆弱性の調査 ウイルスの調査 互換性の確保 独自機能の追加            …etc

解析の必要性 使い方によっては善にも悪にもなる技術だが Securityの分野では重要な技術! 合法 違法

解析を行うには ♪アセンブリ言語に関する知識 ♪Win32APIに関する知識 ♪PE Formatに関する知識 挫けない心 ←これ超重要

アセンブリ言語について アセンブリ言語ではデータを保存する場所として以下の四つがあります。 レジスタ スタック ヒープ領域 データセクション領域 ☆レジスタについて☆  レジスタはCPUの内部に存在するメモリで、高速なので計算を行う際に一時的に使用されます。各レジスタには大まかな役割が割り当てられていますが無視しても大丈夫です。  しかし、命令によってはある特定のレジスタの値に依存した処理が行われる事があるので、出来る限りその方針にしたがった使い方をした方がいいでしょう。

レジスタ一覧 レジスタ名 使用目的 EAX 何にでも使っても良い、関数の戻り値はこれに入る。 EBX アドレス演算用。ポインタみたいな感じ。 EDX 何にでも使って良い。 ECX ECXは特定条件化ではカウンタとなるが 基本的にはEAX,EDX同様に何に使ってもよい ESI extended source indexの略で転送元アドレスの指定に使われる EDI extended destination indexの略で転送先アドレスの指定に使われる ESP スタックの現在アドレスを保持している (基本的にこれは別用途で使用してはいけない) EBP ローカル変数や引数の参照などにつかう EAX AH AX AL レジスタはすべて32bitで、最初のEをとった   ax,bxなどで下位16bitにアクセスできる。 さらに、EAX、EBX、EDX,ECXに至ってはahおよび、alでさらにその半分の8bitにアクセスできる。

命令一覧 命令 説明 mov add dest,src dest = dest + srcという処理が行われます。 add sub dest,src dest = dest - srcという処理が行われます。 push push src     srcがスタックに積まれます。    pop pop dest destにスタックから取り出した値が格納されます。 imul Iml eax,edx eaxにeax*edxの結果が格納されます。 test test src1, src2 src1とsrc2の論理積(AND)をとって、 その結果をステータスレジスタに書き込みます。 ステータスレジスタは変わりますが、 src1とsrc2のあたいは変わらずに保持されます。 j* j* src *の中に入る文字で処理が変わります。 eの時はequalの略で比較命令の結果が等しればジャンプします。      neはnot equalの略で比較命令の結果が等しくなければジャンプ。 lea lea dest,src 実行アドレスの計算。他に簡単な計算などに使われる。

関数の呼び出し規約 C言語では主にcdeclが用いられている。 cdeclでは関数への引数は右から左の順でスタックに積まれる。 関数の戻り値は EAX(80x86のレジスタの一つ)に格納される。 スタックポインタの処理は呼び出し側で行う。 1.の例    foo(int a1,int a2,int a3)という関数を呼び出す場合は ------------------------------------------------- push a3 push a2 push a1 call foo 2.の例    1を戻り値として返す場合 ------------------------------------------------- mov eax,1 ret

とりあえず逆アセンブルしてみよう♪ これで分かる人はマジで凄い! これな~んだ? 56 8B 74 24 08 85 F6 75 07 B8 01 00 00 00 5E C3 8D 46 FF 50 E8 E7 FF FF FF 0F AF C6 83 C4 04 5E C3 これで分かる人はマジで凄い! とりあえず逆アセンブルしてみよう♪

目標はCのソースに変換! 逆アセンブルしてみよう♪ 00941000 PUSH ESI 00941001 MOV ESI,DWORD PTR SS:[ESP+8] 00941005 TEST ESI,ESI 00941007 JNZ SHORT test.00941010 00941009 MOV EAX,1 0094100E POP ESI 0094100F RETN 00941010 LEA EAX,DWORD PTR DS:[ESI-1] 00941013 PUSH EAX 00941014 CALL test.00941000 00941019 IMUL EAX,ESI 0094101C ADD ESP,4 0094101F POP ESI 00941020 RETN 目標はCのソースに変換!

ブロックで分ける 00941000 PUSH ESI 00941001 MOV ESI,DWORD PTR SS:[ESP+8] 00941005 TEST ESI,ESI 00941007 JNZ SHORT test.00941010 00941009 MOV EAX,1 0094100E POP ESI 0094100F RETN 00941010 LEA EAX,DWORD PTR DS:[ESI-1] 00941013 PUSH EAX 00941014 CALL test.00941000 00941019 IMUL EAX,ESI 0094101C ADD ESP,4 0094101F POP ESI 00941020 RETN 第一ブロック 第二ブロック 第三ブロック

第一ブロックの理解 00941000 PUSH ESI ↑下で使うので今現在の値をスタックに待避 00941001 MOV ESI,DWORD PTR SS:[ESP+8] ↑ESIに第一引数の値を格納 00941005 TEST ESI,ESI ↑ESIの値を評価 00941007 JNZ SHORT test.00941010 ↑ESIの値が0ではなかったらジャンプ!

第二ブロックの理解 00941009 MOV EAX,1 ↑EAXに1を代入 0094100E POP ESI 0094100F RETN ↑りた~ん

第三ブロックの理解 00941010 LEA EAX,DWORD PTR DS:[ESI-1] 00941013 PUSH EAX ↑EAXにESI-1の結果を格納 00941013 PUSH EAX ↑EAXをスタックに放り込む 00941014    CALL test.00941000 ↑0x941000番地の関数を呼び出す 00941019 IMUL EAX,ESI ↑EAX=EAX*ESIの計算を行う 0094101C ADD ESP,4 ↑スタックの調整 0094101F POP ESI ↑待避していた値をESIに戻す 00941020 RETN

ちょっとずつCにしていくよ 00941000 PUSH ESI ←ESIを使うのでスタックに待避 00941001 MOV ESI,DWORD PTR SS:[ESP+8] 00941005 TEST ESI,ESI 00941007 JNZ SHORT test.00941010←第三ブロックへ hoge(int arg) { if(arg == 0){ [第二ブロック] } [第三ブロック]

これだけですw 第二ブロック 00941009 MOV EAX,1 戻り値に1を指定 0094100E POP ESI ESIに値を戻す 0094100F RETN Return 1; これだけですw

これだけですw 第三ブロック return hoge(arg-1)*arg 00941010 LEA EAX,DWORD PTR DS:[ESI-1]  ←  ESIはarg 00941013 PUSH EAX 00941014    CALL test.00941000    ← 0x941000は関数の先頭   00941019 IMUL EAX,ESI 0094101C ADD ESP,4 0094101F POP ESI 00941020 RETN return hoge(arg-1)*arg これだけですw

Nの階乗を計算する 再帰関数でした まとめちゃいます hoge(int arg) { if(arg == 0){ return 1; } return hoge(arg-1)*arg; Nの階乗を計算する 再帰関数でした

0と1を愛する心♪ まとめ そして… 解析(リバースエンジニアリング)をするためには☆ アセンブリ言語の知識 Win32APIに関する知識 PE Formatに関する知識 根性 カン&慣れ そして… 0と1を愛する心♪

終わり \(^o^)/オワタ ご静聴 ありがとうございました♪