1

私は pintool を初めて使用しBBL_NumINS < 7、Indirect Jump、Indirect Call、ret などの特定の Tail 命令を使用して、連続する Basic Block の数をカウントしたいと考えています。だから私はこのコードを書いた

static UINT32 consecutiveBasicBlockscount = 0;
//------------------------------------------------------------------------------------------
// This function is called before every block
VOID docount()
{
    OutFile << "Inc Consecutive Basic Block Counter From " <<consecutiveBasicBlockscount<<"\tto "<<consecutiveBasicBlockscount+1<< endl;
    OutFile << "----------------------------------------------------------------------------------------" <<endl;
    consecutiveBasicBlockscount += 1;
}

for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl))
    {
        INS insTail =  BBL_InsTail(bbl);              
        if(INS_IsIndirectBranchOrCall(BBL_InsTail(bbl)))
            {
                if((!INS_IsCall(insTail) && !INS_HasFallThrough(insTail) && !INS_IsHalt(insTail) && !INS_IsRet(insTail))||(INS_IsCall(insTail) && !INS_HasFallThrough(insTail) && !INS_IsHalt(insTail) && !INS_IsRet(insTail)) || INS_IsRet(insTail))
                    {
                        if (BBL_NumIns(bbl) < 7)
                            {
                                OutFile << "*****"<< hex << BBL_Address(bbl) <<"*****"<<endl;
                                for(INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins=INS_Next(ins))
                                    {
                                        OutFile << INS_Disassemble(ins) <<endl;
                                    }
                                OutFile << "********************************" <<endl;

                                BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
                  }
                             }
          }
   }

出力ファイル

----------------------------------------------------------------------------------------
Inc Consecutive BasicBlock Counter From 0    to 1
----------------------------------------------------------------------------------------
*****b6709ba0*****
mov eax, 0xc9
call dword ptr gs:[0x10]
********************************
Inc Consecutive BasicBlock Counter From 1    to 2
----------------------------------------------------------------------------------------
Inc Consecutive BasicBlock Counter From 2    to 3
----------------------------------------------------------------------------------------
Inc Consecutive BasicBlock Counter From 3    to 4
----------------------------------------------------------------------------------------
*****b6709bac*****
ret
********************************
Inc Consecutive BasicBlock Counter From 4    to 5
----------------------------------------------------------------------------------------

この pintool を firefox に対してテストします。カウンタが 0、2、3 の場合、ピンに基本ブロックが表示されないのはなぜですか?

4

1 に答える 1

1

私があなたの質問を完全に誤解していない限り、バイナリの具体的な実行中にすべてのインスタンスを見つけたいと考えています。ここでは、最終命令 (テール) として間接呼び出し/ジャンプまたは ret 命令を持つ複数の基本ブロックが次々に実行されます。

PIN ツールを書き始めると、分析コードとインストルメンテーション コードの違いにかなり混乱することがあります。PIN は動的なバイナリ インストルメンテーション フレームワークですが、記述したコードは静的コンテキストまたは動的コンテキストのいずれかに存在できます。インストルメンテーション コード(たとえば、フックを介してマップTRACE_AddInstrumentFunction) は静的コンテキストで実行されます。つまり、基本ブロックが検出されるたびに実行されるのではなく、新しい基本ブロックをインストルメントする必要がある場合にのみ実行されます。分析コード(BBL_InsertCall一方、フックは動的コンテキストに存在します。つまり、基本ブロックが実行されるたびに実行されます。実際、分析中のバイナリは、PIN ツールの分析コードと一緒にメモリ (コード キャッシュと呼ばれます) に再コンパイルされます。

私があなたの質問を正しく理解していれば、あなたのコードはこれらのコンテキストを混ぜ合わせて、0-1 3-4 の出力が何よりも偶然になるようにします。長さ 2 以上の間接基本ブロックのすべてのチェーンを一覧表示する単純な PIN ツールを作成しました。BBL_InsertCall ドキュメントをもう少し調べれば、asm 命令を出力するように変更するのは簡単です。


主要

instrument_traceこのコードは、まだ計測されていない基本ブロックが検出されるたびに関数を呼び出すように PIN に指示します。簡単にするために、構造を単純化するためにいくつかのグローバル変数も宣言します。

#include "pin.H"
#include <iostream>
#include <vector>

std::vector<ADDRINT>* consecutive_indirect_bbls = new std::vector<ADDRINT>();
std::ostream& Output = std::cout;

int main(int argc, char *argv[]) {
    if (PIN_Init(argc, argv) == 0) {
        TRACE_AddInstrumentFunction(instrument_trace, NULL);
        PIN_StartProgram();
    }

    return 0;
}

インストゥルメント_トレース

これは、まだインストルメント化されていない基本ブロックが PIN によって検出されるたびに実行されるコードです。これは基本的に、いくつかの重要な変更を加えた、質問で提供したのと同じコードです。インストルメンテーション コードは、分析中のバイナリの実行フローを監視できるように分析コードを設定することのみを目的としています。分析中のバイナリは、このコードの実行時に実際には実行されませんが、「一時停止」しているように見えます。

関心のある呼び出しチェーンを出力するには、そのような呼び出しチェーンの直後に続く基本ブロックに分析呼び出しを挿入する必要もあります。これは、呼び出しチェーンを表示する方法が他にないためです。チェーンを壊します。このロジックは、少し遊んでみれば明らかです。

VOID instrument_trace(TRACE trace, VOID* vptr) {
    for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
        INS tail = BBL_InsTail(bbl);
        if ((INS_IsIndirectBranchOrCall(tail) || INS_IsRet(tail))
                && BBL_NumIns(bbl) < 7) {
            BBL_InsertCall(bbl, IPOINT_BEFORE,
                    (AFUNPTR) analysis_indirect_bbl,
                    IARG_ADDRINT, BBL_Address(bbl),
                    IARG_END);
        } else {
            BBL_InsertCall(bbl, IPOINT_BEFORE,
                    (AFUNPTR) analysis_print_vector,
                    IARG_END);
        }
    }
}

analysis_indirect_bbl

この関数は、監視しているバイナリで間接呼び出し/ジャンプまたは ret 命令で終了する基本ブロックが実行されるたびに呼び出されます。これが発生するたびに、その基本ブロックの開始アドレスを、これらのチェーンを追跡するために使用するグローバル ベクトルにプッシュします。

VOID analysis_indirect_bbl(ADDRINT address) {
    consecutive_indirect_bbls->push_back(address);
}

analysis_print_vector

これは、関心のある呼び出しチェーンを出力する関数にすぎませんOutput(std::outこの例では)。

VOID analysis_print_vector() {
    if (consecutive_indirect_bbls->size() > 2) {
        for (unsigned int i = 0;
                i < consecutive_indirect_bbls->size();
                ++i) {
            Output << "0x" << std::hex
                    << consecutive_indirect_bbls->at(i) << " -> ";
        }

        Output << "END" << std::endl;
        consecutive_indirect_bbls->clear();
    } else if (!consecutive_indirect_bbls->empty()) {
        consecutive_indirect_bbls->clear();
    }
}

PIN ツールをテストする場合、まったく同じ実行フローに対して変更をテストすることは不可能であるため、firefox などのプログラムを実行しないことを強くお勧めします。実行の長さを制御するのは非常に簡単なので、通常は自分で gzip に対してテストします。

$ lorem -w 500000 > sample.data
$ cp sample.data sample_exec-001.data
$ pin -injection child -t obj-ia32/cbbl.so -- /bin/gzip -9 sample_exec-001.data

0xb775c7a8 -> 0xb774e5ab -> 0xb7745140 -> END
0xb775c7a8 -> 0xb774e5ab -> 0xb7745140 -> END
0xb775c7a8 -> 0xb774e5ab -> 0xb7745140 -> END
0xb775b9ca -> 0xb7758d7f -> 0xb77474e2 -> END
0xb5eac46b -> 0xb5eb2127 -> 0xb5eb2213 -> END
0xb5eac46b -> 0xb5eb3340 -> 0xb5eb499e -> END
0xb5eac46b -> 0xb5eb3340 -> 0xb5eb499e -> END

...

0xb5eac46b -> 0xb5eb3340 -> 0xb5eb499e -> END
于 2014-06-28T10:54:47.457 に答える