ELF format templates 수정하기
PT_DYNAMIC 일 때 offset data 를 각 구조체로 파싱하기
ELF format templates 수정하기
Introduction
hex-Editor 로 ELF 파일을 보다가 phdr 의 type 이 Dynamic 일 떼 offset 부분이 이쁘게 안 나와서 해당 부분을 수정해주고자 한다.
How We Got Here
기존 방식
기존에는 아래와 같이 char 배열로 1 바이트씩 파싱하는 것이 표준이었다.
1
char p_data[p_filesz_SEGMENT_FILE_LENGTH] <comment="Segment data">;
그러면 아래와 같이 나온다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
p_data[648] 3E90h 288h char Fg: Bg: Segment data
p_data[0] 0 3E90h 1h char Fg: Bg: Segment data
p_data[1] 0 3E91h 1h char Fg: Bg: Segment data
p_data[2] 0 3E92h 1h char Fg: Bg: Segment data
p_data[3] 0 3E93h 1h char Fg: Bg: Segment data
{ . . . }
p_data[30] 0 3EAEh 1h char Fg: Bg: Segment data
p_data[31] 0 3EAFh 1h char Fg: Bg: Segment data
p_data[32] 50 '2' 3EB0h 1h char Fg: Bg: Segment data
p_data[33] 1 3EB1h 1h char Fg: Bg: Segment data
p_data[34] 0 3EB2h 1h char Fg: Bg: Segment data
p_data[35] 0 3EB3h 1h char Fg: Bg: Segment data
p_data[36] 0 3EB4h 1h char Fg: Bg: Segment data
이렇게 확인은 할 수 있으나 ELF 의 dyn 자료형은 아래와 같다.
Elf32_Dyn/Elf64_Dyn 자료형
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef struct dynamic {
Elf32_Sword d_tag;
union {
Elf32_Sword d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
typedef struct {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
따라서 32 bit 경우 8 바이트씩, 64 bit 일 경우 16 바이트씩 structure 로 묶어주면 보기 편할 거 같다.
템플릿 수정하기
Elf64_Sxword
의 대한 자료형을 알려준다.
1
typedef uint64 Elf64_Sxword;
원래는 enum 값 형태로 지정하면 파싱했을 때 갑을 좀 더 명확히 보여줄 수 있다는 편리함이 있다.
PT_DYNAMIC
일 때는 structure 형태로 묶어줘야 하니 condition 을 열어 알맞는 structure 를 작성해준다.
1
2
3
4
5
6
7
8
9
10
11
if (p_type == PT_DYNAMIC) {
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Sword d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
Elf32_Dyn p_dynamic_data[p_filesz_SEGMENT_FILE_LENGTH / sizeof(Elf32_Dyn)] <comment="Dynamic section entries">;
}
여기서 union
은 공용체로 메모리 하나의 영역을 공유하여 사용하는 것으로 d_val
, d_ptr
같은 값이 할당된다.
p_dynamic_data
에 길이는 전체 길이(p_filesz_SEGMENT_FILE_LENGTH
)를 자료형 크기(Elf32_Dyn
)만큼 나눈 갯수이다.
실행해보면 아래와 같이 나온다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
p_dynamic_data[28] 3EA8h 1C0h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[0] 3EA8h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[1] 3EB8h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[2] 3EC8h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[3] 3ED8h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[4] 3EE8h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[5] 3EF8h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[6] 3F08h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[7] 3F18h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[8] 3F28h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
d_tag 7 3F28h 8h Elf64_Sxword Fg: Bg:
d_un 3F30h 8h union Fg: Bg:
p_dynamic_data[9] 3F38h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
d_tag 8 3F38h 8h Elf64_Sxword Fg: Bg:
d_un 3F40h 8h union Fg: Bg:
p_dynamic_data[10] 3F48h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[11] 3F58h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[12] 3F68h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
p_dynamic_data[13] 3F78h 10h struct Elf64_Dyn Fg: Bg: Dynamic section entries
The Game-Changer
최종적으로 정리된 코드를 확인해보면 아래와 같다.
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
29
30
31
32
33
34
35
36
37
// Elf32_Sword 에 대한 자료형
typedef uint32 Elf32_Sword;
// Elf64_Sxword 에 대한 자료형
typedef uint64 Elf64_Sxword;
// Elf32_Dyn with descriptive d_tag
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Sword d_val <comment="Value or index">;
Elf32_Addr d_ptr <comment="Pointer (address in memory)">;
} d_un;
} Elf32_Dyn;
// Elf64_Dyn with descriptive d_tag
typedef struct {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val <comment="Value or index">;
Elf64_Addr d_ptr <comment="Pointer (address in memory)">;
} d_un;
} Elf64_Dyn;
// 32 bit 에서 조건문
if (p_type == PT_DYNAMIC) {
Elf32_Dyn p_dynamic_data[p_filesz_SEGMENT_FILE_LENGTH / sizeof(Elf32_Dyn)] <comment="Dynamic section entries">;
} else {
char p_data[p_filesz_SEGMENT_FILE_LENGTH] <comment="Segment data">;
}
// 64 bit 에서 조건문
if (p_type == PT_DYNAMIC) {
Elf64_Dyn p_dynamic_data[p_filesz_SEGMENT_FILE_LENGTH / sizeof(Elf64_Dyn)] <comment="Dynamic section entries">;
} else {
char p_data[p_filesz_SEGMENT_FILE_LENGTH] <comment="Segment data">;
}
Conclusion
당장 보기 위해서 엉거주춤 모자라게 작성했는데 d_tag 값도 볼 수 있도록 수정하는 편이 좋을 거 같다.
This post is licensed under CC BY 4.0 by the author.
If you find any errors, please let me know by comment or email. Thank you.
If you find any errors, please let me know by comment or email. Thank you.