Tuuna Computer Science

[디버거] ELF Parser 개발일지 .symbol내의 심볼 출력 본문

Debugger

[디버거] ELF Parser 개발일지 .symbol내의 심볼 출력

GuTTe 2018. 12. 4. 20:33




.symtab 섹션에서 확인할 수 있는 symbol들을 구하는데 성공했다. 

.symtab 섹션과 .strtab 섹션과의 위치를 뺐더니 특정값이 나오는데 그 값에 .symtab에 저장되어 있는 엔트리의 구조체의 크기를 나눈다. 

그러면 엔트리(Symbol)의 개수를 구할 수 있다. 

그리고 엔트리 구조체의 멤버 변수중에 st_name을 통해 .strtab의 섹션에서의 인덱스값으로 사용하여 symbol들의 이름값을 구할 수 있었다. 

symbol 구조체중에 st_info의 값이 Type과 Bind의 값이 합쳐진건데 이  st_info값을  ">> 4"해서 Bind값을 구하고, " & 0xf" 연산해서 type값을 구할 수있다. 

사용자가 값을 받을 때에는 symbol의 이름을 적는게 아니라 st_name, 인덱스값을 넣을 수 있도록 해야겠다. 

다음은 이제 각 종 함수들의 주소와 .text의 주소를 찾았으니 실질적으로 디스어셈의 시긴이 온거 같다. 

인텔 기계어 명령어 형식 공부해야겠다. 

Elf32_Sym* symbol_table(int strtab_offset, int symtab_offset ,int file)
{    //중요한건 심볼테이블에 들어있는 심볼의 개수를 파악하는것!
    //또한, 각 심볼이 해당하는 Name값을 알아내는것
    /*
     typdef struct {
    Elf32_Word st_name;     //심볼 이름의 문자 표현이 있는 심볼 스트링 테이블을 가리키는 인덱스
    Elf32_Addr st_value;    //관련된 심볼 값, 주소값
    Elf32_Word st_size;     //심볼의 크기
    unsigned char st_info;  //심볼의 타입과 묶인 속성
    unsigned char st_other; // 0   
    Elf32_Half st_shndx;    //관련된 섹션 헤더 테이블 인덱스를 저장
} Elf32_Sym;
     */
    //사용자는 이름 옆에 붙여진 인덱스값으로 검색할 수 있게
    int size = (strtab_offset - symtab_offset) / 0x10;  //symbol의 개수 0x10은 구조체 크기
    //Elf32_Sym symbol[size]; //동적할당으로 반환할까
    Elf32_Sym* symbol = (Elf32_Sym*)malloc(sizeof(Elf32_Sym)*size);
    int type;
    int bind;
    char* type_string[size];
    char* bind_string[size];
    char name;    
    char sym_name[100][30];     //symbol들의 이름을 넣는다. (나중에 동적할당으로 변환시키자)
    int i;
    int j;

    lseek(file, symtab_offset, SEEK_SET);
    for(i=0;i<size;i++)
    {
        read(file, &symbol[i], sizeof(Elf32_Sym));  //st_info값은 type값과 bind값이 합쳐져 있음
        type = symbol[i].st_info & 0xf;
        bind = symbol[i].st_info >> 4;
        if(type == 0)
            type_string[i] = "NOTYPE";
        else if(type == 1)
            type_string[i] = "OBJECT";
        else if(type == 2)
            type_string[i] = "FUNC";
        else if(type == 3)
            type_string[i] = "SECTION";
        else if(type == 4)
            type_string[i] = "FILE";
        else if(type == 5)
            type_string[i] = "COMMON";
        else if(type == 6)
            type_string[i] = "TLS";
        else if(type == 10)
            type_string[i] = "LOOS";
        else if(type == 12)
            type_string[i] = "HIOS";
        else if(type == 13)
            type_string[i] = "LOPROC";
        else if(type == 15)
            type_string[i] = "HIPROC";
        else
            type_string[i] = "ERROR";

        if(bind == 0)
            bind_string[i] = "LOCAL";
        else if(bind == 1)
            bind_string[i] = "GLOBAL";
        else if(bind == 2)
            bind_string[i] = "WEAK";
        else if(bind == 10)
            bind_string[i] = "LOOP";
        else if(bind == 12)
            bind_string[i] = "HIOS";
        else if(bind == 13)
            bind_string[i] = "LOPROC";
        else if(bind == 15)
            bind_string[i] == "HIPROC";
        else
            bind_string[i] == "ERROR";
    }
//st_name 값이 strtab의 인덱스 값
    //lseek(file, strtab_offset, SEEK_SET); //strtab의 시작점
    for(i=0;i<size;i++)
    {
        lseek(file, strtab_offset+symbol[i].st_name, SEEK_SET);
        while(read(file, &name, 1))
        {
            if(name == '\0')
            {
                break;
            }
            sym_name[i][j] = name;
            j++;
        }
        sym_name[i][j] = '\0';
        j=0;
    }    
  
    printf("\nSymbol table '.symtab' contains %d entries:\n",size);
    printf("\nNum:\tValue\t\tSize\tType\tBind\tName\n");
    for(i=0;i<size;i++)
    {
        printf("[%-2d]:\t%08X\t%X\t%s\t%s\t%s [%-2d]\n",i,symbol[i].st_value, symbol[i].st_size, type_string[i], bind_string[i], sym_name[i], symbol[i].st_name);
    }
    return symbol;
}
(symbol_table.h)
Comments