Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- wrefresh
- NAPT
- iptables
- level trigger
- Compiler
- C언어
- mvwin
- LOB
- vtable
- architecture
- .nret core 배포
- BOF
- REDIS
- Docker
- packet filter
- 풀이
- .net core 7
- rfc5508
- wnourefresh
- doupdate
- 어셈블리어
- ioctl
- DOCKER-USER
- 취약점
- edge trigger
- epoll_wait
- ncurses
- epoll
- packet flow
- cbpf
Archives
- Today
- Total
Tuuna Computer Science
[ELF] 리눅스 Debugger(디버거)만들기 본문
elf header와 elf header의 내용을 바탕으로 섹션 헤더를 출력하는데 성공했다.
이젠 이 섹션 헤더를 바탕으로 .symtab 섹션으로 가서 심볼들을 체크해봐야 겠다.
int check_elf(int file)
{
ssize_t check;
char value[16];
int i;
int magic=1;
lseek(file, 0, SEEK_SET);
for(i=0;i<16;i++)
{
read(file, &value[i], 1);
}
if(value[0] == 0x7F && value[1] == 0x45 && value[2] == 0x4c && value[3] == 0x46)
{
magic = 0;
}
if(magic)
{
return 1;
}
return 0;
}
check_elf.h (파일이 elf인지 아닌지 확인한다.)
/*
// 32-bit ELF base types.
typedef __u32 Elf32_Addr;
typedef __u16 Elf32_Half;
typedef __u32 Elf32_Off;
typedef __s32 Elf32_Sword;
typedef __u32 Elf32_Word;
*/
#define EL_NIDENT 16
/*
typedef struct elf32_hdr{
unsigned char e_ident[EL_NIDENT]; //=> 파일이 object파일임을 나타냄. 기계 독립적인 데이터 제공
Elf32_Half e_type; //=> Object 파일의 타입을 표시
Elf_Half e_machine; //=> 아키텍쳐 정보를 표시 (32인지 64인지)
Elf_Word e_version; //=> Object 파일의 버전 정보
Elf_Addr e_entry; //=> 가상주소 (시작점 ), 프로그램을 어디로
Elf_Off e_phoff; //=> 프로그램 헤더 파일 옵셋을 나타냄
Elf_Off e_shoff; //=> 섹션 헤더 테이블의 파일 옵셋을 나타냄
Elf32_Word e_flags //=> 사용 X
Elf32_Half e_ehsize; //=> ELF 헤더의 크기를 가짐
Elf32_Half e_phentsize; //=> 파일의 프로그램 헤더파일에 있는 한 엔트리의 크기를 나타냄
Elf32_Half e_phnum; //=> 프로그램 헤더 테이블에 들어있는 모든 엔트리의 수를 나타냄
Elf32_Half e_shentsize; //=> 섹션 헤더의 크기를 나타냄.
Elf32_Half e_shnum; //=> 섹션 헤더 테이블에 있는 엔트리의 수를 가짐.
Elf32_Half e_shstrndx;
//=> 섹션의 이름을 나타내는 스트링의 테이블과 관련된 엔트리의 섹션 헤더 테이블 인덱스를 가진다.
} Elf32_Ehdr;
*/
Elf32_Ehdr elf_header(int file)
{
Elf32_Ehdr elf32;
//Elf64_Ehdr elf64;
ssize_t check;
int i;
lseek(file, 0, SEEK_SET);
read(file, &elf32, sizeof(elf32));
printf("magic: ");
for(i=0;i<16;i++)
printf("%X ", elf32.e_ident[i]);
printf("\n");
printf("%c[1;31m",27);
if(elf32.e_ident[4] == 1)
printf("Class: ELF32\n");
else if(elf32.e_ident[4] == 2)
{
printf("Class: ELF64\n");
printf("Sorry! debugger want 32bit binary!\n");
exit(1);
//return -1;
}
else
perror("Error!");
printf("%c[0m",27);
if(elf32.e_ident[5] == 1)
printf("Data: 2's complement, little endian\n");
else if(elf32.e_ident[5] == 2)
printf("Data: 1's complement, big endian\n");
else
perror("Error!");
if(elf32.e_ident[6] == 1)
printf("Version: 1 (current)\n");
else if(elf32.e_ident[6] == 2)
printf("Version: setting....\n");
else
perror("Error!");
printf("OS/ABI: UNIX - System V\n");
printf("ABI Version: 0\n");
printf("%c[1;31m",27);
if(elf32.e_machine ==3)
printf("Machine: Intel 80386\n");
else if(elf32.e_machine == 62)
printf("Machine: Advance Micro Devices X86-64\n");
else
printf("Machine: setting.....\n");
printf("%c[0m",27);
if(elf32.e_type == 0)
printf("Type: NONE\n");
else if(elf32.e_type == 1)
printf("Type: REL\n");
else if(elf32.e_type == 2)
printf("Type: EXEC\n");
else if(elf32.e_type == 3)
printf("Type: DYN\n");
else if(elf32.e_type == 4)
printf("Type: CORE\n");
else
printf("Type: setting....\n");
printf("Version: 0x1\n");
//printf("=========================================\n");
printf("%c[1;31m",27);
printf("Entry Point Address(.text): 0x%X\n",elf32.e_entry);
printf("%c[0m",27);
printf("Flags: %X\n",elf32.e_flags);
printf("Start of program headers: 0x%X\n",elf32.e_phoff);
printf("Start of section headers: 0x%X\n",elf32.e_shoff);
printf("Size of program headers: %X (bytes)\n",elf32.e_phentsize);
printf("Size of section headers: %X (bytes)\n",elf32.e_shentsize);
printf("Number of program headers: %X\n",elf32.e_phnum);
printf("Size of ELF Header: %X (bytes)\n",elf32.e_ehsize);
printf("Number of section headers: %X\n",elf32.e_shnum);
printf("Section header string table index: %d\n",elf32.e_shstrndx);
return elf32;
}
(elf_header.h)(ELF HEADER를 출력한다.)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <elf.h>
#include <linux/types.h>
#include "check_elf.h"
#include "elf_header.h"
int elf_section_header(Elf32_Ehdr elf, int file);
int main(int argc, char** argv)
{
Elf32_Ehdr elf;
int return_check;
int file;
if(argc!=2)
{
perror("Error: ");
exit(1);
}
file = open(argv[1], O_RDONLY);
if(file == -1)
{
perror("Error: ");
exit(1);
}
return_check=check_elf(file); //elf인지 확인한다.
//printf("%d\n", return_check);
if(return_check)
{
printf("This is not ELF\n");
close(file);
exit(1);
}
elf = elf_header(file); //elf의 header를 출력한다.
elf_section_header(elf, file); //elf의 섹션헤더를 출력한다.
close(file);
return 0;
}
int elf_section_header(Elf32_Ehdr elf, int file)
{
char sym[29][30];
char name;
//const char *const name;
Elf32_Shdr section_header[30]; //일단 30개 해놓자
int i;
int j=0;
lseek(file, elf.e_shoff, SEEK_SET);
for(i=0;i<elf.e_shnum;i++)
{
read(file, §ion_header[i], sizeof(section_header[1]));
}
printf("\nThere are %d section headers, starting at offset %X\n", elf.e_shnum, elf.e_shoff);
printf("\nSection Headers:\n");
printf("[Nr] Name\t\t\tAddr\tOff\tSize\n");
//lseek(file, section_header[28].sh_offset, SEEK_SET);
for(i=0;i<elf.e_shnum;i++)
{
lseek(file, section_header[28].sh_offset+section_header[i].sh_name,SEEK_SET);
while(read(file, &name, 1))
{
if(name == '\0')
{
break;
}
sym[i][j] = name;
j++;
}
sym[i][j] = '\0';
j=0;
}
for(i=0;i<elf.e_shnum;i++)
{
printf("[%-2d] %s\t\t\t0x%X\t0x%X\t%X\n",i, sym[i], section_header[i].sh_addr, section_header[i].sh_offset, section_header[i].sh_size);
}
}
//이름은 처음 파일 옵셋에서 sh_name을 더하고, sh_offset을 더한건가.
elf_parser.c ( 여기서 하나를 헤더파일화 안했는데 elf_section_header 함수는 섹션 헤더를 출력하는 함수이다.)
섹션헤더를 출력하면서 좀 힘들었던점이 sh_name의 값이 파일 옵세이 아니라 shstrtab의 옵셋이였던 것이다;;
그래서 name을 구할려면 shstrtabl의 오프셋에서 sh_name을 더해야 했던것
stack overflow에서 왜 이부분을 mmap 시스템콜을 사용해서 하는지 알겠다..
그냥 파일로 읽을려하니 널까지 읽어야하고 등등 처리할게 많아지네
내일은 .symtab을 바탕으로 사용자가 원하는 함수에 대한 명령코드를 출력하는 것을 목표로하자
그리고 이 명령코드를 바탕으로 디스 어셈...ㅎ
'Debugger' 카테고리의 다른 글
[ 32bit ELF Debugger ] 디스어셈블리러(disassembler), 디버거(debugger) 제작 일지2 (0) | 2019.02.20 |
---|---|
[debugger] 32bit binary disassembler 개발일지 (0) | 2019.01.14 |
ModR/M 바이트에서 Mod+R/M과 Reg와의 목적지(순서) 구분 & SIB 바이트 작성법 (0) | 2018.12.15 |
인텔 기계어 정리 (1) | 2018.12.13 |
[디버거] ELF Parser 개발일지 .symbol내의 심볼 출력 (0) | 2018.12.04 |
Comments