私の C++ プログラムでは、Linux の 'strip' gnu 開発ツールを使用してシンボルが削除されたかどうかを実行時にプログラムで検出するにはどうすればよいですか?
削除された場合は true、そうでない場合は false を返す関数定義が必要です。
「main()」で dlsym() を使用すると、これを確実に検出できますか?
私の C++ プログラムでは、Linux の 'strip' gnu 開発ツールを使用してシンボルが削除されたかどうかを実行時にプログラムで検出するにはどうすればよいですか?
削除された場合は true、そうでない場合は false を返す関数定義が必要です。
「main()」で dlsym() を使用すると、これを確実に検出できますか?
コマンドが違いを伝えることができることはわかっているfile
ので、そのソースを見て、それがどのメカニズムを使用しているかを確認できます。
別の答えのために残されたコメントから:
ストリップされたELFには.symtab
エントリがありません。コマンドはfile
、シンボルテーブルセクションが見つかるまで、すべてのELFセクションヘッダーをトラバースします。見つからない場合、バイナリは削除されたと見なされます。
libelfライブラリを使用すると、プログラムでELFオブジェクトファイル、アーカイブファイル、およびアーカイブメンバーを操作できます。elf(3E)のマニュアルページには、ライブラリの使用に関連するドキュメントが記載されています。次のコードは、シンボルテーブルセクション()の存在を探すことによって実行可能ファイルが削除されたかどうかを判断する例を示しています.symtab
。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
/* Include for ELF processing */
#include <libelf.h>
#include <gelf.h>
int main(int argc, char ** argv)
{
int fd;
const char *file = argv[0];
Elf *elf; /* ELF pointer for libelf */
Elf_Scn *scn; /* section descriptor pointer */
GElf_Shdr shdr; /* section header */
/* Open ELF file to obtain file descriptor */
if((fd = open(file, O_RDONLY)) < 0)
{
fprintf(stderr, "Error opening file %s\n", file);
exit(EXIT_FAILURE);
}
/* Protect program from using an older library */
if(elf_version(EV_CURRENT) == EV_NONE)
{
fprintf(stderr, "WARNING - ELF Library is out of date!\n");
exit(EXIT_FAILURE);
}
/* Initialize elf pointer for examining contents of file */
elf = elf_begin(fd, ELF_C_READ, NULL);
/* Initialize section descriptor pointer so that elf_nextscn()
* returns a pointer to the section descriptor at index 1. */
scn = NULL;
/* Iterate through ELF sections */
while((scn = elf_nextscn(elf, scn)) != NULL)
{
/* Retrieve section header */
gelf_getshdr(scn, &shdr);
/* If a section header holding a symbol table (.symtab)
* is found, this ELF file has not been stripped. */
if(shdr.sh_type == SHT_SYMTAB)
{
printf("NOT STRIPPED\n");
break;
}
}
elf_end(elf);
close(fd);
exit(EXIT_SUCCESS);
}
dlsym
stripによって触れられていない動的シンボルを調べます。静的シンボル テーブルは、実行時に読み込まれないため、セグメント テーブルに表示されないセクションに含まれています。
ELF ヘッダー内のセクション テーブルの存在を監視することは、非常に優れたヒューリスティックです。これは通常、プロセス メモリにマップされますが、ダイナミック リンカー インターフェイスにより、意図的に場所を見つけるのが難しくなります。関数 (標準の拡張機能) を備えた典型的なシステムではdl_iterate_phdrs
、PHDRS を調べて vaddr でそれぞれに ELF マジック ナンバーがあるかどうかを確認できるかもしれませんが、それは決して形状ではありません。またはフォームポータブル。
popen()を使用nm
してターゲットアプリケーションで実行し、出力を解析して、それが削除されているかどうかを判断できます。
nm: /bin/ls: no symbols