

"""
このレジスタは何に使うんだっけ?
うーん…名前をveryuniquenameに変えて、テキスト検索で全参照を見つけよう!
よし…検索が終わるのを待とう…もうすぐだ…完了!
あとは検索結果の中から、レジスタの現在の使用フレームに関係あるものを判断するだけだ。
そんなに難しくないはずだよね?
"""
もしこんなことがあったなら(おそらく一度や二度ではないでしょう)、あなたはラッキーです! Shift-X を押すだけで、悩みが解消されます!
使用フレーム内でレジスタの名前を変更することもできます。Shift-N を押して、指示に従ってください! さらに、すべての使用箇所の型を特定の型に一括変更するには、Shift-T を1回押すだけです。
そして最後に、このレジスタの全使用箇所にオフセットを設定したい場合(Ctrl-R のように)は、Shift-R を押してください。
注意:すでに Shift-T を使っている別のプラグインが存在する場合があります。そのプラグインを削除してください — 今まで使ったことないはずですから :-)。
このプラグインは sark を使用して IDA スクリプトと快適に連携し、cachetools を使用してフレームスキャンをキャッシュすることで大幅に高速化しています。
Oregami は IDA 7.x/8.x と IDA 9.0+ の両方をサポートします。 IDA 9 を使用する場合は、IDA 9 をサポートする最新バージョンの sark がインストールされていることを確認してください。
注意:IDA 9 には独自の Shift-X 機能が導入されました。Oregami の代わりに IDA 組み込みの Shift-X を使用する必要がある場合は、プラグインファイル内の Oregami のショートカットを変更してください。
[Python3 の場合] pip3 install sark
[Python2 の場合] IDA で Python2 を使用している場合は、代わりに以下を実行してください: pip2 install -U git+https://github.com/tmr232/[email protected]#egg=Sark
Python2 は積極的にはサポートされていません(IDA は主に Python3 に移行しており、私も同様です)。そのため、動作しない可能性があります。
git clone https://github.com/shemesh999/oregami
sark コードベースには多くのプラグインが含まれています。そのうちのひとつが以下です: https://github.com/tmr232/Sark/blob/master/plugins/plugin_loader.py
これをプラグインディレクトリにコピーし、管理者権限で IDA を一度実行することをお勧めします(plugins.list ファイルを作成するため)。 その後、作成された plugins.list ファイル(例:IDA の cfg フォルダに作成されるもの)のいずれかに新しいプラグインのパスを追加することで、プラグインを追加できます。
次に、いずれかの plugins.list ファイルに以下を追加します: FULLPATH\oregami\oregami_plugin.py FULLPATH\oregami\regname_plugin.py FULLPATH\oregami\typeregter_plugin.py FULLPATH\oregami\offreg_plugin.py
IDA を再起動すると、プラグインが動作するはずです。
別の方法: すべてのファイル(内部の oregami フォルダを含み、setup.py は除く)を IDA のプラグインディレクトリにコピーします。
プラグインとして使用するだけでなく、Oregami を使って独自のスクリプトを書くこともできます!
そのためには、まず同梱の setup.py を使用してインストールしてください。つまり、次のコマンドを実行します: 'python setup.py develop' その後、内部クラスや関数を使用できるようになります。 'install' ではなく 'develop' を使用することをお勧めします。これにより、新しいバージョンの Oregami をプルした場合でも、そのまま動作します。
例: -- script.py --
def find_func_usage(func_ea, reg='r0'):
"""
レジスタのすべての使用箇所を検索し、そのオペランドの情報や
オペランド内での操作を表示します。
"""
import oregami
rf = oregami.RegFrame(func_ea, reg)
for insn in rf.get_instructions():
print('Addr:{:x}'.format(insn.ea))
for opnd in insn.operands:
if opnd.uf_is_external:
continue
print('--opnd_idx:{} - {}'.format(opnd.n, oregami.UsageBits(opnd.op_flags)))
次のようなオペコードのシーケンスを考えます:
ROM:01000010 e_lis r10, 0x4004 # 0x40040000 # Load Immediate Shifted
ROM:01000014 e_add16i r10, r10, 0x1337 # 0x40041337 # Add Immediate
ROM:01000020 se_mr r30, r31 # Move Register
ROM:01000022 cmplw r11, r10 # Compare Logical Word
ROM:01000026 se_bge loc_1000036 # Branch if greater than or equal
ROM:01000028
ROM:01000028 loc_1000028: # CODE XREF: sub_0100000+144↓j
ROM:01000028 e_stmw r30, 0(r11) # Store Multiple Word
ROM:0100002C e_add16i r11, r11, 8 # Add Immediate
ROM:01000030 cmplw r11, r10 # Compare Logical Word
ROM:01000034 se_blt loc_1000028 # Branch if less than
ROM:01000036
ROM:01000036 loc_1000036: # CODE XREF: sub_0100000+136↑j
ROM:01000036 e_add16i r10, r10, 8 # Add Immediate
ROM:0100003A e_li r11, 0 # Load Immediate
アドレス 01000022 から始まる r10 レジスタの使用フレームをスキャンすると、使用フレームには3つのタイプの使用が含まれます。
レジスタの値を初期化する命令が含まれます。 レジスタの値を変更した最後の命令のみ(例ではアドレス 01000014)を含めることも、レジスタの初期値設定に使用された一連の操作(例ではアドレス 01000010 と 01000014)を含めることもできます。 レジスタの初期化に使用される一連の操作を「初期化ステージ」と呼ぶことがあります。 RegFrame の初期化における init_stage_bool パラメータに応じて、初期化ステージをサポートするかどうかを選択できます。
レジスタの値を使用するが、値をまったく変更しない命令が含まれます。例ではアドレス 01000022 と 01000030 に対応します。
レジスタの値を使用するが、その後値を変更する命令が含まれます。これらの命令は、2つの異なる使用フレーム(ひとつはそれにつながるフレーム、もうひとつはそこから派生するフレーム)に含まれると見なせます。 例ではアドレス 01000036 に対応します。
使用フレームをスキャンする際、初期化操作またはブレーク操作に到達すると、特定の方向へのスキャンが停止します。 しかし、使用フレーム外の命令によってスキャンが停止することもあります。 例えば、アドレス 01000030 から始まる r11 レジスタの使用フレームをスキャンすると、アドレス 0100003A で停止します。
これは Oregami で使用される基本クラスです。アドレスと特定のレジスタを指定して初期化すると、そのレジスタの使用フレームをスキャンし、関連するすべての命令に対して UFInstruction を作成します。 get_instruction - 指定されたアドレスの命令を取得します get_instructions - 使用フレーム内の命令を返すジェネレータです。
特定のサブセットの命令だけを要求することもできます: get_init_instructions - 初期化タイプの命令のみを取得 get_pure_instructions - 純粋使用タイプの命令のみを取得 get_break_instructions - ブレークタイプの命令のみを取得 get_nobreak_instructions - ブレークタイプではない命令(すなわち初期化+純粋使用)を取得 get_noinit_instructions - 初期化タイプではない命令(すなわち純粋使用+ブレーク)を取得 get_outbreak_instructions - アウトブレークタイプの命令のみを取得
デフォルトでは、このクラスはスキャン結果をキャッシュし、同じ使用フレームの再スキャンを防ぎます。 つまり、使用フレームの一部であった命令(特に初期化+純粋使用タイプ。ブレークは、その命令からスキャンを開始すると、そこから派生する使用フレームが返されるため含まれません)に対して RegFrame を要求すると、同じ事前計算された RegFrame インスタンスが返されます。 再スキャンを強制するには、クラス初期化時に force フラグを使用します。
RegFrame によって返されるクラスで、使用フレーム内の命令を表します。 このクラスは sark の Instruction クラスを継承しており、同じメソッドをサポートします。 主な違いのひとつは、sark の Operand クラスの配列ではなく、UFOperand クラスの配列を含むことです。 また、このクラスは命令のタイプ(init、pure、break、outbreak)や操作ビット(読み取り、書き込み、明示的、およびさまざまな暗黙的タイプ)を理解するためのメソッドも含みます。
特定の UFInstruction 内のオペランド配列に含まれるクラスです。 このクラスは sark の Operand クラスを継承しており、同じメソッドをサポートします。 sark の操作に加えて、操作ビット(読み取り、書き込み、明示的、およびさまざまな暗黙的タイプ)を取得するメソッドや、オペランドが実際に使用フレームの一部であるかどうかを判断するメソッド(ブレークタイプの命令でどのオペランドが使用フレームに含まれるかを知るのに便利)を含みます。
特定の命令を解析し、レジスタに関する使用状況を把握するためのクラスです。 IDA の知識、テキスト解析、およびプロセッサ固有の詳細情報を使用します。 このクラスが存在する理由は、基本的な IDA 解析では、多くのオペコードで使用されるレジスタのセットや使用方法について誤った情報を提供する傾向があるためです。 このクラスは sark の Instruction クラスを継承しており、同じメソッドをサポートします。 主な違いのひとつは、sark の Operand クラスの配列ではなく、RegOperand クラスの配列を含むことです。
特定のオペランドを解析し、レジスタに関する使用状況を把握するためのクラスです。 IDA の知識、テキスト解析、およびプロセッサ固有の詳細情報を使用します。 このクラスが存在する理由は、基本的な IDA 解析では、多くのオペコードで使用されるレジスタのセットや使用方法について誤った情報を提供する傾向があるためです。 このクラスは sark の Operand クラスを継承しており、同じメソッドをサポートします。