
Astaroth/GuildmaインジェクタDLLの難読化を解除するためのIDA Pythonスクリプト
Astaroth/Guildma インジェクタDLLの難読化を解除するためのIDA Pythonスクリプト
最近の Astaroth/Guildma キャンペーンのインジェクタDLLを分析しようとしたとき(SANS ISC のこの日記に感謝)、本当に 迷惑な難読化の試みに出くわしました。
ある関数(下の画像では time_waster_3000 と呼んでいます)がDLL全体で1,000回以上(!!!)呼び出されています。この関数は、ランダムな word とともに、6つのハードコードされた文字列を引数として受け取ります。この関数自体は、私が見た限り実用的な目的を果たさない算術の迷宮です(リバーサーの時間を無駄にする以外は)。DLLEntry がそれらの迷惑な呼び出しを含む様子は次のとおりです:
このIDA Pythonスクリプトの目的は、このジャンク関数への呼び出しとその引数を含むすべてのコードブロックを非表示にすることです。スクリプト実行後の DLLEntry の様子は次のとおりです:
このスクリプトは、パディング関数への呼び出し(スクリプト内では call sub_CHANGEME で表されます)を見つけることで動作します。したがって、扱っているサンプルで見つかった関数名にスクリプト内の名前を変更する必要があります。たとえば、idc.print_operand(x, 0) == 'sub_CHANGEME' を idc.print_operand(x, 0) == 'sub_431000' に変更します。
引数のプッシュではなく call sub_CHANGEME 命令を反復処理することを選択しました。その理由は単純です。ハードコードされた文字列はバイナリ全体の複数の場所に存在するため、それらの文字列のオフセットを含むプッシュ命令を検索しようとすると、スクリプトはこのジャンクデータのすべてのインスタンスを見つけられなかったからです。
以前のスクリプトは、引数の受け渡しとパディング関数への呼び出しの各インスタンスを1つの折り畳まれたブロックとして非表示にしていました。この関数は連続して複数回呼び出されるため、逆アセンブリビューに巨大な空白が生じていました。このパディングの連続するインスタンスを1つの折り畳まれたブロックにまとめて非表示にするように更新しました。これにより、可読性が本当に向上します。