2012-05-11 3 views
3

デバッグ情報なしのプログラムからコアダンプを解析しようとしています(Linux)。分析はCで自動的に行う必要がありますので、なし GDB。コアダンプからEBPとESPを抽出する方法は?

GDBで見たように、コマンドinfo registersを使用して、スタックポインタの先頭とスタックベースポインタ(ESPとEBP)を取得することができます。そして、私がスタックを上ったり下ったりすると(コマンドupdown)、私は現在のフレームのレジスタの更新版を見ています。

私の質問は、コアダンプでこの情報をどこで見つけるのですか? NT_PRSTATUS、NT_PRPSINFO、およびNT_AUXVが含まれているコアダンプにNOTEセクションがあることを知っています。しかし、残念ながら、私はそのメモに関する情報を見つけることができません。 GDBはフレームをどのように構築しますか?情報はどこから取得されますか?

答えて

5

まずあなたがどのように知ってもらうためにELF仕様書を読んで、その後のlinux/FS/binfmt_elf.cに()関数elf_core_dumpを読む必要がありますコアダンプファイルが編成されます。しかし、とにかく、次のプログラムをチェックすることができます。

#include <stdio.h> 
#include <elf.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <sys/procfs.h> 

int main (int argc, char **arg) 
{ 
Elf32_Ehdr *elfh; 
Elf32_Shdr *elfsh; 
Elf32_Phdr *elfphdr; 
char *p = NULL; 
char buf[1000], sbuf[1000]; 
int ret, fd, i = 0, size; 

if (argc < 2) { 
    printf("\nUsage: corenotes <core>\n"); 
    return 0; 
} 

fd = open(arg[1], O_RDONLY); 
if (fd < 0) { 
    perror("open"); 
    return 0; 
} 

/* Read ELF header*/ 
ret = read(fd, buf, sizeof(*elfh)); 
if (!ret) { 
    perror("Error Reading the ELF Header"); 
    goto cl; 
} 
elfh = (Elf32_Ehdr *) buf; 
/* Is it ELF*/ 
if ((elfh->e_ident[0] != 0x7f) || (elfh->e_ident[1] != 'E') || 
    (elfh->e_ident[2] != 'L') || (elfh->e_ident[3] != 'F')) { 
    printf("\nUnrecongised File Format"); 
    goto cl; 
} 

/* 
* read program headers and print 
*/ 
size = elfh->e_phnum * elfh->e_phentsize; 
p = malloc(size); 

lseek(fd, elfh->e_phoff, SEEK_SET); 
ret = read(fd, p, size); 
if (ret != size) { 
    printf("\nCannot read Program Header"); 
    goto cl; 
} 
elfphdr = (Elf32_Phdr *)p; 
for (i = 0; i < elfh->e_phnum; i++) { 
    if (elfphdr->p_type == PT_NOTE) { 
     unsigned char *pdata; 
     struct note { 
      unsigned int namesz; 
      unsigned int descsz; 
      unsigned int type; 
     }; 
     struct note *not; 
     int pad; 

     pdata = malloc(elfphdr->p_filesz); 
     lseek(fd, elfphdr->p_offset, SEEK_SET); 
     ret = read(fd, pdata, elfphdr->p_filesz); 
     not = (struct note *) pdata; 
     printf("\n%s", pdata + sizeof (*not)); 
     pad = 4 - (not->namesz % 4); 
     if (not->type == NT_PRSTATUS) { 
      struct elf_prstatus *prs; 

      prs = (struct elf_prstatus *)(pdata + sizeof(*not) + not->namesz + pad); 
      printf("\nProgram Received %d", prs->pr_cursig); 
      printf("\nPending Signals %08x", prs->pr_sigpend); 
      printf("\nHold Signals %08x", prs->pr_sighold); 
      printf("\nPID of the process %d", prs->pr_pid); 
      printf("\nPPID of the process %d", prs->pr_ppid); 
      printf("\nEBX: %08x", prs->pr_reg[0]); 
      printf("\nECX: %08x", prs->pr_reg[1]); 
      printf("\nEDX: %08x", prs->pr_reg[2]); 
      printf("\nESI: %08x", prs->pr_reg[3]); 
      printf("\nEDI: %08x", prs->pr_reg[4]); 
      printf("\nEBP: %08x", prs->pr_reg[5]); 
      printf("\nEAX: %08x", prs->pr_reg[6]); 
      printf("\nXDS: %08x", prs->pr_reg[7]); 
      printf("\nXES: %08x", prs->pr_reg[8]); 
      printf("\nXFS: %08x", prs->pr_reg[9]); 
      printf("\nXGS: %08x", prs->pr_reg[10]); 
      printf("\nORG_EAX: %08x", prs->pr_reg[11]); 
      printf("\nEIP: %08x", prs->pr_reg[12]); 
      printf("\nECS: %08x", prs->pr_reg[13]); 
      printf("\nEFLAGS: %08x", prs->pr_reg[14]); 
      printf("\nESP: %08x", prs->pr_reg[15]); 
      printf("\nXSS: %08x", prs->pr_reg[16]); 
      pdata = pdata + sizeof(*not) + not->namesz + pad + sizeof(struct elf_prstatus); 
     } 
     not = (struct note *)pdata; 
     if (not->type == NT_PRPSINFO) { 
      struct elf_prpsinfo *prs; 
      printf("\n\nNT_PRPSINF\n"); 
      pad = 4 - (not->namesz % 4); 
      prs = (struct elf_prpsinfo *)(pdata + sizeof(*not) + not->namesz + pad); 
      printf("\nName of the Exe %s", prs->pr_fname); 
     } 
    // free(pdata); 
    } 
    elfphdr++; 
} 
    free(p);  
    printf("\n\n"); 
    cl: 
    close(fd); 
    return 0; 
} 
+0

SOユーザーが提供するリンクで提供されているソースコードを考慮する必要がないように、ここで回答の関連部分を再現してください。 –

+0

脳、ここにコードを貼り付けたいのですか?これは大きなコードなので、ここに貼り付けなかったのです。それが問題ではない場合、私はここにコードを貼り付けます。 – mohanreddykv

+1

はい、ここに投稿してください。心配しないで、ジョエルは貯蔵法案を手に入れます。 –

0

elfは複雑な形式ですが、libelfを使用してPT_NOTEを抽出してください。 他をスキップすると、NT_PRSTATUSに必要なものがあります。

他のプログラムを呼び出すことができれば、elfdumpでうまくいくでしょう。

あなたはここでNT_PRSTATUS形式を見つけることができます。 http://lxr.free-electrons.com/source/include/linux/elfcore.h#L42 http://lxr.free-electrons.com/source/arch/x86/include/asm/elf.h#L116

関連する問題