ガイド | Radare2は、バイナリ分析用にカスタマイズされたオープンソースツールです。 バイナリ分析に利用できる(非ネイティブの)Linuxツールは多数ありますが、なぜRadare2を選択するのですか? |
なぜ別のツールが必要なのですか?
既存のLinuxネイティブツールが同様のことを実行できる場合は、当然、別のツールが必要な理由を尋ねられます。これは、携帯電話を目覚まし時計として使用したり、メモを取ったり、カメラを作ったり、音楽を聴いたり、インターネットをサーフィンしたり、ときどき電話をかけたり応答したりするのと同じ理由です。以前は、写真を撮るための物理的なカメラ、メモをとるための小さなメモ帳、目を覚ますためのベッドサイドアラームなど、これらの機能を処理するために別々のデバイスとツールが使用されていました。ユーザーが1つのデバイスで複数の(ただし関連する)ことを実行できると便利です。さらに、キラー機能は、独立した機能間の相互運用性です。
同様に、多くのLinuxツールには特定の目的がありますが、同様の(そしてより優れた)機能を1つのツールにバンドルすると非常に便利です。これが、バイナリファイルを処理する必要があるときにRadare2が最適なツールであると私が考える理由です。
GitHubプロファイルによると、Radare2(r2とも呼ばれます)は「Unixライクなシステムに設定されたリバースエンジニアリングフレームワークおよびコマンドラインツール」です。その名前の「2」は、このバージョンがよりモジュール化するために最初から書き直されたためです。
なぜRadare2を選ぶのですか?
バイナリ分析に利用できる(非ネイティブの)Linuxツールはたくさんありますが、なぜRadare2を選択するのですか?私の理由は単純です。
まず第一に、それは活発で健全なコミュニティを持つオープンソースプロジェクトです。これは、新しい機能を探している場合やバグ修正ツールを提供している場合に重要です。
次に、Radare2はコマンドラインで使用でき、GUIに精通している人に適したCutterと呼ばれる機能豊富なグラフィカルユーザーインターフェイス(GUI)環境を備えています。Linuxの長期ユーザーとして、私はシェルでの 入力に慣れ ています。Radare2コマンドに精通するための学習曲線は少しありますが、Vimの学習と比較します。最初に基本的なことを学ぶことができ、それらを習得すると、より高度なことを学び続けることができます。すぐに、それは筋肉の記憶になりました。
第三に、Radare2はプラグインを介して外部ツールを適切にサポートできます。たとえば、最近オープンソースのGhidraバイナリ分析およびリバースエンジニアリングツールのリバースツールは、その逆コンパイラ機能がリバースソフトウェアの重要な要素であるため、非常に人気があります。GhidraデコンパイラーはRadare2コンソールから直接インストールして使用できます。これは驚くべきことであり、両方の長所を提供します。
Radare2の使用を開始する
Radare2をインストールするには、リポジトリのクローンを作成してuser.sh
スクリプトを実行するだけです 。システムにいくつかの準備パッケージがない場合は、それらをインストールする必要がある場合があります。インストールが完了したら、r2 -vコマンドを実行して、Radare2が正しくインストールされているかどうかを確認します。
$ git clone https://github.com/radareorg/radare2.git
$ cd radare2
$ ./sys/user.sh
# version
$ r2 -v
radare2 4.6.0-git 25266 @ linux-x86-64 git.4.4.0-930-g48047b317
commit: 48047b3171e6ed0480a71a04c3693a0650d03543 build: 2020-11-17__09:31:03
$
バイナリテストサンプルを取得する
r2がインストールされたので、試してみるにはサンプルのバイナリプログラムが必要です。任意のシステムバイナリファイル(ls、bashなど)を使用できますが、このチュートリアルの内容を単純にするために、次のCプログラムをコンパイルしてください。
$ cat adder.c
#include <stdio.h>
int adder(int num) {
return num + 1;
}
int main() {
int res, num1 = 100;
res = adder(num1);
printf("Number now is : %d\n", res);
return 0;
}
$ gcc adder.c -o adder
$ file adder
adder: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=9d4366f7160e1ffb46b14466e8e0d70f10de2240, not stripped
$ ./adder
Number now is : 101
バイナリファイルをロードします
バイナリファイルを分析するには、Radare2にロードする必要があります。r2
コマンドのコマンドライン引数としてファイル名を指定してロードします 。シェルとは異なる別のRadare2コンソールに入ります。コンソールを終了するには、次のように入力する Quit
か、 Exit
またはを押し Ctrl+D
ます。
$ r2 ./adder
-- Learn pancake as if you were radare!
[0x004004b0]> quit
$
バイナリを分析する
バイナリを調べる前に、r2にバイナリを分析させる必要があります。これを行うには、r2コンソールでaaaコマンドを実行します。
$ r2 ./adder
-- Learn pancake as if you were radare!
[0x004004b0]> quit
$
つまり、分析するバイナリファイルを選択するたびに、バイナリファイルをロードした後に追加のコマンドaaaを入力する必要があります。これをバイパスして、コマンドの後に-Aを指定してr2を呼び出すことができます。これにより、r2にバイナリを自動的に分析するように指示されます。
$ r2 -A ./adder
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
-- Already up-to-date.
[0x004004b0]>
バイナリに関する基本情報を入手する
バイナリファイルの分析を開始する前に、いくつかの背景情報が必要です。多くの場合、これはバイナリファイルの形式(ELF、PEなど)、バイナリアーキテクチャ(x86、AMD、ARMなど)、およびバイナリが32ビットか64ビットかです。r2の便利なiIコマンドは、必要な情報を提供できます。
[0x004004b0]> iI
arch x86
baddr 0x400000
binsz 14724
bintype elf
bits 64
canary false
class ELF64
compiler GCC: (GNU) 8.3.1 20190507 (Red Hat 8.3.1-4)
crypto false
endian little
havecode true
intrp /lib64/ld-linux-x86-64.so.2
laddr 0x0
lang c
linenum true
lsyms true
machine AMD x86-64 architecture
maxopsz 16
minopsz 1
nx true
os linux
pcalign 0
pic false
relocs true
relro partial
rpath NONE
sanitiz false
static false
stripped false
subsys linux
va true
[0x004004b0]>
[0x004004b0]>
インポートとエクスポート
通常、処理しているファイルの種類がわかっている場合は、バイナリプログラムが使用する標準ライブラリ関数を知りたい、またはプログラムの潜在的な関数を理解したい。このチュートリアルのサンプルCプログラムでは、ライブラリ関数はprintfのみであり、これは情報の印刷に使用されます。これは、バイナリによってインポートされたすべてのライブラリを表示するiiコマンドを実行することで確認できます。
[0x004004b0]> ii
[Imports]
nth vaddr bind type lib name
―――――――――――――――――――――――――――――――――――――
1 0x00000000 WEAK NOTYPE _ITM_deregisterTMCloneTable
2 0x004004a0 GLOBAL FUNC printf
3 0x00000000 GLOBAL FUNC __libc_start_main
4 0x00000000 WEAK NOTYPE __gmon_start__
5 0x00000000 WEAK NOTYPE _ITM_registerTMCloneTable
バイナリは、独自のシンボル、関数、またはデータを持つこともできます。これらの機能は通常、[エクスポート]の下に表示されます。このテストのバイナリは、mainとadderの2つの関数をエクスポートします。残りの関数は、バイナリファイルがビルドされるコンパイルフェーズ中に追加されます。ローダーは、バイナリファイルをロードするために次の関数を必要とします(今のところあまり気にしないでください)。
[0x004004b0]>
[0x004004b0]> iE
[Exports]
nth paddr vaddr bind type size lib name
――――――――――――――――――――――――――――――――――――――――――――――――――――――
82 0x00000650 0x00400650 GLOBAL FUNC 5 __libc_csu_fini
85 ---------- 0x00601024 GLOBAL NOTYPE 0 _edata
86 0x00000658 0x00400658 GLOBAL FUNC 0 _fini
89 0x00001020 0x00601020 GLOBAL NOTYPE 0 __data_start
90 0x00000596 0x00400596 GLOBAL FUNC 15 adder
92 0x00000670 0x00400670 GLOBAL OBJ 0 __dso_handle
93 0x00000668 0x00400668 GLOBAL OBJ 4 _IO_stdin_used
94 0x000005e0 0x004005e0 GLOBAL FUNC 101 __libc_csu_init
95 ---------- 0x00601028 GLOBAL NOTYPE 0 _end
96 0x000004e0 0x004004e0 GLOBAL FUNC 5 _dl_relocate_static_pie
97 0x000004b0 0x004004b0 GLOBAL FUNC 47 _start
98 ---------- 0x00601024 GLOBAL NOTYPE 0 __bss_start
99 0x000005a5 0x004005a5 GLOBAL FUNC 55 main
100 ---------- 0x00601028 GLOBAL OBJ 0 __TMC_END__
102 0x00000468 0x00400468 GLOBAL FUNC 0 _init
[0x004004b0]>
ハッシュ情報
2つのバイナリファイルが類似しているかどうかを知る方法は?バイナリファイルを開いて、その中のソースコードを表示することはできません。ほとんどの場合、バイナリファイルのハッシュ値(md5sum、sha1、sha256)を使用して一意に識別します。itコマンドを使用して、バイナリハッシュ値を見つけることができます。
[0x004004b0]> it
md5 7e6732f2b11dec4a0c7612852cede670
sha1 d5fa848c4b53021f6570dd9b18d115595a2290ae
sha256 13dd5a492219dac1443a816ef5f91db8d149e8edbf26f24539c220861769e1c2
[0x004004b0]>
関数
コードは関数ごとにグループ化されています。バイナリに存在する関数を一覧表示するには、aflコマンドを実行します。次のリストは、主な機能と加算器機能を示しています。通常、sym.impで始まる関数は、標準ライブラリ(ここではglibc)からインポートされます。
[0x004004b0]> afl
0x004004b0 1 46 entry0
0x004004f0 4 41 -> 34 sym.deregister_tm_clones
0x00400520 4 57 -> 51 sym.register_tm_clones
0x00400560 3 33 -> 32 sym.__do_global_dtors_aux
0x00400590 1 6 entry.init0
0x00400650 1 5 sym.__libc_csu_fini
0x00400658 1 13 sym._fini
0x00400596 1 15 sym.adder
0x004005e0 4 101 loc..annobin_elf_init.c
0x004004e0 1 5 loc..annobin_static_reloc.c
0x004005a5 1 55 main
0x004004a0 1 6 sym.imp.printf
0x00400468 3 27 sym._init
[0x004004b0]>
クロスリファレンス
[0x004004b0]> axt sym.adder
main 0x4005b9 [CALL] call sym.adder
[0x004004b0]>
[0x004004b0]> axt main
entry0 0x4004d1 [DATA] mov rdi, main
[0x004004b0]>
場所を探す
テキストファイルを操作するときは、行番号と行番号または列番号を引用してファイル内を移動することがよくあります。バイナリファイルでは、アドレスを使用する必要があります。これらは、0xで始まり、その後にアドレスが続く16進数です。バイナリ内の位置を見つけるには、sコマンドを実行します。別の場所に移動するには、sコマンドに続けてアドレスを使用します。
関数名はラベルのようなもので、内部アドレスが表現されています。関数名がバイナリ(削除されていない)の場合、関数名の後にsコマンドを使用して、特定の関数アドレスにジャンプできます。同様に、バイナリの先頭にジャンプする場合は、s0と入力します。
[0x004004b0]> s
0x4004b0
[0x004004b0]>
[0x004004b0]> s main
[0x004005a5]>
[0x004005a5]> s
0x4005a5
[0x004005a5]>
[0x004005a5]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[0x00400596]>
[0x00400596]> s 0
[0x00000000]>
[0x00000000]> s
0x0
[0x00000000]>
16進ビュー
通常、生のバイナリには意味がありません。バイナリとそれに相当するASCII表記を16進モードで表示すると便利です。
[0x004004b0]> s main
[0x004005a5]>
[0x004005a5]> px
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x004005a5 5548 89e5 4883 ec10 c745 fc64 0000 008b UH..H....E.d....
0x004005b5 45fc 89c7 e8d8 ffff ff89 45f8 8b45 f889 E.........E..E..
0x004005c5 c6bf 7806 4000 b800 0000 00e8 cbfe ffff ..x.@...........
0x004005d5 b800 0000 00c9 c30f 1f40 00f3 0f1e fa41 [email protected]
0x004005e5 5749 89d7 4156 4989 f641 5541 89fd 4154 WI..AVI..AUA..AT
0x004005f5 4c8d 2504 0820 0055 488d 2d04 0820 0053 L.%.. .UH.-.. .S
0x00400605 4c29 e548 83ec 08e8 57fe ffff 48c1 fd03 L).H....W...H...
0x00400615 741f 31db 0f1f 8000 0000 004c 89fa 4c89 t.1........L..L.
0x00400625 f644 89ef 41ff 14dc 4883 c301 4839 dd75 .D..A...H...H9.u
0x00400635 ea48 83c4 085b 5d41 5c41 5d41 5e41 5fc3 .H...[]A\A]A^A_.
0x00400645 9066 2e0f 1f84 0000 0000 00f3 0f1e fac3 .f..............
0x00400655 0000 00f3 0f1e fa48 83ec 0848 83c4 08c3 .......H...H....
0x00400665 0000 0001 0002 0000 0000 0000 0000 0000 ................
0x00400675 0000 004e 756d 6265 7220 6e6f 7720 6973 ...Number now is
0x00400685 2020 3a20 2564 0a00 0000 0001 1b03 3b44 : %d........;D
0x00400695 0000 0007 0000 0000 feff ff88 0000 0020 ...............
[0x004005a5]>
分解
コンパイルされたバイナリファイルを使用している場合、ソースコードを表示することはできません。コンパイラは、ソースコードをCPUが理解して実行できる機械語命令に変換します。その結果、バイナリファイルまたは実行可能ファイルが作成されます。ただし、アセンブリ命令(ニーモニック)を見て、プログラムが何をしているのかを理解することができます。たとえば、main関数の動作を確認したい場合は、s mainを使用してmain関数のアドレスを検索し、pdfコマンドを実行して逆アセンブルされた命令を確認できます。
アセンブリ手順を理解するには、アーキテクチャマニュアル(ここではx86)、そのアプリケーションバイナリインターフェイス(ABI、または呼び出し規約)を参照し、スタックがどのように機能するかについての基本的な理解が必要です。
[0x004004b0]> s main
[0x004005a5]>
[0x004005a5]> s
0x4005a5
[0x004005a5]>
[0x004005a5]> pdf
; DATA XREF from entry0 @ 0x4004d1
┌ 55: int main (int argc, char **argv, char **envp);
│ ; var int64_t var_8h @ rbp-0x8
│ ; var int64_t var_4h @ rbp-0x4
│ 0x004005a5 55 push rbp
│ 0x004005a6 4889e5 mov rbp, rsp
│ 0x004005a9 4883ec10 sub rsp, 0x10
│ 0x004005ad c745fc640000. mov dword [var_4h], 0x64 ; 'd' ; 100
│ 0x004005b4 8b45fc mov eax, dword [var_4h]
│ 0x004005b7 89c7 mov edi, eax
│ 0x004005b9 e8d8ffffff call sym.adder
│ 0x004005be 8945f8 mov dword [var_8h], eax
│ 0x004005c1 8b45f8 mov eax, dword [var_8h]
│ 0x004005c4 89c6 mov esi, eax
│ 0x004005c6 bf78064000 mov edi, str.Number_now_is__:__d ; 0x400678 ; "Number now is : %d\n" ; const char *format
│ 0x004005cb b800000000 mov eax, 0
│ 0x004005d0 e8cbfeffff call sym.imp.printf ; int printf(const char *format)
│ 0x004005d5 b800000000 mov eax, 0
│ 0x004005da c9 leave
└ 0x004005db c3 ret
[0x004005a5]>
这是 adder 函数的反汇编结果:
[0x004005a5]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[0x00400596]>
[0x00400596]> pdf
; CALL XREF from main @ 0x4005b9
┌ 15: sym.adder (int64_t arg1);
│ ; var int64_t var_4h @ rbp-0x4
│ ; arg int64_t arg1 @ rdi
│ 0x00400596 55 push rbp
│ 0x00400597 4889e5 mov rbp, rsp
│ 0x0040059a 897dfc mov dword [var_4h], edi ; arg1
│ 0x0040059d 8b45fc mov eax, dword [var_4h]
│ 0x004005a0 83c001 add eax, 1
│ 0x004005a3 5d pop rbp
└ 0x004005a4 c3 ret
[0x00400596]>
ストリング
バイナリ分析の開始点として使用できるバイナリに存在する文字列を確認します。文字列はバイナリにハードコードされており、通常、分析の特定の領域に焦点を移すことができる重要なヒントを提供します。バイナリでiz
コマンドを実行して、 すべての文字列を一覧表示します。このテストバイナリには、ハードコードされた文字列が1つだけあります。
[0x004004b0]> iz
[Strings]
nth paddr vaddr len size section type string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000678 0x00400678 20 21 .rodata ascii Number now is : %d\n
[0x004004b0]>
相互参照文字列
関数と同様に、文字列を相互参照し、文字列がどこから出力されているかを確認し、文字列を囲むコードを理解できます。
[0x004004b0]> ps @ 0x400678
Number now is : %d
[0x004004b0]>
[0x004004b0]> axt 0x400678
main 0x4005c6 [DATA] mov edi, str.Number_now_is__:__d
[0x004004b0]>
ビジュアルモード
コードが複雑で複数の関数が呼び出されると、迷子になりがちです。どの関数がグラフィカルまたは視覚的に呼び出され、特定の条件に従ってどのパスが使用されたかを確認すると便利です。目的の機能に移動した後、VVコマンドを使用してr2の視覚化モードを調べることができます。たとえば、加算器関数の場合:
[0x004004b0]> s sym.adder
[0x00400596]>
[0x00400596]> VV
デバッガ
これまでのところ、静的分析を行っています。バイナリファイルを実行せずに、バイナリファイル内の内容を確認しているだけです。バイナリファイルを実行し、実行時にメモリ内のさまざまな情報を分析する必要がある場合があります。R2の内部デバッガーを使用すると、バイナリファイルの実行、ブレークポイントの設定、変数の値の分析、またはレジスターの内容のダンプを行うことができます。
-dフラグを指定してデバッガーを起動し、バイナリーをロードするときに分析用に-Aフラグを追加します。db <function-name>コマンドを使用して、関数やメモリアドレスなどのさまざまな場所にブレークポイントを設定できます。既存のブレークポイントを表示するには、dbiコマンドを使用します。ブレークポイントを設定したら、dcコマンドを使用してバイナリファイルの実行を開始します。dbtコマンドを使用して、関数呼び出しを表示できるスタックを表示できます。最後に、drrコマンドを使用して、レジスタの内容をダンプできます。
$ r2 -d -A ./adder
Process with PID 17453 started...
= attach 17453 17453
bin.baddr 0x00400000
Using 0x400000
asm.bits 64
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
-- git checkout hamster
[0x7f77b0a28030]>
[0x7f77b0a28030]> db main
[0x7f77b0a28030]>
[0x7f77b0a28030]> db sym.adder
[0x7f77b0a28030]>
[0x7f77b0a28030]> dbi
0 0x004005a5 E:1 T:0
1 0x00400596 E:1 T:0
[0x7f77b0a28030]>
[0x7f77b0a28030]> afl | grep main
0x004005a5 1 55 main
[0x7f77b0a28030]>
[0x7f77b0a28030]> afl | grep sym.adder
0x00400596 1 15 sym.adder
[0x7f77b0a28030]>
[0x7f77b0a28030]> dc
hit breakpoint at: 0x4005a5
[0x004005a5]>
[0x004005a5]> dbt
0 0x4005a5 sp: 0x0 0 [main] main sym.adder+15
1 0x7f77b0687873 sp: 0x7ffe35ff6858 0 [??] section..gnu.build.attributes-1345820597
2 0x7f77b0a36e0a sp: 0x7ffe35ff68e8 144 [??] map.usr_lib64_ld_2.28.so.r_x+65034
[0x004005a5]> dc
hit breakpoint at: 0x400596
[0x00400596]> dbt
0 0x400596 sp: 0x0 0 [sym.adder] rip entry.init0+6
1 0x4005be sp: 0x7ffe35ff6838 0 [main] main+25
2 0x7f77b0687873 sp: 0x7ffe35ff6858 32 [??] section..gnu.build.attributes-1345820597
3 0x7f77b0a36e0a sp: 0x7ffe35ff68e8 144 [??] map.usr_lib64_ld_2.28.so.r_x+65034
[0x00400596]>
[0x00400596]>
[0x00400596]> dr
rax = 0x00000064
rbx = 0x00000000
rcx = 0x7f77b0a21738
rdx = 0x7ffe35ff6948
r8 = 0x7f77b0a22da0
r9 = 0x7f77b0a22da0
r10 = 0x0000000f
r11 = 0x00000002
r12 = 0x004004b0
r13 = 0x7ffe35ff6930
r14 = 0x00000000
r15 = 0x00000000
rsi = 0x7ffe35ff6938
rdi = 0x00000064
rsp = 0x7ffe35ff6838
rbp = 0x7ffe35ff6850
rip = 0x00400596
rflags = 0x00000202
orax = 0xffffffffffffffff
[0x00400596]>
逆コンパイラ
アセンブリを理解できることは、バイナリ分析の前提条件です。アセンブリ言語は、常にバイナリビルドのアーキテクチャと予想される操作に関連しています。ソースコードの行とアセンブリコードの間に1:1のマッピングはありません。通常、1行のCソースコードは複数行のアセンブリコードを生成します。したがって、アセンブリコードを1行ずつ読み取ることは最善の選択ではありません。
これが逆コンパイラの役割です。彼らは、アセンブリ命令に基づいて可能なソースコードを再構築しようとします。これは、バイナリの作成に使用されたソースコードとまったく同じではなく、アセンブリに基づくソースコードのおおよその表現です。さらに、コンパイラによって実行される最適化を考慮する必要があります。これにより、さまざまなアセンブリコードが生成され、高速化、バイナリのサイズの縮小などが行われるため、逆コンパイラの作業がより困難になります。さらに、マルウェアの作成者は意図的にコードを難読化することが多く、マルウェアアナリストを思いとどまらせます。
Radare2は、プラグインを介して逆コンパイラーを提供します。Radare2でサポートされている任意の逆コンパイラーをインストールできます。r2pm -lコマンドを使用して、現在のプラグインを表示します。r2pm installコマンドを使用して、サンプルの逆コンパイラr2decをインストールします。
$ r2pm -l
$
$ r2pm install r2dec
Cloning into 'r2dec'...
remote: Enumerating objects: 100, done.
remote: Counting objects: 100% (100/100), done.
remote: Compressing objects: 100% (97/97), done.
remote: Total 100 (delta 18), reused 27 (delta 1), pack-reused 0
Receiving objects: 100% (100/100), 1.01 MiB | 1.31 MiB/s, done.
Resolving deltas: 100% (18/18), done.
Install Done For r2dec
gmake: Entering directory '/root/.local/share/radare2/r2pm/git/r2dec/p'
[CC] duktape/duktape.o
[CC] duktape/duk_console.o
[CC] core_pdd.o
[CC] core_pdd.so
gmake: Leaving directory '/root/.local/share/radare2/r2pm/git/r2dec/p'
$
$ r2pm -l
r2dec
$
逆コンパイラビュー
バイナリファイルを逆コンパイルするには、バイナリファイルをr2にロードし、自動的に分析します。この例では、s sym.adderコマンドを使用して目的の加算器関数に移動し、次にpddaコマンドを使用してアセンブルおよび逆コンパイルされたソースコードを並べて表示します。この逆コンパイルされたソースコードを読むことは、多くの場合、アセンブリを1行ずつ読むよりも簡単です。
$ r2 -A ./adder
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
-- What do you want to debug today?
[0x004004b0]>
[0x004004b0]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[0x00400596]>
[0x00400596]> pdda
; assembly | /* r2dec pseudo code output */
| /* ./adder @ 0x400596 */
| #include <stdint.h>
|
; (fcn) sym.adder () | int32_t adder (int64_t arg1) {
| int64_t var_4h;
| rdi = arg1;
0x00400596 push rbp |
0x00400597 mov rbp, rsp |
0x0040059a mov dword [rbp - 4], edi | *((rbp - 4)) = edi;
0x0040059d mov eax, dword [rbp - 4] | eax = *((rbp - 4));
0x004005a0 add eax, 1 | eax++;
0x004005a3 pop rbp |
0x004005a4 ret | return eax;
| }
[0x00400596]>
構成設定
Radare2の使用法に慣れてきたら、作業方法に合わせて構成を変更する必要があります。eコマンドを使用して、r2のデフォルト設定を表示できます。特定の構成を設定するには、eコマンドの後にconfig = valueを追加します。
[0x004005a5]> e | wc -l
593
[0x004005a5]> e | grep syntax
asm.syntax = intel
[0x004005a5]>
[0x004005a5]> e asm.syntax = att
[0x004005a5]>
[0x004005a5]> e | grep syntax
asm.syntax = att
[0x004005a5]>
構成の変更を永続的にするには、r2の起動時に読み取られる.radare2rcという名前のスタートアップファイルにそれらを配置します。このファイルは通常、ホームディレクトリにありますが、そうでない場合は作成できます。構成オプションの例は次のとおりです。
$ cat ~/.radare2rc
e asm.syntax = att
e scr.utf8 = true
eco solarized
e cmd.stack = true
e stack.size = 256
$
詳細を見る
あなたは十分なRadare2機能を見て、このツールについてある程度理解しています。Radare2はUnix哲学に従っているため、メインコンソールからさまざまなことを実行できる場合でも、以下の独立したバイナリのセットを使用してタスクを完了します。Linuxはこのように学ぶ必要があります
以下にリストされている個々のバイナリを調べて、それらがどのように機能するかを確認してください。たとえば、iIコマンドを使用してコンソールに表示されるバイナリ情報は、rabin2 <binary>コマンドを使用して見つけることもできます。
$ cd bin/
$
$ ls
prefix r2agent r2pm rabin2 radiff2 ragg2 rarun2 rasm2
r2 r2-indent r2r radare2 rafind2 rahash2 rasign2 rax2
$