GNU/Linux >> Linux の 問題 >  >> Linux

このフル機能のLinuxツールを使用してバイナリを探索する

Linuxでバイナリファイルを分析する10の方法 、Linuxの豊富なネイティブツールセットを使用してバイナリを分析する方法を説明しました。ただし、バイナリをさらに詳しく調べたい場合は、バイナリ分析用にカスタムメイドされたツールが必要です。バイナリ分析に不慣れで、主にスクリプト言語を使用したことがある場合は、9つの重要なGNUbinutilsツール コンパイルプロセスとバイナリを構成するものの学習を開始するのに役立ちます。

なぜ別のツールが必要なのですか?

その他のLinuxリソース

  • Linuxコマンドのチートシート
  • 高度なLinuxコマンドのチートシート
  • 無料のオンラインコース:RHELの技術概要
  • Linuxネットワーキングのチートシート
  • SELinuxチートシート
  • Linuxの一般的なコマンドのチートシート
  • Linuxコンテナとは何ですか?
  • 最新のLinux記事

既存のLinuxネイティブツールが同様のことを行うのに、なぜさらに別のツールが必要なのかを尋ねるのは自然なことです。それは、携帯電話を目覚まし時計として使用したり、メモを取ったり、カメラとして使用したり、音楽を聴いたり、インターネットをサーフィンしたり、時には電話をかけたり受けたりするのと同じ理由です。以前は、写真を撮るための物理的なカメラ、メモをとるための小さなメモ帳、目を覚ますためのベッドサイドの目覚まし時計など、別々のデバイスとツールがこれらの機能を処理していました。 1つのデバイスで複数の(ただし関連する)ことを実行できるのは便利です ユーザーのために。また、キラー機能は相互運用性です。 別々の機能の間。

同様に、多くのLinuxツールには特定の目的がありますが、同様の(そしてより優れた)機能を単一のツールにバンドルすることは非常に役立ちます。これが、バイナリを操作する必要があるときはいつでもRadare2が頼りになるツールになるべきだと私が思う理由です。

Radare2(r2とも呼ばれます)は、GitHubプロファイルによると、「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 
$ cdradare2
$ sys / user.sh

#バージョン

$ r2 -v
radare2 4.6.0-git 25266 @ linux-x86-64 git.4.4.0-930-g48047b317
commit:48047b3171e6ed0480a71a04c3693a0650d03543ビルド:2020-11-17__09:31 :03
$
サンプルテストバイナリを取得する

r2がインストールされたので、試してみるにはサンプルバイナリが必要です。任意のシステムバイナリ(ls)を使用できます 、bash 、など)。ただし、このチュートリアルを簡単にするために、次のCプログラムをコンパイルします。

 $ cat adder.c 
#include

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ビットLSB実行可能、x86-64、バージョン1(SYSV)、動的リンク、インタープリター/lib64/ld-linux-x86-64.so.2、GNU / Linux 3.2.0用、BuildID [sha1] =9d4366f7160e1ffb46b14466e8e0d70f10de2240、削除されていません
$
$ ./adder
現在の数値は:101
$
バイナリをロードする

バイナリを分析するには、Radare2にロードする必要があります。 r2へのコマンドライン引数としてファイルを指定してロードします 指図。シェルとは別のRadare2コンソールに移動します。コンソールを終了するには、終了と入力します または終了 またはCtrlを押します + D

 $ r2 ./adder 
-まるでレーダーのようにパンケーキを学びましょう!
[0x004004b0]> quit
$
バイナリを分析する

バイナリを探索する前に、r2に分析を依頼する必要があります。 aaaを実行することでそれを行うことができます r2コンソールのコマンド;

 $ r2 ./adder 
-申し訳ありませんが、radare2で内部エラーが発生しました。
[0x004004b0]>
[0x004004b0]>
[0x004004b0]> aaa
[x]symで始まるすべてのフラグを分析します。およびentry0(aa)
[x]関数呼び出しの分析(aac)
[x]参照用の命令のlenバイトの分析(aar)
[x]vtablesのチェック
[ x]すべての関数のタイプマッチング分析(aaft)
[x]ノーリターン情報の伝達
[x]-AAまたはaaaaを使用して追加の実験分析を実行します。
[0x004004b0]>
>

つまり、分析用のバイナリを選択するたびに、aaaに追加のコマンドを入力する必要があります。 バイナリをロードした後。 -Aを指定してr2を呼び出すことにより、これを回避できます。 バイナリ名が続きます。これにより、r2にバイナリを自動分析するように指示されます:

 $ r2 -A ./adder 
[x]symで始まるすべてのフラグを分析します。およびentry0(aa)
[x]関数呼び出しの分析(aac)
[x]参照用の命令のlenバイトの分析(aar)
[x]vtablesのチェック
[ x]すべての関数のタイプマッチング分析(aaft)
[x]ノーリターン情報の伝達
[x]-AAまたはaaaaを使用して、追加の実験分析を実行します。
-すでに最大-日付。
[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
コンパイラ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
machineAMDx86-64アーキテクチャ
maxopsz16
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 
[インポート]
nth vaddr bind type lib name
――――――――――――――――――――― ――――――――――――――――
1 0x00000000 WEAK NOTYPE _ITM_deregisterTMCloneTable
2 0x004004a0 GLOBAL FUNC printf
3 0x00000000 GLOBAL FUNC WE __libc_start_ NOTYPE __gmon_start __
5 0x00000000 WEAK NOTYPE _ITM_registerTMCloneTable

バイナリには、独自のシンボル、関数、またはデータを含めることもできます。これらの関数は通常、Exportsの下に表示されます 。テストバイナリには、エクスポートされる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 006 0x00000658 0x00400658 GLOBAL FUNC 0
90 0x00000596 0x00400596 GLOBAL FUNC 15加算器
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 ---- -0x00601024 GLOBAL NOTYPE 0 __bss_start
99 0x00000 5a5 0x004005a5 GLOBAL FUNC 55 main
100 ---------- 0x00601028 GLOBAL OBJ 0 __TMC_END __
102 0x00000468 0x00400468 GLOBAL FUNC 0 <04 <04
ハッシュ情報

2つのバイナリが類似しているかどうかをどうやって知ることができますか?バイナリを正確に開いて、その中のソースコードを表示することはできません。ほとんどの場合、バイナリのハッシュ(md5sum、sha1、sha256)を使用して一意に識別します。 itを使用してバイナリハッシュを見つけることができます コマンド:

 [0x004004b0]> it 
md5 7e6732f2b11dec4a0c7612852cede670
sha1 d5fa848c4b53021f6570dd9b18d115595a2290ae
sha256 13dd5a492219dac1443a816ef5f91db8d149e8ed 関数

コードは関数にグループ化されています。バイナリ内に存在する関数を一覧表示するには、aflを実行します 指図。次のリストは、主な機能と加算機能を示しています。通常、sym.impで始まる関数 標準ライブラリ(この場合はglibc)からインポートされます:

 [0x004004b0]> afl 
0x004004b0 1 46 entry0
0x004004f0 4 41-> 34 sym.deregister_tm_clones
0x00400520 _ s> 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メイン
0x004004a0 1~6 sym.imp.printf
0x00400468 3 27 SYM。 _init
[0x004004b0]>
相互参照

Cでは、主な機能はプログラムが実行を開始する場所です。理想的には、他の関数はmainから呼び出され、プログラムを終了すると、main関数は終了ステータスをオペレーティングシステムに返します。これはソースコードで明らかです。しかし、バイナリはどうですか?加算器関数がどこで呼び出されているかをどのように判断できますか?

axtを使用できます コマンドの後に関数名を続けて、加算器関数が呼び出される場所を確認します。以下に示すように、これはmain関数から呼び出されます。これは相互参照として知られています。しかし、何がメイン関数自体を呼び出すのでしょうか? axt main 以下の関数は、entry0によって呼び出されることを示しています (entry0については学習しません。 読者のための演習として):

 [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を使用できます コマンドの後に関数名を続けて、特定の関数アドレスにジャンプします。同様に、バイナリの先頭にジャンプする場合は、s 0と入力します。 :

 [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
-オフセット-01 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 cbfeffff..x。@...........
0x004005d5 b800 0000 00c9 c30f 1f40 00f3 0f1efa41......。 .. @ ..... A
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 77206973...現在の番号は
0x004006852020 3a20 2564 0a00 0000 0001 1b03 3b44:%d ........; D
0x00400695 0000 0007 0000 0000 feff ff88 0000 0020 ...............
[0x004005a5]>
分解

コンパイルされたバイナリを使用している場合、表示できるソースコードはありません。コンパイラは、ソースコードをCPUが理解して実行できる機械語命令に変換します。結果はバイナリまたは実行可能ファイルです。ただし、アセンブリ命令(ニーモニック)を表示して、プログラムが実行していることを理解することができます。たとえば、メイン関数が何をしているのかを知りたい場合は、s mainを使用してメイン関数のアドレスを探すことができます。 次に、pdfを実行します 分解手順を表示するコマンド。

アセンブリ手順を理解するには、アーキテクチャマニュアル(この場合はx86)、そのアプリケーションバイナリインターフェイス(ABI、または呼び出し規約)を参照し、スタックがどのように機能するかについての基本的な理解が必要です。

 [0x004004b0]> s main 
[0x004005a5]>
[0x004005a5]> s
0x4005a5
[0x004005a5]>
[0x004005a5]> pdf
; entry0@0x4004d1からのDATAXREF
┌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プッシュRBP
│0x004005a6 4889e5 MOV RBP、RSP
│0x004005a9 4883ec10サブ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コール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; "現在の番号は次のとおりです:%d \ n"; const char * format
│0x004005cbb800000000mov eax、0
│0x004005d00x004005d0e8cbfeffff call sym.imp.printf; INTのprintf(CONST文字*形式)
│0x004005d5 b800000000 MOV EAX、0
│0x004005da C9残す
└0x004005db C3 RET
[0x004005a5]>

加算器関数の逆アセンブルは次のとおりです。

 [0x004005a5]> s sym.adder 
[0x00400596]>
[0x00400596]> s
0x400596
[0x00400596]>
[0x00400596]> pdf
; main @0x4005b9からXREFを呼び出します
┌15:sym.adder(int64_t arg1);
│; var int64_t var_4h @ rbp-0x4
│;引数int64_tのARG1 @ RDI
│0x00400596 55プッシュRBP
│0x00400597 4889e5 MOV RBP、RSP
│0x0040059a 897dfc MOV DWORD [var_4h]、EDI。 ARG1
│0x0040059d 8b45fc MOV EAX、DWORD [var_4h]
│0x004005a0 83c001追加EAX、1
│0x004005a3 5Dポップ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は:%d \ n

[0x004004b0]>
相互参照文字列

関数と同様に、文字列を相互参照して、文字列がどこから印刷されているかを確認し、文字列の周囲のコードを理解することができます。

 [0x004004b0]> ps @ 0x400678 
現在の番号は次のとおりです:%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 
PID17453のプロセスが開始されました...
=attach 17453 17453
bin.baddr 0x00400000
0x400000の使用
asm.bits 64
[x]symで始まるすべてのフラグを分析します。およびentry0(aa)
[x]関数呼び出しの分析(aac)
[x]参照用の命令のlenバイトの分析(aar)
[x]vtablesのチェック
[ x]すべての関数のタイプマッチング分析(aaft)
[x]ノーリターン情報の伝達
[x]-AAまたはaaaaを使用して、追加の実験分析を実行します。
-git checkout hamster
[0x7f77b0a28030]>
[0x7f77b0a28030]> db main
[0x7f77b0a28030]>
[0x7f77b0a28030]> db sym.adder
[0x7f77b0a28030]>
[0 ]> 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
ヒットブレークポイント:0x4005a5
[0x /> [0x004005a5]> dbt
0 0x4005a5 sp:0x0 0 [main] main sym.adder + 15
1 0x7f77b0687873?
2 0x7f77b0a36e0a sp:0x7ffe35ff68e8 144 [??] map.usr_lib64_ld_2.28.so.r_x + 65034
[0x004005a5]> dc
ヒットブレークポイント:0x400> DBT
0 0x400596 SP:0x0の0 [sym.adder] RIP entry.init0 + 6
1 0x4005be SP:0x7ffe35ff6838 0 [メインメイン+ 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
[0x00 [0x00400596]>
[0x00400596]> dr
rax =0x00000064
rb x =0x00000000
rcx =0x7f77b0a21738
rdx =0x7ffe35ff6948
r8 =0x7f77b0a22da0
r9 =0x7f77b0a22da0
r10 =0x0000000f
r11 =0x000000 =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を使用して現在のプラグインを表示する 指図。サンプルのr2decをインストールします r2pm installを使用した逆コンパイラ コマンド:

 $ r2pm -l <​​br /> $ 
$ r2pm install r2dec
'r2dec'へのクローン作成...
リモート:オブジェクトの列挙:100、完了。
リモート:オブジェクトのカウント:100%(100/100)、完了。
リモート:オブジェクトの圧縮:100%(97/97)、完了。
リモート:合計100(デルタ18)、再利用27(デルタ1)、パック再利用0
オブジェクトの受信:100%(100/100)、1.01 MiB | 1.31 MiB / s、完了。
デルタの解決:100%(18/18)、完了。
r2decのインストール完了
gmake:ディレクトリ'/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:ディレクトリを離れる'/root/.local/share/radare2/r2pm/git/r2dec/p'
$
$ r2pm -l <​​br /> r2dec
$
逆コンパイラビュー

バイナリを逆コンパイルするには、バイナリをr2にロードし、自動分析します。 s sym.adderを使用して、目的の関数(この例では加算器)に移動します。 コマンドを実行してから、pddaを使用します アセンブリと逆コンパイルされたソースコードを並べて表示するコマンド。この逆コンパイルされたソースコードを読むことは、多くの場合、アセンブリを1行ずつ読むよりも簡単です。

 $ r2 -A ./adder 
[x]symで始まるすべてのフラグを分析します。およびentry0(aa)
[x]関数呼び出しの分析(aac)
[x]参照用の命令のlenバイトの分析(aar)
[x]vtablesのチェック
[ x]すべての関数のタイプマッチング分析(aaft)
[x]ノーリターン情報の伝達
[x]-AAまたはaaaaを使用して追加の実験分析を実行します。
-何をしたいですか今日デバッグしますか?
[0x004004b0]>
[0x004004b0]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[ 0x00400596]>
[0x00400596]> pdda
;アセンブリ| /*r2dec擬似コード出力*/
| / * ./adder @ 0x400596 * /
| #include
|
; (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 eaxを追加、1 | eax ++;
0x004005a3 pop rbp |
0x004005a4 ret | return eax;
| }
[0x00400596]>
設定を構成する

Radare2に慣れてきたら、構成を変更して、作業方法に合わせて調整することをお勧めします。 eを使用して、r2のデフォルト構成を表示できます。 指図。特定の構成を設定するには、config = valueを追加します eの後 コマンド:

 [0x004005a5]> e | wc -l <​​br /> 593 
[0x004005a5]> e | grep構文
asm.syntax=intel
[0x004005a5]>
[0x004005a5]> e asm.syntax =att
[0x004005a5]>
[0x004005a5]> e || grep構文
asm.syntax=att
[0x004005a5]>

構成の変更を永続的にするには、それらを.radare2rcという名前のスタートアップファイルに配置します。 そのr2は起動時に読み取ります。このファイルは通常、ホームディレクトリにあります。そうでない場合は、作成できます。構成オプションの例は次のとおりです。

 $ cat〜/ .radare2rc 
e asm.syntax =att
e scr.utf8 =true
eco solarized
e cmd.stack =true
e stack.size =256
$
もっと探索する

ツールを回避する方法を見つけるのに十分なRadare2機能を見てきました。 Radare2はUnix哲学に従っているため、コンソールからさまざまなことを実行できますが、その下にある別のバイナリセットを使用してタスクを実行します。

以下にリストされているスタンドアロンバイナリを調べて、それらがどのように機能するかを確認してください。たとえば、iIを使用してコンソールに表示されるバイナリ情報 コマンドは、rabin2 <binary>を使用して見つけることもできます コマンド:

 $ cd bin / 
$
$ ls
prefix r2agent r2pm rabin2 radiff2 ragg2 rarun2 rasm2
r2 rah 2 rah 2 rah 2 rah 2 rafind / pre>

Radare2についてどう思いますか?コメントでフィードバックを共有してください。


Linux
  1. このオープンソースツールを使用してELFバイナリの機能を検査します

  2. このオープンソースツールを使用してLinuxメモリフォレンジックを実行します

  3. LinuxでプロのようにGNOMEスクリーンショットツールを使用する

  1. このLinuxツールとのオープンソースファイル共有

  2. ProcDumpを使用してLinuxをデバッグする

  3. diff3ツールを使用してLinuxで3つのファイルを比較する方法

  1. このLinuxコマンドラインツールでメモリ使用統計を取得する

  2. PiperGUIツールを使用してLinuxでゲーミングマウスを構成する方法

  3. Scalpelデータ回復ツールを使用してLinuxで削除されたファイルを回復する方法は?