2

小さな静的ライブラリ(.a)があります。静的ライブラリには、静的に割り当てられた大きな1D配列を指すポインタがあります。

コードをこのライブラリにリンクすると、ポインタのアドレスがさまざまな場所にハードコードされ、逆アセンブルで簡単に見つけることができます。問題は、コードがこの配列にアクセスできるようにしたいことです(ライブラリに障害があり、その理由を知りたい)。

当然、そのアドレスを逆アセンブルし、コードにハードコーディングしてから再コンパイルすることで、そのポインターを取得するのは簡単です。ライブラリを他のモジュールとは異なる方法で構成でき、どのモジュールがリンクされているかによって配列のポインターが変わることを除けば、これは問題にはなりません。

そのポインタを取得するための私のオプションは何ですか?配列の開始状態は予測可能であるため、適切に見えるものが見つかるまで、メモリをウォークスルーし、シグナルハンドラーを使用してsegfaultをキャッチできます。もっと良い方法はありますか?

4

1 に答える 1

4

あなたのライブラリは.aアーカイブなので、何らかの UNIX を使用していると仮定します。

グローバル配列には、それに関連付けられた記号名が必要です。あなたの仕事は、それを表すシンボルの種類に応じて、簡単になったり難しくなったりします。

この配列を記述するグローバルシンボルがある場合は、それを直接参照できます。

extern char some_array[];
for (int i = 0; i < 100; i++) printf("%2d: 0x%2x\n", i, some_array[i]);

シンボルがローカルの場合は、最初に でグローバル化してobjcopy --globalize-symbol=some_arrayから、上記の手順に進みます。

では、その配列を表す記号が何であるかをどのように判断できるのでしょうか? Runには、その配列を参照することがわかっている命令objdump -dr foo.oが含まれています。foo.o参照命令の横に表示される再配置は、名前を教えてくれます。

最後に、実行しnm foo.o | grep some_arrayます。が表示00000XX D some_arrayされたら完了です。配列はグローバルに表示されます ( も同じですB)。が表示されている場合は000XX d some_array、最初にグローバル化する必要があります (同様にb)。

アップデート:

-dr to objectdump が機能しませんでした

そうです、シンボルがローカルであることが判明したため、再配置はおそらく.bss + 0xNNN.

00000000006b5ec0 b grid
00000000006c8620 b grid
00000000006da4a0 b grid
00000000006ec320 b grid
00000000006fe1a0 b grid

アーカイブ内のnm個々のオブジェクトではなく、最終的にリンクされた実行可能ファイルで実行する必要があります。バイナリで呼び出されるfoo.o5 つの個別の静的配列があります。grid

「extern int grid[];」を宣言する それを使用すると、未定義の参照が与えられます

これはローカル シンボルの場合に予想されます。ライブラリ内のコードは次のようなものでした。

// foo.c
static char grid[1000];

最初にシンボルをグローバル化しないと、これgridを外部から参照することはできません。foo.o

セキュリティ上の理由から、サーバー上でライブラリの変更されたバイナリを実行することは許可されていません

その議論が完全なBSであることを理解していただければ幸いです。独自のコードをそのバイナリにリンクできれば、サーバー上で何でもできます(ユーザーIDの制限に従います)。あなたはすでに信頼されています。サードパーティのライブラリを変更することは、サーバーの管理者があなたを信頼していない場合、最も心配する必要はありません。

于 2012-04-27T03:53:58.640 に答える