Rizin
unix-like reverse engineering framework and cli tools
elf_segments.c File Reference
#include "elf.h"

Go to the source code of this file.

Functions

static bool get_phdr_entry (ELFOBJ *bin, Elf_(Phdr) *segment, ut64 offset)
 
static bool verify_phdr_entry (ELFOBJ *bin, RzBinObjectLoadOptions *options, Elf_(Phdr) *entry)
 
static bool get_elf_segment (ELFOBJ *bin, RzBinObjectLoadOptions *options, RzBinElfSegment *segment, ut64 offset, size_t pos)
 
static RzVectorget_segments_from_phdr (ELFOBJ *bin, size_t count, RzBinObjectLoadOptions *options)
 
static size_t get_number_of_segments (ELFOBJ *bin, RzVector *sections)
 
RZ_BORROW RzBinElfSegment *Elf_() rz_bin_elf_get_segment_with_type (RZ_NONNULL ELFOBJ *bin, Elf_(Word) type)
 
RZ_OWN RzVector *Elf_() rz_bin_elf_segments_new (RZ_NONNULL ELFOBJ *bin, RzVector *sections, RZ_NONNULL RzBinObjectLoadOptions *options)
 
bool Elf_() rz_bin_elf_has_segments (RZ_NONNULL ELFOBJ *bin)
 

Function Documentation

◆ get_elf_segment()

static bool get_elf_segment ( ELFOBJ bin,
RzBinObjectLoadOptions options,
RzBinElfSegment segment,
ut64  offset,
size_t  pos 
)
static

Definition at line 56 of file elf_segments.c.

56  {
57  if (!get_phdr_entry(bin, &segment->data, offset)) {
58  RZ_LOG_WARN("Failed to read segment entry at 0x%" PFMT64x ".\n", offset);
59  return false;
60  }
61 
62  segment->is_valid = verify_phdr_entry(bin, options, &segment->data);
63  if (!segment->is_valid) {
64  RZ_LOG_WARN("The segment %zu at 0x%" PFMT64x " seems to be invalid.\n", pos, offset);
65  }
66 
67  return true;
68 }
static bool verify_phdr_entry(ELFOBJ *bin, RzBinObjectLoadOptions *options, Elf_(Phdr) *entry)
Definition: elf_segments.c:27
static bool get_phdr_entry(ELFOBJ *bin, Elf_(Phdr) *segment, ut64 offset)
Definition: elf_segments.c:7
voidpf uLong offset
Definition: ioapi.h:144
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define PFMT64x
Definition: rz_types.h:393
Definition: malloc.c:26
int pos
Definition: main.c:11

References get_phdr_entry(), options, PFMT64x, pos, RZ_LOG_WARN, and verify_phdr_entry().

Referenced by get_segments_from_phdr().

◆ get_number_of_segments()

static size_t get_number_of_segments ( ELFOBJ bin,
RzVector sections 
)
static

Definition at line 101 of file elf_segments.c.

101  {
102  if (bin->ehdr.e_phnum != PN_XNUM) {
103  return bin->ehdr.e_phnum;
104  }
105 
106  if (!sections) {
107  RZ_LOG_WARN("Failed to fetch the number of segments because there are no sections.\n");
108  return 0;
109  }
110 
112  if (!section) {
113  RZ_LOG_WARN("Failed to fetch the number of segments from the section 0.\n");
114  return 0;
115  }
116 
117  return section->sh_info;
118 }
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
#define Elf_(name)
Definition: elf_specs.h:32
#define PN_XNUM
Definition: glibc_elf.h:698
static void * rz_vector_index_ptr(RzVector *vec, size_t index)
Definition: rz_vector.h:88

References Elf_, PN_XNUM, RZ_LOG_WARN, rz_vector_index_ptr(), and sections().

Referenced by rz_bin_elf_segments_new().

◆ get_phdr_entry()

static bool get_phdr_entry ( ELFOBJ bin,
Elf_(Phdr) *  segment,
ut64  offset 
)
static

Definition at line 7 of file elf_segments.c.

7  {
8  if (!Elf_(rz_bin_elf_read_word)(bin, &offset, &segment->p_type) ||
9 #if RZ_BIN_ELF64
10  !Elf_(rz_bin_elf_read_word)(bin, &offset, &segment->p_flags) ||
11 #endif
12  !Elf_(rz_bin_elf_read_off)(bin, &offset, &segment->p_offset) ||
13  !Elf_(rz_bin_elf_read_addr)(bin, &offset, &segment->p_vaddr) ||
14  !Elf_(rz_bin_elf_read_addr)(bin, &offset, &segment->p_paddr) ||
15  !Elf_(rz_bin_elf_read_word_xword)(bin, &offset, &segment->p_filesz) ||
16  !Elf_(rz_bin_elf_read_word_xword)(bin, &offset, &segment->p_memsz) ||
17 #ifndef RZ_BIN_ELF64
18  !Elf_(rz_bin_elf_read_word)(bin, &offset, &segment->p_flags) ||
19 #endif
20  !Elf_(rz_bin_elf_read_word_xword)(bin, &offset, &segment->p_align)) {
21  return false;
22  }
23 
24  return true;
25 }
#define RZ_BIN_ELF64
Definition: elf64.c:5
bool Elf_() rz_bin_elf_read_word_xword(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Word) *result)
Definition: elf_misc.c:117
bool Elf_() rz_bin_elf_read_addr(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Addr) *result)
Definition: elf_misc.c:82
bool Elf_() rz_bin_elf_read_off(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Off) *result)
Definition: elf_misc.c:91
bool Elf_() rz_bin_elf_read_word(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Word) *result)
Definition: elf_misc.c:62

References Elf_, RZ_BIN_ELF64, rz_bin_elf_read_addr(), rz_bin_elf_read_off(), rz_bin_elf_read_word(), and rz_bin_elf_read_word_xword().

Referenced by get_elf_segment().

◆ get_segments_from_phdr()

static RzVector* get_segments_from_phdr ( ELFOBJ bin,
size_t  count,
RzBinObjectLoadOptions options 
)
static

Definition at line 70 of file elf_segments.c.

70  {
71  RzVector *result = rz_vector_new(sizeof(RzBinElfSegment), NULL, NULL);
72  if (!result) {
73  return NULL;
74  }
75 
76  ut64 offset = bin->ehdr.e_phoff;
77 
78  for (size_t i = 0; i < count; i++) {
79  RzBinElfSegment *segment = rz_vector_push(result, NULL);
80  if (!segment) {
81  rz_vector_free(result);
82  return NULL;
83  }
84 
85  if (!get_elf_segment(bin, options, segment, offset, i)) {
86  rz_vector_free(result);
87  return NULL;
88  }
89 
90  offset += sizeof(Elf_(Phdr));
91  }
92 
93  if (!rz_vector_len(result)) {
94  rz_vector_free(result);
95  return NULL;
96  }
97 
98  return result;
99 }
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
RzBinElfSegment
Definition: elf.h:131
static bool get_elf_segment(ELFOBJ *bin, RzBinObjectLoadOptions *options, RzBinElfSegment *segment, ut64 offset, size_t pos)
Definition: elf_segments.c:56
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
RZ_API void rz_vector_free(RzVector *vec)
Definition: vector.c:75
RZ_API RzVector * rz_vector_new(size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:42
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References count, Elf_, get_elf_segment(), i, NULL, options, rz_vector_free(), rz_vector_len(), rz_vector_new(), rz_vector_push(), RzBinElfSegment, and ut64().

Referenced by rz_bin_elf_segments_new().

◆ rz_bin_elf_get_segment_with_type()

RZ_BORROW RzBinElfSegment* Elf_() rz_bin_elf_get_segment_with_type ( RZ_NONNULL ELFOBJ bin,
Elf_(Word)  type 
)

Definition at line 120 of file elf_segments.c.

120  {
122 
125  if (iter->data.p_type == type) {
126  return iter;
127  }
128  }
129 
130  return NULL;
131 }
#define rz_bin_elf_foreach_segments(bin, segment)
Definition: elf.h:26
int type
Definition: mipsasm.c:17
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References NULL, rz_bin_elf_foreach_segments, rz_return_val_if_fail, RzBinElfSegment, and type.

Referenced by elf_has_gnu_relro(), init_dt_dynamic(), rz_bin_elf_get_intrp(), rz_bin_elf_has_nx(), and rz_bin_elf_is_static().

◆ rz_bin_elf_has_segments()

◆ rz_bin_elf_segments_new()

RZ_OWN RzVector* Elf_() rz_bin_elf_segments_new ( RZ_NONNULL ELFOBJ bin,
RzVector sections,
RZ_NONNULL RzBinObjectLoadOptions options 
)

Definition at line 133 of file elf_segments.c.

133  {
135 
137  if (!count) {
138  return NULL;
139  }
140 
141  if (!Elf_(rz_bin_elf_check_array)(bin, bin->ehdr.e_phoff, count, sizeof(Elf_(Phdr)))) {
142  RZ_LOG_WARN("Invalid program header (check array failed).\n");
143  return NULL;
144  }
145 
147 }
bool Elf_() rz_bin_elf_check_array(RZ_NONNULL ELFOBJ *bin, Elf_(Off) offset, Elf_(Off) length, Elf_(Off) entry_size)
Definition: elf_misc.c:32
static size_t get_number_of_segments(ELFOBJ *bin, RzVector *sections)
Definition: elf_segments.c:101
static RzVector * get_segments_from_phdr(ELFOBJ *bin, size_t count, RzBinObjectLoadOptions *options)
Definition: elf_segments.c:70

References count, Elf_, get_number_of_segments(), get_segments_from_phdr(), NULL, options, rz_bin_elf_check_array(), RZ_LOG_WARN, rz_return_val_if_fail, and sections().

Referenced by init_phdr_aux().

◆ verify_phdr_entry()

static bool verify_phdr_entry ( ELFOBJ bin,
RzBinObjectLoadOptions options,
Elf_(Phdr) *  entry 
)
static

Definition at line 27 of file elf_segments.c.

27  {
28  if (!options->elf_checks_segments) {
29  return true;
30  }
31 
32  if (!entry->p_offset && !entry->p_vaddr && !entry->p_paddr && !entry->p_filesz && !entry->p_memsz) {
33  return true;
34  }
35 
36  Elf_(Off) end_off;
37  if (!Elf_(rz_bin_elf_add_off)(&end_off, entry->p_offset, entry->p_filesz) || end_off > bin->size) {
38  return false;
39  }
40 
41  if (!Elf_(rz_bin_elf_add_addr)(NULL, entry->p_vaddr, entry->p_memsz)) {
42  return false;
43  }
44 
45  if (entry->p_flags == PT_LOAD && (!entry->p_memsz || entry->p_filesz > entry->p_memsz)) {
46  return false;
47  }
48 
49  if (entry->p_align && entry->p_offset % entry->p_align != entry->p_vaddr % entry->p_align) {
50  return false;
51  }
52 
53  return true;
54 }
bool Elf_() rz_bin_elf_add_off(Elf_(Off) *result, Elf_(Off) addr, Elf_(Off) value)
Definition: elf_misc.c:146
bool Elf_() rz_bin_elf_add_addr(Elf_(Addr) *result, Elf_(Addr) addr, Elf_(Addr) value)
Definition: elf_misc.c:138
#define PT_LOAD
Definition: common.h:303
Definition: zipcmp.c:77

References Elf_, NULL, options, PT_LOAD, rz_bin_elf_add_addr(), and rz_bin_elf_add_off().

Referenced by get_elf_segment().