2012-05-11 15 views
3

디버그 정보가없는 프로그램에서 코어 덤프를 분석하려고합니다 (Linux). 분석은 C로 자동 수행되어야하므로 아니요 GDB입니다.코어 덤프에서 EBP와 ESP를 추출하는 방법은 무엇입니까?

GDB에서 보았 듯이 info registers 명령을 통해 스택 포인터의 맨 위와 스택 기본 포인터 (ESP 및 EBP)를 가져올 수 있습니다. 그리고 스택 (명령 updown)을 위아래로 이동하면 현재 프레임에 대한 레지스터의 업데이트 된 버전이 표시됩니다.

제 질문은 코어 덤프에서이 정보를 어디에서 찾을 수 있습니까? 코어 덤프에 NT_PRSTATUS, NT_PRPSINFO 및 NT_AUXV가 들어있는 NOTE 섹션이 있다는 것을 알고 있습니다. 그러나 슬프게도, 나는 그 노트에 관한 어떤 정보도 찾을 수 없다. GDB는 프레임을 어떻게 구축합니까? 정보를 어디에서 가져 옵니까?

답변

5

먼저 당신이 방법을 알고 얻을 수있는 ELF 사양을 읽은 다음 리눅스/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

예, 여기에 게시하십시오. 걱정 마세요. 조엘이 보관료를받습니다. –

관련 문제