バイナリにビルド情報を追加するためにldの--build-idオプションを使いたいと思います。しかし、私はどのようにプログラム内でこの情報を利用できるようにするか分からない。例外が発生するたびにバックトレースを書き込むプログラムと、この情報を解析するスクリプトを記述したいとします。スクリプトはプログラムのシンボルテーブルを読み込み、バックトレースに表示されているアドレスを検索します(プログラムが静的にリンクされ、backtrace_symbolsが機能しないため、このようなスクリプトを使用することを余儀なくされます)。スクリプトが正しく動作するためには、バックトレースを作成したプログラムのビルドバージョンとプログラムのビルドバージョンを一致させる必要があります。 .note.gnu.build-id elfセクションにあるプログラムのビルド版をプログラム自体から印刷するにはどうすればよいですか?プログラムは独自のelfセクションを読むことができますか?
答えて
プログラムのビルドバージョン(.note.gnu.build-id elfセクションにあります)をプログラム自体から印刷するにはどうすればよいですか?
はあなたが読む必要が
ElfW(Ehdr)
にプログラムヘッダを見つけるために(ファイルの先頭)あなたのバイナリ(.e_phoff
と.e_phnum
はプログラムヘッダがどこにあるかを教えてくれますし、それらを読むためにどのように多くの) 。次に、プログラムの
PT_NOTE
セグメントが見つかるまで、プログラムヘッダーを読み取ります。そのセグメントは、バイナリ内のすべてのノートの先頭にオフセットするよう指示します。.n_type == NT_GNU_BUILD_ID
でノートが見つかるまで、ElfW(Nhdr)
を読み、残りのメモ(合計ノートサイズはsizeof(Nhdr) + .n_namesz + .n_descsz
、正しく整列されています)をスキップする必要があります。NT_GNU_BUILD_ID
というメモが見つかったら、その.n_namesz
をスキップし、.n_descsz
バイトを読み取って実際のビルドIDを読み取ります。
あなたは、あなたがreadelf -n a.out
の出力と読んだものと比較することによって、右のデータを読んでいることを確認することができます。
P.S.代わりに
あなたの実行ファイルが取り除かれていない場合はあなただけのデコードおよび印刷するためにあなたは、上記のように、ビルドIDをデコードする手間を通過しよう、とされている場合、それは良いかもしれシンボル名(すなわちへbacktrace_symbols
を複製する) - 実際には、シンボルテーブルに固定サイズのエントリが含まれているため、ELFノートをデコードするよりも簡単です。
基本的に、これは私の質問に与えられた答えに基づいて書いたコードです。コードをコンパイルするために私はいくつかの変更を加えなければならず、できるだけ多くの種類のプラットフォームで動作することを願っています。ただし、1台のビルドマシンでのみテストされました。私が使用した仮定の1つは、プログラムが実行されるマシン上にプログラムが構築されているため、プログラムとマシンの間のエンディアンの互換性をチェックすることができませんでした。答えるため
[email protected]:~/$ uname -s -r -m -o
Linux 3.2.0-45-generic x86_64 GNU/Linux
[email protected]:~/$ g++ test.cpp -o test
[email protected]:~/$ readelf -n test | grep Build
Build ID: dc5c4682e0282e2bd8bc2d3b61cfe35826aa34fc
[email protected]:~/$ ./test
Build ID: dc5c4682e0282e2bd8bc2d3b61cfe35826aa34fc
#include <elf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#if __x86_64__
# define ElfW(type) Elf64_##type
#else
# define ElfW(type) Elf32_##type
#endif
/*
detecting build id of a program from its note section
http://stackoverflow.com/questions/17637745/can-a-program-read-its-own-elf-section
http://www.scs.stanford.edu/histar/src/pkg/uclibc/utils/readelf.c
http://www.sco.com/developers/gabi/2000-07-17/ch5.pheader.html#note_section
*/
int main (int argc, char* argv[])
{
char *thefilename = argv[0];
FILE *thefile;
struct stat statbuf;
ElfW(Ehdr) *ehdr = 0;
ElfW(Phdr) *phdr = 0;
ElfW(Nhdr) *nhdr = 0;
if (!(thefile = fopen(thefilename, "r"))) {
perror(thefilename);
exit(EXIT_FAILURE);
}
if (fstat(fileno(thefile), &statbuf) < 0) {
perror(thefilename);
exit(EXIT_FAILURE);
}
ehdr = (ElfW(Ehdr) *)mmap(0, statbuf.st_size,
PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(thefile), 0);
phdr = (ElfW(Phdr) *)(ehdr->e_phoff + (size_t)ehdr);
while (phdr->p_type != PT_NOTE)
{
++phdr;
}
nhdr = (ElfW(Nhdr) *)(phdr->p_offset + (size_t)ehdr);
while (nhdr->n_type != NT_GNU_BUILD_ID)
{
nhdr = (ElfW(Nhdr) *)((size_t)nhdr + sizeof(ElfW(Nhdr)) + nhdr->n_namesz + nhdr->n_descsz);
}
unsigned char * build_id = (unsigned char *)malloc(nhdr->n_descsz);
memcpy(build_id, (void *)((size_t)nhdr + sizeof(ElfW(Nhdr)) + nhdr->n_namesz), nhdr->n_descsz);
printf(" Build ID: ");
for (int i = 0 ; i < nhdr->n_descsz ; ++i)
{
printf("%02x",build_id[i]);
}
free(build_id);
printf("\n");
return 0;
}
- 1. 独自のARM ELFバイナリ
- 2. Xiaomiの電話からプログラムでプログラムを読むことができません
- 3. iPhoneアプリで独自の広告を読み込むことはできますか?
- 4. 最小限の動的リンクELFプログラムにはどのセクションが必要ですか?
- 5. ELFセクションのパディング
- 6. SegfaultはELFファイルの.dynstr(strtab)を読むとき
- 7. ELFのセクションをスワップ
- 8. 独自の.NETプロセスをプログラムでデバッグすることは可能ですか
- 9. PHPは自分のhtmlをファイル内で読むことができません。
- 10. モジュールは独自の設定ファイルを持つことができますか?
- 11. どこでソースコードを読むことができますか?
- 12. elfの.rodataセクションのchar *の値を変更することはできますか?
- 13. Python - オブジェクトは独自の型にすることができますか?
- 14. TabLayoutのAndroidフラグメントが独自のインデックスをどのように読み取ることができますか?
- 15. クローラーがSPAページを読むことはできますか?
- 16. BabelはプレーンなJavaScriptを読むことができますか?
- 17. オープンソースライセンスのもとで独自フォーマットを読むためのコードを公開できますか?
- 18. pythonプログラムがフォアグラウンドにないときに、どのようにキーストロークを読むことができますか?
- 19. LKMのELFセクションを使用
- 20. 独自のメソッドでUIAElementArrayを拡張することはできますか?
- 21. 独自のinitWithFrameでクラスを初期化することはできますか?
- 22. Androidアプリケーションで独自のログファイルを表示することはできますか?
- 23. XAMLで独自のウィジェットを作成することはできますか?
- 24. jprofilerでjmapのダンプを読むことはできますか?
- 25. C++ファイルから読み込むことができず、ベクターに読み込むことができません
- 26. プログラムで読み込むことができません。アセットの画像Xamarin iOS
- 27. Mesonはファイルの内容を読むことができます
- 28. テレグラムはチャネルのメッセージを読むことができます
- 29. セクションに独自のスクロールバーがあります
- 30. 独自のインテントフィルタを設定することはできますか?
感謝。 – e271p314