Rizin
unix-like reverse engineering framework and cli tools
pe.h File Reference
#include <rz_types.h>
#include <rz_util.h>
#include <rz_lib.h>
#include <rz_bin.h>
#include "pe_specs.h"
#include "dotnet.h"

Go to the source code of this file.

Classes

struct  rz_bin_pe_addr_t
 
struct  rz_bin_pe_section_t
 
struct  rz_bin_pe_import_t
 
struct  rz_bin_pe_export_t
 
struct  rz_bin_pe_string_t
 
struct  rz_bin_pe_lib_t
 
struct  _PE_RESOURCE
 
struct  SDebugInfo
 

Macros

#define PE_READ_STRUCT_FIELD(var, struct_type, field, size)   var->field = rz_read_le##size(buf + offsetof(struct_type, field))
 
#define RZ_BIN_PE_SCN_IS_SHAREABLE(x)   x &PE_IMAGE_SCN_MEM_SHARED
 
#define RZ_BIN_PE_SCN_IS_EXECUTABLE(x)   x &PE_IMAGE_SCN_MEM_EXECUTE
 
#define RZ_BIN_PE_SCN_IS_READABLE(x)   x &PE_IMAGE_SCN_MEM_READ
 
#define RZ_BIN_PE_SCN_IS_WRITABLE(x)   x &PE_IMAGE_SCN_MEM_WRITE
 
#define IMAGE_SCN_TYPE_NO_PAD   0x00000008
 
#define IMAGE_SCN_CNT_CODE   0x00000020
 
#define IMAGE_SCN_CNT_INITIALIZED_DATA   0x00000040
 
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA   0x00000080
 
#define IMAGE_SCN_LNK_OTHER   0x00000100
 
#define IMAGE_SCN_LNK_INFO   0x00000200
 
#define IMAGE_SCN_LNK_REMOVE   0x00000800
 
#define IMAGE_SCN_LNK_COMDAT   0x00001000
 
#define IMAGE_SCN_GPREL   0x00008000
 
#define IMAGE_SCN_MEM_PURGEABLE   0x00020000
 
#define IMAGE_SCN_MEM_16BIT   0x00020000
 
#define IMAGE_SCN_MEM_LOCKED   0x00040000
 
#define IMAGE_SCN_MEM_PRELOAD   0x00080000
 
#define IMAGE_SCN_ALIGN_1BYTES   0x00100000
 
#define IMAGE_SCN_ALIGN_2BYTES   0x00200000
 
#define IMAGE_SCN_ALIGN_4BYTES   0x00300000
 
#define IMAGE_SCN_ALIGN_8BYTES   0x00400000
 
#define IMAGE_SCN_ALIGN_16BYTES   0x00500000
 
#define IMAGE_SCN_ALIGN_32BYTES   0x00600000
 
#define IMAGE_SCN_ALIGN_64BYTES   0x00700000
 
#define IMAGE_SCN_ALIGN_128BYTES   0x00800000
 
#define IMAGE_SCN_ALIGN_256BYTES   0x00900000
 
#define IMAGE_SCN_ALIGN_512BYTES   0x00A00000
 
#define IMAGE_SCN_ALIGN_1024BYTES   0x00B00000
 
#define IMAGE_SCN_ALIGN_2048BYTES   0x00C00000
 
#define IMAGE_SCN_ALIGN_4096BYTES   0x00D00000
 
#define IMAGE_SCN_ALIGN_8192BYTES   0x00E00000
 
#define IMAGE_SCN_LNK_NRELOC_OVFL   0x01000000
 
#define IMAGE_SCN_MEM_DISCARDABLE   0x02000000
 
#define IMAGE_SCN_MEM_NOT_CACHED   0x04000000
 
#define IMAGE_SCN_MEM_NOT_PAGED   0x08000000
 
#define PE_SCN_ALIGN_MASK   0x00F00000
 
#define GUIDSTR_LEN   41
 
#define DBG_FILE_NAME_LEN   255
 
#define RzBinPEObj   struct PE_(rz_bin_pe_obj_t)
 
#define MAX_METADATA_STRING_LENGTH   256
 
#define COFF_SYMBOL_SIZE   18
 
#define PE_READ_STRUCT_FIELD(var, struct_type, field, size)   var->field = rz_read_le##size(buf + offsetof(struct_type, field))
 

Typedefs

typedef struct _PE_RESOURCE rz_pe_resource
 
typedef struct SDebugInfo SDebugInfo
 

Functions

struct PE_ (rz_bin_pe_obj_t)
 
RZ_OWN RzList *PE_() rz_bin_pe_get_clr_symbols (RzBinPEObj *bin)
 
ut64 PE_() rz_bin_pe_get_clr_methoddef_offset (RzBinPEObj *bin, Pe_image_metadata_methoddef *methoddef)
 
int PE_() bin_pe_init_clr (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_get_debug_data (RzBinPEObj *bin, SDebugInfo *res)
 
int PE_() bin_pe_init_exports (RzBinPEObj *bin)
 
struct rz_bin_pe_export_t *PE_() rz_bin_pe_get_exports (RzBinPEObj *bin)
 
int PE_() bin_pe_init_hdr (RzBinPEObj *bin)
 
int PE_() bin_pe_init_imports (RzBinPEObj *bin)
 
int PE_() read_image_import_directory (RzBuffer *b, ut64 addr, PE_(image_import_directory) *import_dir)
 
int PE_() read_image_delay_import_directory (RzBuffer *b, ut64 addr, PE_(image_delay_import_directory) *directory)
 
struct rz_bin_pe_import_t *PE_() rz_bin_pe_get_imports (RzBinPEObj *bin)
 
char *PE_() rz_bin_pe_get_arch (RzBinPEObj *bin)
 
char *PE_() rz_bin_pe_get_cc (RzBinPEObj *bin)
 
char *PE_() rz_bin_pe_get_machine (RzBinPEObj *bin)
 
char *PE_() rz_bin_pe_get_os (RzBinPEObj *bin)
 
char *PE_() rz_bin_pe_get_class (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_get_bits (RzBinPEObj *bin)
 
char *PE_() rz_bin_pe_get_subsystem (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_is_dll (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_is_big_endian (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_is_stripped_relocs (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_is_stripped_line_nums (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_is_stripped_local_syms (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_is_stripped_debug (RzBinPEObj *bin)
 
int PE_() bin_pe_get_claimed_checksum (RzBinPEObj *bin)
 
int PE_() bin_pe_get_actual_checksum (RzBinPEObj *bin)
 
struct rz_bin_pe_addr_t *PE_() check_unknow (RzBinPEObj *bin)
 
struct rz_bin_pe_addr_t *PE_() check_msvcseh (RzBinPEObj *bin)
 
struct rz_bin_pe_addr_t *PE_() check_mingw (RzBinPEObj *bin)
 
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_entrypoint (RzBinPEObj *bin)
 
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_main_vaddr (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_get_image_size (RzBinPEObj *bin)
 
struct rz_bin_pe_lib_t *PE_() rz_bin_pe_get_libs (RzBinPEObj *bin)
 
ut64 PE_() rz_bin_pe_get_image_base (RzBinPEObj *bin)
 
int PE_() bin_pe_get_overlay (RzBinPEObj *bin, ut64 *size)
 
int PE_() bin_pe_init_overlay (RzBinPEObj *bin)
 
RZ_API void PE_() bin_pe_parse_resource (RzBinPEObj *bin)
 
void PE_() bin_pe_init_rich_info (RzBinPEObj *bin)
 
int PE_() bin_pe_init_resource (RzBinPEObj *bin)
 
int PE_() bin_pe_init_sections (RzBinPEObj *bin)
 
void PE_() rz_bin_pe_check_sections (RzBinPEObj *bin, struct rz_bin_pe_section_t **sects)
 
RzList *PE_() section_flag_to_rzlist (ut64 flag)
 
struct rz_bin_pe_section_t *PE_() rz_bin_pe_get_sections (RzBinPEObj *bin)
 
int PE_() bin_pe_init_security (RzBinPEObj *bin)
 
const char *PE_() bin_pe_get_authentihash (RzBinPEObj *bin)
 
char *PE_() bin_pe_compute_authentihash (RzBinPEObj *bin)
 
int PE_() bin_pe_is_authhash_valid (RzBinPEObj *bin)
 
void PE_() free_security_directory (Pe_image_security_directory *security_directory)
 
int PE_() bin_pe_init_tls (RzBinPEObj *bin)
 
PE_DWord PE_() bin_pe_rva_to_paddr (RzBinPEObj *bin, PE_DWord rva)
 
PE_DWord PE_() bin_pe_rva_to_va (RzBinPEObj *bin, PE_DWord rva)
 
PE_DWord PE_() bin_pe_va_to_rva (RzBinPEObj *bin, PE_DWord va)
 
void *PE_() rz_bin_pe_free (RzBinPEObj *bin)
 
RzBinPEObj *PE_() rz_bin_pe_new (const char *file, bool verbose)
 
RzBinPEObj *PE_() rz_bin_pe_new_buf (RzBuffer *buf, bool verbose)
 

Macro Definition Documentation

◆ COFF_SYMBOL_SIZE

#define COFF_SYMBOL_SIZE   18

Definition at line 176 of file pe.h.

◆ DBG_FILE_NAME_LEN

#define DBG_FILE_NAME_LEN   255

Definition at line 117 of file pe.h.

◆ GUIDSTR_LEN

#define GUIDSTR_LEN   41

Definition at line 116 of file pe.h.

◆ IMAGE_SCN_ALIGN_1024BYTES

#define IMAGE_SCN_ALIGN_1024BYTES   0x00B00000

Definition at line 46 of file pe.h.

◆ IMAGE_SCN_ALIGN_128BYTES

#define IMAGE_SCN_ALIGN_128BYTES   0x00800000

Definition at line 43 of file pe.h.

◆ IMAGE_SCN_ALIGN_16BYTES

#define IMAGE_SCN_ALIGN_16BYTES   0x00500000

Definition at line 40 of file pe.h.

◆ IMAGE_SCN_ALIGN_1BYTES

#define IMAGE_SCN_ALIGN_1BYTES   0x00100000

Definition at line 36 of file pe.h.

◆ IMAGE_SCN_ALIGN_2048BYTES

#define IMAGE_SCN_ALIGN_2048BYTES   0x00C00000

Definition at line 47 of file pe.h.

◆ IMAGE_SCN_ALIGN_256BYTES

#define IMAGE_SCN_ALIGN_256BYTES   0x00900000

Definition at line 44 of file pe.h.

◆ IMAGE_SCN_ALIGN_2BYTES

#define IMAGE_SCN_ALIGN_2BYTES   0x00200000

Definition at line 37 of file pe.h.

◆ IMAGE_SCN_ALIGN_32BYTES

#define IMAGE_SCN_ALIGN_32BYTES   0x00600000

Definition at line 41 of file pe.h.

◆ IMAGE_SCN_ALIGN_4096BYTES

#define IMAGE_SCN_ALIGN_4096BYTES   0x00D00000

Definition at line 48 of file pe.h.

◆ IMAGE_SCN_ALIGN_4BYTES

#define IMAGE_SCN_ALIGN_4BYTES   0x00300000

Definition at line 38 of file pe.h.

◆ IMAGE_SCN_ALIGN_512BYTES

#define IMAGE_SCN_ALIGN_512BYTES   0x00A00000

Definition at line 45 of file pe.h.

◆ IMAGE_SCN_ALIGN_64BYTES

#define IMAGE_SCN_ALIGN_64BYTES   0x00700000

Definition at line 42 of file pe.h.

◆ IMAGE_SCN_ALIGN_8192BYTES

#define IMAGE_SCN_ALIGN_8192BYTES   0x00E00000

Definition at line 49 of file pe.h.

◆ IMAGE_SCN_ALIGN_8BYTES

#define IMAGE_SCN_ALIGN_8BYTES   0x00400000

Definition at line 39 of file pe.h.

◆ IMAGE_SCN_CNT_CODE

#define IMAGE_SCN_CNT_CODE   0x00000020

Definition at line 24 of file pe.h.

◆ IMAGE_SCN_CNT_INITIALIZED_DATA

#define IMAGE_SCN_CNT_INITIALIZED_DATA   0x00000040

Definition at line 25 of file pe.h.

◆ IMAGE_SCN_CNT_UNINITIALIZED_DATA

#define IMAGE_SCN_CNT_UNINITIALIZED_DATA   0x00000080

Definition at line 26 of file pe.h.

◆ IMAGE_SCN_GPREL

#define IMAGE_SCN_GPREL   0x00008000

Definition at line 31 of file pe.h.

◆ IMAGE_SCN_LNK_COMDAT

#define IMAGE_SCN_LNK_COMDAT   0x00001000

Definition at line 30 of file pe.h.

◆ IMAGE_SCN_LNK_INFO

#define IMAGE_SCN_LNK_INFO   0x00000200

Definition at line 28 of file pe.h.

◆ IMAGE_SCN_LNK_NRELOC_OVFL

#define IMAGE_SCN_LNK_NRELOC_OVFL   0x01000000

Definition at line 50 of file pe.h.

◆ IMAGE_SCN_LNK_OTHER

#define IMAGE_SCN_LNK_OTHER   0x00000100

Definition at line 27 of file pe.h.

◆ IMAGE_SCN_LNK_REMOVE

#define IMAGE_SCN_LNK_REMOVE   0x00000800

Definition at line 29 of file pe.h.

◆ IMAGE_SCN_MEM_16BIT

#define IMAGE_SCN_MEM_16BIT   0x00020000

Definition at line 33 of file pe.h.

◆ IMAGE_SCN_MEM_DISCARDABLE

#define IMAGE_SCN_MEM_DISCARDABLE   0x02000000

Definition at line 51 of file pe.h.

◆ IMAGE_SCN_MEM_LOCKED

#define IMAGE_SCN_MEM_LOCKED   0x00040000

Definition at line 34 of file pe.h.

◆ IMAGE_SCN_MEM_NOT_CACHED

#define IMAGE_SCN_MEM_NOT_CACHED   0x04000000

Definition at line 52 of file pe.h.

◆ IMAGE_SCN_MEM_NOT_PAGED

#define IMAGE_SCN_MEM_NOT_PAGED   0x08000000

Definition at line 53 of file pe.h.

◆ IMAGE_SCN_MEM_PRELOAD

#define IMAGE_SCN_MEM_PRELOAD   0x00080000

Definition at line 35 of file pe.h.

◆ IMAGE_SCN_MEM_PURGEABLE

#define IMAGE_SCN_MEM_PURGEABLE   0x00020000

Definition at line 32 of file pe.h.

◆ IMAGE_SCN_TYPE_NO_PAD

#define IMAGE_SCN_TYPE_NO_PAD   0x00000008

Definition at line 23 of file pe.h.

◆ MAX_METADATA_STRING_LENGTH

#define MAX_METADATA_STRING_LENGTH   256

Definition at line 175 of file pe.h.

◆ PE_READ_STRUCT_FIELD [1/2]

#define PE_READ_STRUCT_FIELD (   var,
  struct_type,
  field,
  size 
)    var->field = rz_read_le##size(buf + offsetof(struct_type, field))

Definition at line 177 of file pe.h.

◆ PE_READ_STRUCT_FIELD [2/2]

#define PE_READ_STRUCT_FIELD (   var,
  struct_type,
  field,
  size 
)    var->field = rz_read_le##size(buf + offsetof(struct_type, field))

Definition at line 177 of file pe.h.

◆ PE_SCN_ALIGN_MASK

#define PE_SCN_ALIGN_MASK   0x00F00000

Definition at line 55 of file pe.h.

◆ RZ_BIN_PE_SCN_IS_EXECUTABLE

#define RZ_BIN_PE_SCN_IS_EXECUTABLE (   x)    x &PE_IMAGE_SCN_MEM_EXECUTE

Definition at line 18 of file pe.h.

◆ RZ_BIN_PE_SCN_IS_READABLE

#define RZ_BIN_PE_SCN_IS_READABLE (   x)    x &PE_IMAGE_SCN_MEM_READ

Definition at line 19 of file pe.h.

◆ RZ_BIN_PE_SCN_IS_SHAREABLE

#define RZ_BIN_PE_SCN_IS_SHAREABLE (   x)    x &PE_IMAGE_SCN_MEM_SHARED

Definition at line 17 of file pe.h.

◆ RZ_BIN_PE_SCN_IS_WRITABLE

#define RZ_BIN_PE_SCN_IS_WRITABLE (   x)    x &PE_IMAGE_SCN_MEM_WRITE

Definition at line 20 of file pe.h.

◆ RzBinPEObj

#define RzBinPEObj   struct PE_(rz_bin_pe_obj_t)

Definition at line 126 of file pe.h.

Typedef Documentation

◆ rz_pe_resource

typedef struct _PE_RESOURCE rz_pe_resource

◆ SDebugInfo

typedef struct SDebugInfo SDebugInfo

Function Documentation

◆ bin_pe_compute_authentihash()

char* PE_() bin_pe_compute_authentihash ( RzBinPEObj bin)

Definition at line 21 of file pe_security.c.

21  {
22  if (!bin->spcinfo) {
23  return NULL;
24  }
25 
26  char *hashtype = strdup(bin->spcinfo->messageDigest.digestAlgorithm.algorithm->string);
27  rz_str_replace_char(hashtype, '-', 0);
28 
29  RzHashCfg *md = rz_hash_cfg_new_with_algo2(bin->hash, hashtype);
30  if (!md) {
31  free(hashtype);
32  return NULL;
33  }
34  ut32 checksum_paddr = bin->nt_header_offset + 4 + sizeof(PE_(image_file_header)) + 0x40;
35  ut32 security_entry_offset = bin->nt_header_offset + sizeof(PE_(image_nt_headers)) - 96;
36  PE_(image_data_directory) *data_dir_security = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_SECURITY];
37  PE_DWord security_dir_offset = data_dir_security->VirtualAddress;
38  ut32 security_dir_size = data_dir_security->Size;
39  rz_buf_fwd_scan(bin->b, 0, checksum_paddr, buf_fwd_hash, md);
40  rz_buf_fwd_scan(bin->b, checksum_paddr + 4, security_entry_offset - checksum_paddr - 4, buf_fwd_hash, md);
41  rz_buf_fwd_scan(bin->b, security_entry_offset + 8, security_dir_offset - security_entry_offset - 8, buf_fwd_hash, md);
42  rz_buf_fwd_scan(bin->b, security_dir_offset + security_dir_size, rz_buf_size(bin->b) - security_dir_offset - security_dir_size, buf_fwd_hash, md);
43 
44  RzHashSize digest_size = 0;
45  const ut8 *digest = NULL;
46  if (!rz_hash_cfg_final(md) ||
47  !(digest = rz_hash_cfg_get_result(md, hashtype, &digest_size))) {
48 
49  free(hashtype);
51  return NULL;
52  }
53 
54  char *hashstr = rz_hex_bin2strdup(digest, digest_size);
55  free(hashtype);
57  return hashstr;
58 }
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
RZ_API RZ_BORROW const ut8 * rz_hash_cfg_get_result(RZ_NONNULL RzHashCfg *md, RZ_NONNULL const char *name, RZ_NONNULL ut32 *size)
Returns the digest value of the requested algorithm name.
Definition: hash.c:445
RZ_API void rz_hash_cfg_free(RZ_NONNULL RzHashCfg *md)
Definition: hash.c:186
RZ_API bool rz_hash_cfg_final(RZ_NONNULL RzHashCfg *md)
Generates the final value of the message digest contextes.
Definition: hash.c:359
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
uint8_t ut8
Definition: lh5801.h:11
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static ut64 buf_fwd_hash(const ut8 *buf, ut64 size, void *user)
Definition: pe_security.c:17
#define PE_(name)
Definition: pe_specs.h:23
#define PE_IMAGE_DIRECTORY_ENTRY_SECURITY
Definition: pe_specs.h:147
#define PE_DWord
Definition: pe_specs.h:27
RZ_API ut64 rz_buf_fwd_scan(RZ_NONNULL RzBuffer *b, ut64 start, ut64 amount, RZ_NONNULL RzBufferFwdScan fwd_scan, RZ_NULLABLE void *user)
Scans buffer linearly in chunks calling fwd_scan for each chunk.
Definition: buf.c:1303
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
ut32 RzHashSize
Definition: rz_hash.h:24
RZ_API char * rz_hex_bin2strdup(const ut8 *in, int len)
Definition: hex.c:415
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169
Definition: malloc.c:26

References buf_fwd_hash(), free(), benchmark::md, NULL, PE_, PE_DWord, PE_IMAGE_DIRECTORY_ENTRY_SECURITY, rz_buf_fwd_scan(), rz_buf_size(), rz_hash_cfg_final(), rz_hash_cfg_free(), rz_hash_cfg_get_result(), rz_hex_bin2strdup(), rz_str_replace_char(), and strdup().

Referenced by bin_pe_get_authentihash().

◆ bin_pe_get_actual_checksum()

int PE_() bin_pe_get_actual_checksum ( RzBinPEObj bin)

Definition at line 249 of file pe_info.c.

249  {
250  size_t i, j, checksum_offset = 0;
251  ut64 computed_cs = 0;
252  int remaining_bytes;
253  int shift;
254  ut32 cur;
255  if (!bin || !bin->nt_header_offset) {
256  return 0;
257  }
258  const size_t buf_sz = 0x1000;
259  ut32 *buf = malloc(buf_sz);
260  if (!buf) {
261  return 0;
262  }
263  if (rz_buf_read_at(bin->b, 0, (ut8 *)buf, buf_sz) < 0) {
264  free(buf);
265  return 0;
266  }
267  checksum_offset = bin->nt_header_offset + 4 + sizeof(PE_(image_file_header)) + 0x40;
268  checksum_ctx ctx = { &computed_cs, bin->big_endian };
269  rz_buf_fwd_scan(bin->b, 0, checksum_offset, buf_fwd_checksum, &ctx);
270  rz_buf_fwd_scan(bin->b, checksum_offset + 4, bin->size - checksum_offset - 4 - bin->size % 4, buf_fwd_checksum, &ctx);
271 
272  // add resultant bytes to checksum
273  remaining_bytes = bin->size % 4;
274  i = bin->size - remaining_bytes;
275  if (remaining_bytes != 0) {
276  ut8 tmp;
277  if (!rz_buf_read8_at(bin->b, i, &tmp)) {
278  return 0;
279  }
280  cur = tmp;
281 
282  shift = 8;
283  for (j = 1; j < remaining_bytes; j++, shift += 8) {
284  if (!rz_buf_read8_at(bin->b, i + j, &tmp)) {
285  return 0;
286  }
287  cur |= tmp << shift;
288  }
289  computed_cs = (computed_cs & 0xFFFFFFFF) + cur + (computed_cs >> 32);
290  if (computed_cs >> 32) {
291  computed_cs = (computed_cs & 0xFFFFFFFF) + (computed_cs >> 32);
292  }
293  }
294 
295  // 32bits -> 16bits
296  computed_cs = (computed_cs & 0xFFFF) + (computed_cs >> 16);
297  computed_cs = (computed_cs) + (computed_cs >> 16);
298  computed_cs = (computed_cs & 0xFFFF);
299 
300  // add filesize
301  computed_cs += bin->size;
302  free(buf);
303  return computed_cs;
304 }
lzma_index ** i
Definition: index.h:629
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
Definition: arm_il32.c:190
voidpf void * buf
Definition: ioapi.h:138
void * malloc(size_t size)
Definition: malloc.c:123
static ut64 buf_fwd_checksum(const ut8 *buf, ut64 size, void *user)
Definition: pe_info.c:233
RZ_API bool rz_buf_read8_at(RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *result)
Read a byte at the specified address in the buffer.
Definition: buf.c:876
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References buf_fwd_checksum(), free(), i, malloc(), PE_, rz_buf_fwd_scan(), rz_buf_read8_at(), rz_buf_read_at(), shift(), autogen_x86imm::tmp, and ut64().

◆ bin_pe_get_authentihash()

const char* PE_() bin_pe_get_authentihash ( RzBinPEObj bin)

Definition at line 60 of file pe_security.c.

60  {
61  if (!bin->authentihash) {
62  bin->authentihash = PE_(bin_pe_compute_authentihash)(bin);
63  }
64  return bin->authentihash;
65 }
char *PE_() bin_pe_compute_authentihash(RzBinPEObj *bin)
Definition: pe_security.c:21

References bin_pe_compute_authentihash(), and PE_.

Referenced by bin_pe_init_security().

◆ bin_pe_get_claimed_checksum()

int PE_() bin_pe_get_claimed_checksum ( RzBinPEObj bin)

Definition at line 221 of file pe_info.c.

221  {
222  if (!bin || !bin->optional_header) {
223  return 0;
224  }
225  return bin->optional_header->CheckSum;
226 }

◆ bin_pe_get_overlay()

int PE_() bin_pe_get_overlay ( RzBinPEObj bin,
ut64 size 
)

Definition at line 16 of file pe_overlay.c.

16  {
17  ut64 largest_offset = 0;
18  ut64 largest_size = 0;
19  *size = 0;
20  int i;
21 
22  if (!bin) {
23  return 0;
24  }
25 
26  if (bin->optional_header) {
28  bin->nt_header_offset + 4 + sizeof(bin->nt_headers->file_header),
29  bin->nt_headers->file_header.SizeOfOptionalHeader,
30  bin->size,
31  &largest_offset,
32  &largest_size);
33  }
34 
35  struct rz_bin_pe_section_t *sects = bin->sections;
36  for (i = 0; !sects[i].last; i++) {
38  sects[i].paddr,
39  sects[i].size,
40  bin->size,
41  &largest_offset,
42  &largest_size);
43  }
44 
45  if (bin->optional_header) {
46  for (i = 0; i < PE_IMAGE_DIRECTORY_ENTRIES; i++) {
48  continue;
49  }
50 
52  PE_(bin_pe_rva_to_paddr)(bin, bin->data_directory[i].VirtualAddress),
53  bin->data_directory[i].Size,
54  bin->size,
55  &largest_offset,
56  &largest_size);
57  }
58  }
59 
60  if ((ut64)bin->size > largest_offset + largest_size) {
61  *size = bin->size - largest_offset - largest_size;
62  return largest_offset + largest_size;
63  }
64  return 0;
65 }
voidpf void uLong size
Definition: ioapi.h:138
PE_DWord PE_() bin_pe_rva_to_paddr(RzBinPEObj *bin, PE_DWord rva)
Definition: pe.c:15
static void computeOverlayOffset(ut64 offset, ut64 size, ut64 file_size, ut64 *largest_offset, ut64 *largest_size)
Definition: pe_overlay.c:8
#define PE_IMAGE_DIRECTORY_ENTRIES
Definition: pe_specs.h:142
ut64 paddr
Definition: pe.h:68

References bin_pe_rva_to_paddr(), computeOverlayOffset(), i, rz_bin_pe_section_t::last, rz_bin_pe_section_t::paddr, PE_, PE_IMAGE_DIRECTORY_ENTRIES, PE_IMAGE_DIRECTORY_ENTRY_SECURITY, and ut64().

Referenced by bin_pe_init_overlay().

◆ bin_pe_init_clr()

int PE_() bin_pe_init_clr ( RzBinPEObj bin)

Definition at line 122 of file pe_clr.c.

122  {
123  PE_(image_data_directory) *clr_dir = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
124  PE_DWord image_clr_hdr_paddr = PE_(bin_pe_rva_to_paddr)(bin, clr_dir->VirtualAddress);
125 
127  if (!clr) {
128  return -1;
129  }
130 
131  if (bin_pe_dotnet_init_clr(clr, bin->b, image_clr_hdr_paddr)) {
132  return -1;
133  }
134 
135  if (clr->header) {
136  PE_DWord metadata_directory = PE_(bin_pe_rva_to_paddr)(bin, clr->header->MetaDataDirectoryAddress);
137  bin_pe_dotnet_init_metadata(clr, bin->big_endian, bin->b, metadata_directory);
138  }
139 
140  bin->clr = clr;
141  return 0;
142 }
int bin_pe_dotnet_init_clr(Pe_image_clr *clr, RzBuffer *b, ut64 image_clr_hdr_paddr)
Definition: dotnet.c:932
int bin_pe_dotnet_init_metadata(Pe_image_clr *clr, bool big_endian, RzBuffer *b, ut64 metadata_directory)
Definition: dotnet.c:783
#define PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: pe_specs.h:158
#define RZ_NEW0(x)
Definition: rz_types.h:284
ut32 MetaDataDirectoryAddress
Definition: dotnet.h:15
Pe_image_clr_header * header
Definition: dotnet.h:151

References bin_pe_dotnet_init_clr(), bin_pe_dotnet_init_metadata(), bin_pe_rva_to_paddr(), Pe_image_clr::header, Pe_image_clr_header::MetaDataDirectoryAddress, PE_, PE_DWord, PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, and RZ_NEW0.

Referenced by bin_pe_init().

◆ bin_pe_init_exports()

int PE_() bin_pe_init_exports ( RzBinPEObj bin)

Definition at line 140 of file pe_exports.c.

140  {
141  PE_(image_data_directory) *data_dir_export = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_EXPORT];
142  PE_DWord export_dir_paddr = PE_(bin_pe_rva_to_paddr)(bin, data_dir_export->VirtualAddress);
143  if (!export_dir_paddr) {
144  // This export-dir-paddr should only appear in DLL files
145  // RZ_LOG_INFO("Warning: Cannot find the paddr of the export directory\n");
146  return false;
147  }
148  // sdb_setn (DB, "hdr.exports_directory", export_dir_paddr);
149  // RZ_LOG_INFO("Pexports paddr at 0x%"PFMT64x"\n", export_dir_paddr);
150  if (!(bin->export_directory = malloc(sizeof(PE_(image_export_directory))))) {
151  rz_sys_perror("malloc (export directory)");
152  return false;
153  }
154  if (read_image_export_directory(bin->b, export_dir_paddr, bin->export_directory) < 0) {
155  RZ_LOG_INFO("read (export directory)\n");
156  RZ_FREE(bin->export_directory);
157  return false;
158  }
159  return true;
160 }
static int read_image_export_directory(RzBuffer *b, ut64 addr, PE_(image_export_directory) *export_dir)
Definition: pe_exports.c:118
#define PE_IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: pe_specs.h:143
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define rz_sys_perror(x)
Definition: rz_types.h:336
#define RZ_FREE(x)
Definition: rz_types.h:369

References bin_pe_rva_to_paddr(), malloc(), PE_, PE_DWord, PE_IMAGE_DIRECTORY_ENTRY_EXPORT, read_image_export_directory(), RZ_FREE, RZ_LOG_INFO, and rz_sys_perror.

Referenced by bin_pe_init().

◆ bin_pe_init_hdr()

int PE_() bin_pe_init_hdr ( RzBinPEObj bin)

Definition at line 124 of file pe_hdr.c.

124  {
125  if (!(bin->dos_header = malloc(sizeof(PE_(image_dos_header))))) {
126  rz_sys_perror("malloc (dos header)");
127  return false;
128  }
129  if (!PE_(read_dos_header)(bin->b, bin->dos_header)) {
130  RZ_LOG_INFO("read (dos header)\n");
131  return false;
132  }
133  sdb_num_set(bin->kv, "pe_dos_header.offset", 0, 0);
134  sdb_set(bin->kv, "pe_dos_header.format", "[2]zwwwwwwwwwwwww[4]www[10]wx"
135  " e_magic e_cblp e_cp e_crlc e_cparhdr e_minalloc e_maxalloc"
136  " e_ss e_sp e_csum e_ip e_cs e_lfarlc e_ovno e_res e_oemid"
137  " e_oeminfo e_res2 e_lfanew",
138  0);
139  if (bin->dos_header->e_lfanew > (unsigned int)bin->size) {
140  RZ_LOG_INFO("Invalid e_lfanew field\n");
141  return false;
142  }
143  if (!(bin->nt_headers = malloc(sizeof(PE_(image_nt_headers))))) {
144  rz_sys_perror("malloc (nt header)");
145  return false;
146  }
147  bin->nt_header_offset = bin->dos_header->e_lfanew;
148  if (!PE_(read_nt_headers)(bin->b, bin->dos_header->e_lfanew, bin->nt_headers)) {
149  RZ_LOG_INFO("read (nt header)\n");
150  return false;
151  }
152  sdb_set(bin->kv, "pe_magic.cparse", "enum pe_magic { IMAGE_NT_OPTIONAL_HDR32_MAGIC=0x10b, IMAGE_NT_OPTIONAL_HDR64_MAGIC=0x20b, IMAGE_ROM_OPTIONAL_HDR_MAGIC=0x107 };", 0);
153  sdb_set(bin->kv, "pe_subsystem.cparse", "enum pe_subsystem { IMAGE_SUBSYSTEM_UNKNOWN=0, IMAGE_SUBSYSTEM_NATIVE=1, IMAGE_SUBSYSTEM_WINDOWS_GUI=2, "
154  " IMAGE_SUBSYSTEM_WINDOWS_CUI=3, IMAGE_SUBSYSTEM_OS2_CUI=5, IMAGE_SUBSYSTEM_POSIX_CUI=7, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI=9, "
155  " IMAGE_SUBSYSTEM_EFI_APPLICATION=10, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER=11, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER=12, "
156  " IMAGE_SUBSYSTEM_EFI_ROM=13, IMAGE_SUBSYSTEM_XBOX=14, IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION=16 };",
157  0);
158  sdb_set(bin->kv, "pe_dllcharacteristics.cparse", "enum pe_dllcharacteristics { IMAGE_LIBRARY_PROCESS_INIT=0x0001, IMAGE_LIBRARY_PROCESS_TERM=0x0002, "
159  " IMAGE_LIBRARY_THREAD_INIT=0x0004, IMAGE_LIBRARY_THREAD_TERM=0x0008, IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA=0x0020, "
160  " IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE=0x0040, IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY=0x0080, "
161  " IMAGE_DLLCHARACTERISTICS_NX_COMPAT=0x0100, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION=0x0200,IMAGE_DLLCHARACTERISTICS_NO_SEH=0x0400, "
162  " IMAGE_DLLCHARACTERISTICS_NO_BIND=0x0800, IMAGE_DLLCHARACTERISTICS_APPCONTAINER=0x1000, IMAGE_DLLCHARACTERISTICS_WDM_DRIVER=0x2000, "
163  " IMAGE_DLLCHARACTERISTICS_GUARD_CF=0x4000, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE=0x8000};",
164  0);
165 #if RZ_BIN_PE64
166  sdb_num_set(bin->kv, "pe_nt_image_headers64.offset", bin->dos_header->e_lfanew, 0);
167  sdb_set(bin->kv, "pe_nt_image_headers64.format", "[4]z?? signature (pe_image_file_header)fileHeader (pe_image_optional_header64)optionalHeader", 0);
168  sdb_set(bin->kv, "pe_image_optional_header64.format", "[2]Ebbxxxxxqxxwwwwwwxxxx[2]E[2]Bqqqqxx[16]?"
169  " (pe_magic)magic majorLinkerVersion minorLinkerVersion sizeOfCode sizeOfInitializedData"
170  " sizeOfUninitializedData addressOfEntryPoint baseOfCode imageBase"
171  " sectionAlignment fileAlignment majorOperatingSystemVersion minorOperatingSystemVersion"
172  " majorImageVersion minorImageVersion majorSubsystemVersion minorSubsystemVersion"
173  " win32VersionValue sizeOfImage sizeOfHeaders checkSum (pe_subsystem)subsystem (pe_dllcharacteristics)dllCharacteristics"
174  " sizeOfStackReserve sizeOfStackCommit sizeOfHeapReserve sizeOfHeapCommit loaderFlags"
175  " numberOfRvaAndSizes (pe_image_data_directory)dataDirectory",
176  0);
177 #else
178  sdb_num_set(bin->kv, "pe_nt_image_headers32.offset", bin->dos_header->e_lfanew, 0);
179  sdb_set(bin->kv, "pe_nt_image_headers32.format", "[4]z?? signature (pe_image_file_header)fileHeader (pe_image_optional_header32)optionalHeader", 0);
180  sdb_set(bin->kv, "pe_image_optional_header32.format", "[2]Ebbxxxxxxxxxwwwwwwxxxx[2]E[2]Bxxxxxx[16]?"
181  " (pe_magic)magic majorLinkerVersion minorLinkerVersion sizeOfCode sizeOfInitializedData"
182  " sizeOfUninitializedData addressOfEntryPoint baseOfCode baseOfData imageBase"
183  " sectionAlignment fileAlignment majorOperatingSystemVersion minorOperatingSystemVersion"
184  " majorImageVersion minorImageVersion majorSubsystemVersion minorSubsystemVersion"
185  " win32VersionValue sizeOfImage sizeOfHeaders checkSum (pe_subsystem)subsystem (pe_dllcharacteristics)dllCharacteristics"
186  " sizeOfStackReserve sizeOfStackCommit sizeOfHeapReserve sizeOfHeapCommit loaderFlags numberOfRvaAndSizes"
187  " (pe_image_data_directory)dataDirectory",
188  0);
189 #endif
190  sdb_set(bin->kv, "pe_machine.cparse", "enum pe_machine { IMAGE_FILE_MACHINE_I386=0x014c, IMAGE_FILE_MACHINE_IA64=0x0200, IMAGE_FILE_MACHINE_AMD64=0x8664 };", 0);
191  sdb_set(bin->kv, "pe_characteristics.cparse", "enum pe_characteristics { "
192  " IMAGE_FILE_RELOCS_STRIPPED=0x0001, IMAGE_FILE_EXECUTABLE_IMAGE=0x0002, IMAGE_FILE_LINE_NUMS_STRIPPED=0x0004, "
193  " IMAGE_FILE_LOCAL_SYMS_STRIPPED=0x0008, IMAGE_FILE_AGGRESIVE_WS_TRIM=0x0010, IMAGE_FILE_LARGE_ADDRESS_AWARE=0x0020, "
194  " IMAGE_FILE_BYTES_REVERSED_LO=0x0080, IMAGE_FILE_32BIT_MACHINE=0x0100, IMAGE_FILE_DEBUG_STRIPPED=0x0200, "
195  " IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP=0x0400, IMAGE_FILE_NET_RUN_FROM_SWAP=0x0800, IMAGE_FILE_SYSTEM=0x1000, "
196  " IMAGE_FILE_DLL=0x2000, IMAGE_FILE_UP_SYSTEM_ONLY=0x4000, IMAGE_FILE_BYTES_REVERSED_HI=0x8000 };",
197  0);
198  sdb_set(bin->kv, "pe_image_file_header.format", "[2]Ewtxxw[2]B"
199  " (pe_machine)machine numberOfSections timeDateStamp pointerToSymbolTable"
200  " numberOfSymbols sizeOfOptionalHeader (pe_characteristics)characteristics",
201  0);
202  sdb_set(bin->kv, "pe_image_data_directory.format", "xx virtualAddress size", 0);
203 
204  // adding compile time to the SDB
205  {
206  sdb_num_set(bin->kv, "image_file_header.TimeDateStamp", bin->nt_headers->file_header.TimeDateStamp, 0);
207  char *timestr = rz_time_stamp_to_str(bin->nt_headers->file_header.TimeDateStamp);
208  sdb_set_owned(bin->kv, "image_file_header.TimeDateStamp_string", timestr, 0);
209  }
210  bin->optional_header = &bin->nt_headers->optional_header;
211  bin->data_directory = (PE_(image_data_directory *)) & bin->optional_header->DataDirectory;
212 
213  if (bin->dos_header->e_magic != 0x5a4d || // "MZ"
214  (bin->nt_headers->Signature != 0x4550 && // "PE"
215  /* Check also for Phar Lap TNT DOS extender PL executable */
216  bin->nt_headers->Signature != 0x4c50)) { // "PL"
217  return false;
218  }
219  return true;
220 }
RZ_API int sdb_num_set(Sdb *s, const char *key, ut64 v, ut32 cas)
Definition: num.c:25
bool PE_() read_nt_headers(RzBuffer *buf, ut64 addr, PE_(image_nt_headers) *headers)
Definition: pe_hdr.c:109
bool PE_() read_dos_header(RzBuffer *buf, PE_(image_dos_header) *header)
Definition: pe_hdr.c:25
RZ_API RZ_OWN char * rz_time_stamp_to_str(ut32 timestamp)
Converts an unix epoch timestamp to string.
Definition: time.c:143
RZ_API int sdb_set_owned(Sdb *s, const char *key, char *val, ut32 cas)
Definition: sdb.c:607
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References if(), malloc(), PE_, read_dos_header(), read_nt_headers(), RZ_LOG_INFO, rz_sys_perror, rz_time_stamp_to_str(), sdb_num_set(), sdb_set(), and sdb_set_owned().

Referenced by bin_pe_init().

◆ bin_pe_init_imports()

int PE_() bin_pe_init_imports ( RzBinPEObj bin)

HACK to modify import size because of begin 0.. this may report wrong info con corkami tests

Definition at line 325 of file pe_imports.c.

325  {
326  PE_(image_data_directory) *data_dir_import = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_IMPORT];
327  PE_(image_data_directory) *data_dir_delay_import = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
328 
329  PE_DWord import_dir_paddr = PE_(bin_pe_rva_to_paddr)(bin, data_dir_import->VirtualAddress);
330  PE_DWord import_dir_offset = PE_(bin_pe_rva_to_paddr)(bin, data_dir_import->VirtualAddress);
331  PE_DWord delay_import_dir_offset = PE_(bin_pe_rva_to_paddr)(bin, data_dir_delay_import->VirtualAddress);
332 
333  PE_(image_import_directory) *import_dir = NULL;
334  PE_(image_import_directory) *new_import_dir = NULL;
335  PE_(image_import_directory) *curr_import_dir = NULL;
336 
337  PE_(image_delay_import_directory) *delay_import_dir = NULL;
338  PE_(image_delay_import_directory) *new_delay_import_dir = NULL;
339  PE_(image_delay_import_directory) *curr_delay_import_dir = NULL;
340 
341  int dir_size = sizeof(PE_(image_import_directory));
342  int delay_import_size = sizeof(PE_(image_delay_import_directory));
343  int indx = 0;
344  int rr, count = 0;
345  int import_dir_size = data_dir_import->Size;
346  int delay_import_dir_size = data_dir_delay_import->Size;
348  if (!import_dir_size) {
349  // asume 1 entry for each
350  import_dir_size = data_dir_import->Size = 0xffff;
351  }
352  if (!delay_import_dir_size) {
353  data_dir_delay_import->Size = 0xffff;
354  }
355  int maxidsz = RZ_MIN((PE_DWord)bin->size, import_dir_offset + import_dir_size);
356  maxidsz -= import_dir_offset;
357  if (maxidsz < 0) {
358  maxidsz = 0;
359  }
360  // int maxcount = maxidsz/ sizeof (struct rz_bin_pe_import_t);
361 
362  RZ_FREE(bin->import_directory);
363  if (import_dir_paddr != 0) {
364  if (import_dir_size < 1 || import_dir_size > maxidsz) {
365  RZ_LOG_INFO("Invalid import directory size: 0x%x is now 0x%x\n", import_dir_size, maxidsz);
366  import_dir_size = maxidsz;
367  }
368  bin->import_directory_offset = import_dir_offset;
369  count = 0;
370  do {
371  new_import_dir = (PE_(image_import_directory) *)realloc(import_dir, ((1 + indx) * dir_size));
372  if (!new_import_dir) {
373  rz_sys_perror("malloc (import directory)");
374  RZ_FREE(import_dir);
375  break; //
376  // goto fail;
377  }
378  import_dir = new_import_dir;
379  new_import_dir = NULL;
380  curr_import_dir = import_dir + indx;
381  if (PE_(read_image_import_directory)(bin->b, import_dir_offset + indx * dir_size, curr_import_dir) <= 0) {
382  RZ_LOG_INFO("read (import directory)\n");
383  RZ_FREE(import_dir);
384  break; // return false;
385  }
386  if (((2 + indx) * dir_size) > import_dir_size) {
387  break; // goto fail;
388  }
389  indx++;
390  count++;
391  } while (curr_import_dir->FirstThunk != 0 || curr_import_dir->Name != 0 ||
392  curr_import_dir->TimeDateStamp != 0 || curr_import_dir->Characteristics != 0 ||
393  curr_import_dir->ForwarderChain != 0);
394 
395  bin->import_directory = import_dir;
396  bin->import_directory_size = import_dir_size;
397  }
398 
399  indx = 0;
400  if (rz_buf_size(bin->b) > 0) {
401  if ((delay_import_dir_offset != 0) && (delay_import_dir_offset < (ut32)rz_buf_size(bin->b))) {
402  ut64 off;
403  bin->delay_import_directory_offset = delay_import_dir_offset;
404  do {
405  indx++;
406  off = indx * delay_import_size;
407  if (off >= rz_buf_size(bin->b)) {
408  RZ_LOG_INFO("Cannot find end of import symbols\n");
409  break;
410  }
411  new_delay_import_dir = (PE_(image_delay_import_directory) *)realloc(
412  delay_import_dir, (indx * delay_import_size) + 1);
413  if (!new_delay_import_dir) {
414  rz_sys_perror("malloc (delay import directory)");
415  free(delay_import_dir);
416  return false;
417  }
418  delay_import_dir = new_delay_import_dir;
419  curr_delay_import_dir = delay_import_dir + (indx - 1);
420  rr = PE_(read_image_delay_import_directory)(bin->b, delay_import_dir_offset + (indx - 1) * delay_import_size,
421  curr_delay_import_dir);
422  if (rr != dir_size) {
423  RZ_LOG_INFO("read (delay import directory)\n");
424  goto fail;
425  }
426  } while (curr_delay_import_dir->Name != 0);
427  bin->delay_import_directory = delay_import_dir;
428  }
429  }
430 
431  return true;
432 fail:
433  RZ_FREE(import_dir);
434  bin->import_directory = import_dir;
435  free(delay_import_dir);
436  return false;
437 }
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
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
int off
Definition: pal.c:13
int PE_() read_image_delay_import_directory(RzBuffer *b, ut64 addr, PE_(image_delay_import_directory) *directory)
Definition: pe_imports.c:24
int PE_() read_image_import_directory(RzBuffer *b, ut64 addr, PE_(image_import_directory) *import_dir)
Definition: pe_imports.c:8
#define PE_IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pe_specs.h:144
#define PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
Definition: pe_specs.h:157
#define RZ_MIN(x, y)
#define fail(test)
Definition: tests.h:29
static int indx(const char **ptr, const char **list, int error, const char **expr)
Definition: z80asm.c:154

References bin_pe_rva_to_paddr(), count, fail, free(), indx(), NULL, off, PE_, PE_DWord, PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, PE_IMAGE_DIRECTORY_ENTRY_IMPORT, read_image_delay_import_directory(), read_image_import_directory(), realloc(), rz_buf_size(), RZ_FREE, RZ_LOG_INFO, RZ_MIN, rz_sys_perror, and ut64().

Referenced by bin_pe_init().

◆ bin_pe_init_overlay()

int PE_() bin_pe_init_overlay ( RzBinPEObj bin)

Definition at line 67 of file pe_overlay.c.

67  {
68  ut64 pe_overlay_size;
69  ut64 pe_overlay_offset = PE_(bin_pe_get_overlay)(bin, &pe_overlay_size);
70  if (pe_overlay_offset) {
71  sdb_num_set(bin->kv, "pe_overlay.offset", pe_overlay_offset, 0);
72  sdb_num_set(bin->kv, "pe_overlay.size", pe_overlay_size, 0);
73  }
74  return 0;
75 }
int PE_() bin_pe_get_overlay(RzBinPEObj *bin, ut64 *size)
Definition: pe_overlay.c:16

References bin_pe_get_overlay(), PE_, sdb_num_set(), and ut64().

Referenced by bin_pe_init().

◆ bin_pe_init_resource()

int PE_() bin_pe_init_resource ( RzBinPEObj bin)

Definition at line 50 of file pe_rsrc.c.

50  {
51  PE_(image_data_directory) *resource_dir = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_RESOURCE];
52  PE_DWord resource_dir_paddr = PE_(bin_pe_rva_to_paddr)(bin, resource_dir->VirtualAddress);
53  if (!resource_dir_paddr) {
54  return false;
55  }
56 
58  if (!bin->resources) {
59  return false;
60  }
61  if (!(bin->resource_directory = malloc(sizeof(*bin->resource_directory)))) {
62  rz_sys_perror("malloc (resource directory)");
63  return false;
64  }
65  if (read_image_resource_directory(bin->b, resource_dir_paddr, bin->resource_directory) < 0) {
66  RZ_LOG_INFO("read (resource directory)\n");
67  RZ_FREE(bin->resource_directory);
68  return false;
69  }
70  bin->resource_directory_offset = resource_dir_paddr;
71  return true;
72 }
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
static int read_image_resource_directory(RzBuffer *b, ut64 addr, Pe_image_resource_directory *dir)
Definition: pe_rsrc.c:29
static void _free_resource(rz_pe_resource *rs)
Definition: pe_rsrc.c:9
#define PE_IMAGE_DIRECTORY_ENTRY_RESOURCE
Definition: pe_specs.h:145
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11

References _free_resource(), bin_pe_rva_to_paddr(), malloc(), PE_, PE_DWord, PE_IMAGE_DIRECTORY_ENTRY_RESOURCE, read_image_resource_directory(), RZ_FREE, rz_list_newf(), RZ_LOG_INFO, and rz_sys_perror.

Referenced by bin_pe_init().

◆ bin_pe_init_rich_info()

void PE_() bin_pe_init_rich_info ( RzBinPEObj bin)

Definition at line 1101 of file pe_rsrc.c.

1101  {
1102  if (!bin->rich_entries) {
1103  bin->rich_entries = rz_list_newf(free);
1104  }
1105  bin->rich_header_offset = bin->nt_header_offset;
1106  ut64 off = bin->nt_header_offset - sizeof(ut32);
1107  ut32 magic = 0x68636952; // Rich
1108  if (off % sizeof(ut32)) {
1109  return;
1110  }
1111 
1112  ut32 tmp;
1113  while (rz_buf_read_le32_at(bin->b, off, &tmp) && tmp != magic && off) {
1114  off -= sizeof(ut32);
1115  }
1116 
1117  if (!off) {
1118  return;
1119  }
1120 
1121  ut32 mask;
1122  if (!rz_buf_read_le32_at(bin->b, off + sizeof(ut32), &mask)) {
1123  return;
1124  }
1125 
1126  magic = 0x536E6144; // DanS
1127  off -= sizeof(ut32);
1128 
1129  ut32 data;
1130  while (rz_buf_read_le32_at(bin->b, off, &data) && data != magic && data ^ mask && off > 0x80) {
1132  if (!entry) {
1133  return;
1134  }
1135  entry->timesUsed = data ^ mask;
1136  off -= sizeof(ut32);
1137  if (!rz_buf_read_le32_at(bin->b, off, &data)) {
1138  free(entry);
1139  return;
1140  }
1141  data ^= mask;
1142  entry->productId = data >> 16;
1143  entry->minVersion = data & 0xFFFF;
1144  entry->productName = _known_product_ids(entry->productId);
1145  off -= sizeof(ut32);
1146  rz_list_append(bin->rich_entries, entry);
1147  }
1148  bin->rich_header_offset = off + sizeof(ut32);
1149 }
#define mask()
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
static char * _known_product_ids(int id)
Definition: pe_rsrc.c:849
#define rz_buf_read_le32_at(b, addr, result)
Definition: rz_buf.h:271
Definition: pe_specs.h:345
Definition: zipcmp.c:77

References _known_product_ids(), free(), mask, off, rz_buf_read_le32_at, rz_list_append(), rz_list_newf(), RZ_NEW0, autogen_x86imm::tmp, and ut64().

Referenced by bin_pe_init().

◆ bin_pe_init_sections()

int PE_() bin_pe_init_sections ( RzBinPEObj bin)

Definition at line 333 of file pe_section.c.

333  {
334  bin->num_sections = bin->nt_headers->file_header.NumberOfSections;
335  if (bin->num_sections < 1) {
336  return true;
337  }
338  ut64 sections_size = sizeof(PE_(image_section_header)) * bin->num_sections;
339  if (sections_size > bin->size) {
340  sections_size = bin->size;
341  bin->num_sections = bin->size / sizeof(PE_(image_section_header));
342  // massage this to make corkami happy
343  // RZ_LOG_INFO("Invalid NumberOfSections value\n");
344  // goto out_error;
345  }
346  if (!(bin->section_header = malloc(sections_size))) {
347  rz_sys_perror("malloc (section header)");
348  goto out_error;
349  }
350  bin->section_header_offset = bin->dos_header->e_lfanew + 4 + sizeof(PE_(image_file_header)) +
351  bin->nt_headers->file_header.SizeOfOptionalHeader;
352  int i;
353  for (i = 0; i < bin->num_sections; i++) {
354  if (!PE_(read_image_section_header)(bin->b, bin->section_header_offset + i * sizeof(PE_(image_section_header)),
355  bin->section_header + i)) {
356  RZ_LOG_INFO("read (sections)\n");
357  RZ_FREE(bin->section_header);
358  goto out_error;
359  }
360  }
361 #if 0
362  Each symbol table entry includes a name, storage class, type, value and section number.Short names (8 characters or fewer) are stored directly in the symbol table;
363  longer names are stored as an paddr into the string table at the end of the COFF object.
364 
365  ================================================================
366  COFF SYMBOL TABLE RECORDS (18 BYTES)
367  ================================================================
368  record
369  paddr
370 
371  struct symrec {
372  union {
373  char string[8]; // short name
374  struct {
375  ut32 seros;
376  ut32 stridx;
377  } stridx;
378  } name;
379  ut32 value;
380  ut16 secnum;
381  ut16 symtype;
382  ut8 symclass;
383  ut8 numaux;
384  }
385  ------------------------------------------------------ -
386  0 | 8 - char symbol name |
387  | or 32 - bit zeroes followed by 32 - bit |
388  | index into string table |
389  ------------------------------------------------------ -
390  8 | symbol value |
391  ------------------------------------------------------ -
392  0Ch | section number | symbol type |
393  ------------------------------------------------------ -
394  10h | sym class | num aux |
395  -------------------------- -
396  12h
397 
398 #endif
399  return true;
400 out_error:
401  bin->num_sections = 0;
402  return false;
403 }
const lzma_allocator const uint8_t * in
Definition: block.h:527
static int value
Definition: cmd_api.c:93
RzCryptoSelector bit
Definition: crypto.c:16
uint16_t ut16
#define true
@ TABLE
Definition: inflate9.h:15
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
int type
Definition: mipsasm.c:17
static const struct names names[]
const char * name
Definition: op.c:541
bool PE_() read_image_section_header(RzBuffer *b, ut64 addr, PE_(image_section_header) *section_header)
Definition: pe_section.c:212
int stored(struct state *s)
Definition: puff.c:164
#define a(i)
Definition: sha256.c:41
#define h(i)
Definition: sha256.c:48
#define Ch(x, y, z)
Definition: sha2.c:153
Definition: z80asm.h:102
Definition: names.h:123
Definition: tar.h:52

References a, bit, Ch, test_evm::end, h, i, if(), in, malloc(), name, names, num, rz_bin_pe_section_t::paddr, PE_, read_image_section_header(), RZ_FREE, RZ_LOG_INFO, rz_sys_perror, stored(), TABLE, true, type, ut64(), and value.

Referenced by bin_pe_init().

◆ bin_pe_init_security()

int PE_() bin_pe_init_security ( RzBinPEObj bin)

Definition at line 71 of file pe_security.c.

71  {
72  if (!bin || !bin->nt_headers) {
73  return false;
74  }
75  if (bin->nt_headers->optional_header.NumberOfRvaAndSizes < 5) {
76  return false;
77  }
78  PE_(image_data_directory) *data_dir_security = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_SECURITY];
79  PE_DWord paddr = data_dir_security->VirtualAddress;
80  ut32 size = data_dir_security->Size;
81  if (size < 8 || paddr > bin->size || paddr + size > bin->size) {
82  RZ_LOG_INFO("Invalid certificate table");
83  return false;
84  }
85 
87  if (!security_directory) {
88  return false;
89  }
90  bin->security_directory = security_directory;
91 
92  PE_DWord offset = paddr;
93  while (offset < paddr + size) {
94  Pe_certificate **tmp = (Pe_certificate **)realloc(security_directory->certificates, (security_directory->length + 1) * sizeof(Pe_certificate *));
95  if (!tmp) {
96  return false;
97  }
98  security_directory->certificates = tmp;
100  if (!cert) {
101  return false;
102  }
103  if (!rz_buf_read_le32_at(bin->b, offset, &cert->dwLength)) {
104  RZ_FREE(cert);
105  return false;
106  }
107  cert->dwLength += (8 - (cert->dwLength & 7)) & 7; // align32
108  if (offset + cert->dwLength > paddr + size) {
109  RZ_LOG_INFO("Invalid certificate entry");
110  RZ_FREE(cert);
111  return false;
112  }
113  if (!rz_buf_read_le16_at(bin->b, offset + 4, &cert->wRevision)) {
114  RZ_FREE(cert);
115  return false;
116  }
117  if (!rz_buf_read_le16_at(bin->b, offset + 6, &cert->wCertificateType)) {
118  RZ_FREE(cert);
119  return false;
120  }
121  if (cert->dwLength < 6) {
122  RZ_LOG_ERROR("Invalid cert.dwLength (must be > 6)\n");
123  RZ_FREE(cert);
124  return false;
125  }
126  if (!(cert->bCertificate = malloc(cert->dwLength - 6))) {
127  RZ_FREE(cert);
128  return false;
129  }
130  rz_buf_read_at(bin->b, offset + 8, cert->bCertificate, cert->dwLength - 6);
131 
133  bin->cms = rz_pkcs7_parse_cms(cert->bCertificate, cert->dwLength - 6);
134  bin->spcinfo = rz_pkcs7_parse_spcinfo(bin->cms);
135  }
136 
137  security_directory->certificates[security_directory->length] = cert;
138  security_directory->length++;
139  offset += cert->dwLength;
140  }
141 
142  if (bin->cms && bin->spcinfo) {
143  const char *actual_authentihash = PE_(bin_pe_get_authentihash)(bin);
144  const char *claimed_authentihash = PE_(bin_pe_get_claimed_authentihash)(bin);
145  if (actual_authentihash && claimed_authentihash) {
146  bin->is_authhash_valid = !strcmp(actual_authentihash, claimed_authentihash);
147  } else {
148  bin->is_authhash_valid = false;
149  }
150  free((void *)claimed_authentihash);
151  }
152  bin->is_signed = bin->cms != NULL;
153  return true;
154 }
voidpf uLong offset
Definition: ioapi.h:144
static const char *PE_() bin_pe_get_claimed_authentihash(RzBinPEObj *bin)
Definition: pe_security.c:9
const char *PE_() bin_pe_get_authentihash(RzBinPEObj *bin)
Definition: pe_security.c:60
#define PE_WIN_CERT_TYPE_PKCS_SIGNED_DATA
Definition: pe_specs.h:433
#define rz_buf_read_le16_at(b, addr, result)
Definition: rz_buf.h:270
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API RCMS * rz_pkcs7_parse_cms(const ut8 *buffer, ut32 length)
Definition: pkcs7.c:308
RZ_API SpcIndirectDataContent * rz_pkcs7_parse_spcinfo(RCMS *cms)
Definition: pkcs7.c:674
ut8 * bCertificate
Definition: pe_specs.h:421
ut16 wRevision
Definition: pe_specs.h:419
ut16 wCertificateType
Definition: pe_specs.h:420
Pe_certificate ** certificates
Definition: pe_specs.h:426

References Pe_certificate::bCertificate, bin_pe_get_authentihash(), bin_pe_get_claimed_authentihash(), Pe_image_security_directory::certificates, Pe_certificate::dwLength, free(), Pe_image_security_directory::length, malloc(), NULL, PE_, PE_DWord, PE_IMAGE_DIRECTORY_ENTRY_SECURITY, PE_WIN_CERT_TYPE_PKCS_SIGNED_DATA, realloc(), rz_buf_read_at(), rz_buf_read_le16_at, rz_buf_read_le32_at, RZ_FREE, RZ_LOG_ERROR, RZ_LOG_INFO, RZ_NEW0, rz_pkcs7_parse_cms(), rz_pkcs7_parse_spcinfo(), autogen_x86imm::tmp, Pe_certificate::wCertificateType, and Pe_certificate::wRevision.

Referenced by bin_pe_init().

◆ bin_pe_init_tls()

int PE_() bin_pe_init_tls ( RzBinPEObj bin)

Definition at line 71 of file pe_tls.c.

71  {
72  PE_(image_tls_directory) * image_tls_directory;
73  PE_(image_data_directory) *data_dir_tls = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_TLS];
74  PE_DWord tls_paddr = PE_(bin_pe_rva_to_paddr)(bin, data_dir_tls->VirtualAddress);
75 
76  image_tls_directory = RZ_NEW0(PE_(image_tls_directory));
77  if (read_tls_directory(bin->b, tls_paddr, image_tls_directory) < 0) {
78  RZ_LOG_INFO("read (image_tls_directory)\n");
79  free(image_tls_directory);
80  return 0;
81  }
82  bin->tls_directory = image_tls_directory;
83  if (!image_tls_directory->AddressOfCallBacks) {
84  return 0;
85  }
86  if (image_tls_directory->EndAddressOfRawData < image_tls_directory->StartAddressOfRawData) {
87  return 0;
88  }
89  PE_DWord callbacks_paddr = PE_(bin_pe_rva_to_paddr)(bin, PE_(bin_pe_va_to_rva)(bin, (PE_DWord)image_tls_directory->AddressOfCallBacks));
90  bin_pe_store_tls_callbacks(bin, callbacks_paddr);
91  return 0;
92 }
PE_DWord PE_() bin_pe_va_to_rva(RzBinPEObj *bin, PE_DWord va)
Definition: pe.c:32
#define PE_IMAGE_DIRECTORY_ENTRY_TLS
Definition: pe_specs.h:153
static void bin_pe_store_tls_callbacks(RzBinPEObj *bin, PE_DWord callbacks)
Definition: pe_tls.c:8
static int read_tls_directory(RzBuffer *b, ut64 addr, PE_(image_tls_directory) *tls_directory)
Definition: pe_tls.c:50

References bin_pe_rva_to_paddr(), bin_pe_store_tls_callbacks(), bin_pe_va_to_rva(), free(), PE_, PE_DWord, PE_IMAGE_DIRECTORY_ENTRY_TLS, read_tls_directory(), RZ_LOG_INFO, and RZ_NEW0.

Referenced by bin_pe_init().

◆ bin_pe_is_authhash_valid()

int PE_() bin_pe_is_authhash_valid ( RzBinPEObj bin)

Definition at line 67 of file pe_security.c.

67  {
68  return bin->is_authhash_valid;
69 }

◆ bin_pe_parse_resource()

RZ_API void PE_() bin_pe_parse_resource ( RzBinPEObj bin)

Definition at line 1523 of file pe_rsrc.c.

1523  {
1524  int index = 0;
1525  ut64 off = 0, rsrc_base = bin->resource_directory_offset;
1526  Pe_image_resource_directory *rs_directory = bin->resource_directory;
1527  ut32 curRes = 0;
1528  int totalRes = 0;
1529  HtUUOptions opt = { 0 };
1530  HtUU *dirs = ht_uu_new_opt(&opt); // to avoid infinite loops
1531  if (!dirs) {
1532  return;
1533  }
1534  if (!rs_directory) {
1535  ht_uu_free(dirs);
1536  return;
1537  }
1538  curRes = rs_directory->NumberOfNamedEntries;
1539  totalRes = curRes + rs_directory->NumberOfIdEntries;
1540  if (totalRes > RZ_PE_MAX_RESOURCES) {
1541  RZ_LOG_ERROR("Cannot parse resource directory\n");
1542  ht_uu_free(dirs);
1543  return;
1544  }
1545  for (index = 0; index < totalRes; index++) {
1547  off = rsrc_base + sizeof(*rs_directory) + index * sizeof(typeEntry);
1548  ht_uu_insert(dirs, off, 1);
1549  if (off > bin->size || off + sizeof(typeEntry) > bin->size) {
1550  break;
1551  }
1552  if (read_image_resource_directory_entry(bin->b, off, &typeEntry) < 0) {
1553  RZ_LOG_ERROR("read resource directory entry\n");
1554  break;
1555  }
1556  if (typeEntry.u2.OffsetToData >> 31) {
1557  Pe_image_resource_directory identEntry;
1558  ut32 OffsetToDirectory = typeEntry.u2.OffsetToData & 0x7fffffff;
1559  off = rsrc_base + OffsetToDirectory;
1560  int len = read_image_resource_directory(bin->b, off, &identEntry);
1561  if (len != sizeof(identEntry)) {
1562  RZ_LOG_ERROR("parsing resource directory\n");
1563  }
1564  (void)_parse_resource_directory(bin, &identEntry, OffsetToDirectory, typeEntry.u1.Name & 0xffff, 0, dirs, NULL);
1565  }
1566  }
1567  ht_uu_free(dirs);
1569 }
size_t len
Definition: 6502dis.c:15
static void _store_resource_sdb(RzBinPEObj *bin)
Definition: pe_rsrc.c:1494
static int read_image_resource_directory_entry(RzBuffer *b, ut64 addr, Pe_image_resource_directory_entry *entry)
Definition: pe_rsrc.c:1321
static void _parse_resource_directory(RzBinPEObj *bin, Pe_image_resource_directory *dir, ut64 offDir, int type, int id, HtUU *dirs, const char *resource_name)
Definition: pe_rsrc.c:1357
#define RZ_PE_MAX_RESOURCES
Definition: pe_specs.h:509
Definition: pe_specs.h:469
ut32 Name
Definition: pe_specs.h:476
ut32 OffsetToData
Definition: pe_specs.h:483
union Pe_image_resource_directory_entry::@191 u1
union Pe_image_resource_directory_entry::@192 u2

References _parse_resource_directory(), _store_resource_sdb(), len, Pe_image_resource_directory_entry::Name, NULL, Pe_image_resource_directory::NumberOfIdEntries, Pe_image_resource_directory::NumberOfNamedEntries, off, Pe_image_resource_directory_entry::OffsetToData, read_image_resource_directory(), read_image_resource_directory_entry(), RZ_LOG_ERROR, RZ_PE_MAX_RESOURCES, Pe_image_resource_directory_entry::u1, Pe_image_resource_directory_entry::u2, and ut64().

Referenced by bin_pe_init().

◆ bin_pe_rva_to_paddr()

PE_DWord PE_() bin_pe_rva_to_paddr ( RzBinPEObj bin,
PE_DWord  rva 
)

Definition at line 15 of file pe.c.

15  {
16  PE_DWord section_base;
17  int i, section_size;
18  for (i = 0; i < bin->num_sections; i++) {
19  section_base = bin->sections[i].vaddr;
20  section_size = bin->sections[i].vsize;
21  if (rva >= section_base && rva < section_base + section_size) {
22  return bin->sections[i].paddr + (rva - section_base);
23  }
24  }
25  return rva;
26 }
static ut64 rva(RzBinObject *o, ut64 paddr, ut64 vaddr, int va)
Definition: cbin.c:77

References i, PE_DWord, and rva().

Referenced by _parse_resource_directory(), bin_pe_get_overlay(), bin_pe_init_clr(), bin_pe_init_exports(), bin_pe_init_imports(), bin_pe_init_resource(), bin_pe_init_tls(), bin_pe_parse_imports(), bin_pe_store_tls_callbacks(), rz_bin_pe_get_clr_methoddef_offset(), rz_bin_pe_get_clr_symbols(), rz_bin_pe_get_debug_data(), rz_bin_pe_get_entrypoint(), rz_bin_pe_get_exports(), rz_bin_pe_get_imports(), and rz_bin_pe_get_libs().

◆ bin_pe_rva_to_va()

PE_DWord PE_() bin_pe_rva_to_va ( RzBinPEObj bin,
PE_DWord  rva 
)

◆ bin_pe_va_to_rva()

PE_DWord PE_() bin_pe_va_to_rva ( RzBinPEObj bin,
PE_DWord  va 
)

Definition at line 32 of file pe.c.

32  {
33  ut64 imageBase = PE_(rz_bin_pe_get_image_base)(bin);
34  if (va < imageBase) {
35  return va;
36  }
37  return va - imageBase;
38 }

References PE_, rz_bin_pe_get_image_base(), and ut64().

Referenced by bin_pe_init_tls(), and bin_pe_store_tls_callbacks().

◆ check_mingw()

struct rz_bin_pe_addr_t* PE_() check_mingw ( RzBinPEObj bin)

Definition at line 822 of file pe_info.c.

822  {
823  struct rz_bin_pe_addr_t *entry;
824  bool sw = false;
825  ut8 b[1024];
826  size_t n = 0;
827  if (!bin || !bin->b) {
828  return 0LL;
829  }
831  ZERO_FILL(b);
832  if (rz_buf_read_at(bin->b, entry->paddr, b, sizeof(b)) < 0) {
833  RZ_LOG_INFO("Cannot read entry at 0x%08" PFMT64x "\n", entry->paddr);
834  free(entry);
835  return NULL;
836  }
837  // mingw
838  // 55 push ebp
839  // 89 E5 mov ebp, esp
840  // 83 EC 08 sub esp, 8
841  // C7 04 24 01 00 00 00 mov dword ptr[esp], 1
842  // FF 15 C8 63 41 00 call ds : __imp____set_app_type
843  // E8 B8 FE FF FF call ___mingw_CRTStartup
844  if (b[0] == 0x55 && b[1] == 0x89 && b[3] == 0x83 && b[6] == 0xc7 && b[13] == 0xff && b[19] == 0xe8) {
845  sw = follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 19);
846  }
847  // 83 EC 1C sub esp, 1Ch
848  // C7 04 24 01 00 00 00 mov[esp + 1Ch + var_1C], 1
849  // FF 15 F8 60 40 00 call ds : __imp____set_app_type
850  // E8 6B FD FF FF call ___mingw_CRTStartup
851  if (b[0] == 0x83 && b[3] == 0xc7 && b[10] == 0xff && b[16] == 0xe8) {
852  sw = follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 16);
853  }
854  // 83 EC 0C sub esp, 0Ch
855  // C7 05 F4 0A 81 00 00 00 00 00 mov ds : _mingw_app_type, 0
856  // ED E8 3E AD 24 00 call ___security_init_cookie
857  // F2 83 C4 0C add esp, 0Ch
858  // F5 E9 86 FC FF FF jmp ___tmainCRTStartup
859  if (b[0] == 0x83 && b[3] == 0xc7 && b[13] == 0xe8 && b[18] == 0x83 && b[21] == 0xe9) {
860  sw = follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 21);
861  }
862  if (sw) {
863  // case1:
864  // from des address of call search for a1 xx xx xx xx 89 xx xx e8 xx xx xx xx
865  // A1 04 50 44 00 mov eax, ds:dword_445004
866  // 89 04 24 mov[esp + 28h + lpTopLevelExceptionFilter], eax
867  // E8 A3 01 00 00 call sub_4013EE
868  for (n = 0; n < sizeof(b) - 12; n++) {
869  if (b[n] == 0xa1 && b[n + 5] == 0x89 && b[n + 8] == 0xe8) {
870  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 8);
871  return entry;
872  }
873  }
874  }
875  free(entry);
876  return NULL;
877 }
int n
Definition: mipsasm.c:19
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_entrypoint(RzBinPEObj *bin)
Definition: pe_info.c:509
static bool follow_offset(struct rz_bin_pe_addr_t *entry, RzBuffer *buf, ut8 *b, int len, bool big_endian, size_t instr_off)
Definition: pe_info.c:616
#define ZERO_FILL(x)
Definition: rz_types.h:281
#define PFMT64x
Definition: rz_types.h:393
#define b(i)
Definition: sha256.c:42

References b, follow_offset(), free(), n, NULL, PE_, PFMT64x, rz_bin_pe_get_entrypoint(), rz_buf_read_at(), RZ_LOG_INFO, and ZERO_FILL.

Referenced by rz_bin_pe_get_main_vaddr().

◆ check_msvcseh()

struct rz_bin_pe_addr_t* PE_() check_msvcseh ( RzBinPEObj bin)

Definition at line 623 of file pe_info.c.

623  {
625  ut8 b[512];
626  size_t n = 0;
628  ZERO_FILL(b);
629  if (rz_buf_read_at(bin->b, entry->paddr, b, sizeof(b)) < 0) {
630  RZ_LOG_INFO("Cannot read entry at 0x%08" PFMT64x "\n", entry->paddr);
631  free(entry);
632  return NULL;
633  }
634 
635  read_and_follow_jump(entry, bin->b, b, sizeof(b), bin->big_endian);
636 
637  // MSVC SEH
638  // E8 13 09 00 00 call 0x44C388
639  // E9 05 00 00 00 jmp 0x44BA7F
640  if (b[0] == 0xe8 && b[5] == 0xe9) {
641  if (follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 5)) {
642  // case1:
643  // from des address of jmp search for 68 xx xx xx xx e8 and test xx xx xx xx = imagebase
644  // 68 00 00 40 00 push 0x400000
645  // E8 3E F9 FF FF call 0x44B4FF
646  ut32 imageBase = bin->nt_headers->optional_header.ImageBase;
647  for (n = 0; n < sizeof(b) - 6; n++) {
648  const ut32 tmp_imgbase = rz_read_ble32(b + n + 1, bin->big_endian);
649  if (b[n] == 0x68 && tmp_imgbase == imageBase && b[n + 5] == 0xe8) {
650  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 5);
651  return entry;
652  }
653  }
654  // case2:
655  // from des address of jmp search for 50 FF xx FF xx E8
656  // 50 push eax
657  // FF 37 push dword ptr[edi]
658  // FF 36 push dword ptr[esi]
659  // E8 6F FC FF FF call _main
660  for (n = 0; n < sizeof(b) - 6; n++) {
661  if (b[n] == 0x50 && b[n + 1] == 0xff && b[n + 3] == 0xff && b[n + 5] == 0xe8) {
662  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 5);
663  return entry;
664  }
665  }
666  // case3:
667  // 50 push eax
668  // FF 35 0C E2 40 00 push xxxxxxxx
669  // FF 35 08 E2 40 00 push xxxxxxxx
670  // E8 2B FD FF FF call _main
671  for (n = 0; n < sizeof(b) - 20; n++) {
672  if (b[n] == 0x50 && b[n + 1] == 0xff && b[n + 7] == 0xff && b[n + 13] == 0xe8) {
673  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 13);
674  return entry;
675  }
676  }
677  // case4:
678  // 50 push eax
679  // 57 push edi
680  // FF 36 push dword ptr[esi]
681  // E8 D9 FD FF FF call _main
682  for (n = 0; n < sizeof(b) - 5; n++) {
683  if (b[n] == 0x50 && b[n + 1] == 0x57 && b[n + 2] == 0xff && b[n + 4] == 0xe8) {
684  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 4);
685  return entry;
686  }
687  }
688  // case5:
689  // 57 push edi
690  // 56 push esi
691  // FF 36 push dword ptr[eax]
692  // E8 D9 FD FF FF call _main
693  for (n = 0; n < sizeof(b) - 5; n++) {
694  if (b[n] == 0x57 && b[n + 1] == 0x56 && b[n + 2] == 0xff && b[n + 4] == 0xe8) {
695  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 4);
696  return entry;
697  }
698  }
699  }
700  }
701 
702  // MSVC 32bit debug
703  if (b[3] == 0xe8) {
704  // 55 push ebp
705  // 8B EC mov ebp, esp
706  // E8 xx xx xx xx call xxxxxxxx
707  // 5D pop ebp
708  // C3 ret
709  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 3);
710  if (b[8] == 0xe8) {
711  // 55 push ebp
712  // 8B EC mov ebp, esp
713  // E8 xx xx xx xx call xxxxxxxx
714  // E8 xx xx xx xx call xxxxxxxx <- Follow this
715  // 5D pop ebp
716  // C3 ret
717  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 8);
718  for (n = 0; n < sizeof(b) - 17; n++) {
719  // E8 xx xx xx xx call sub.ucrtbased.dll__register_thread_local_exe_atexit_callback
720  // 83 C4 04 add esp, 4
721  // E8 xx xx xx xx call xxxxxxxx <- Follow this
722  // 89 xx xx mov dword [xxxx], eax
723  // E8 xx xx xx xx call xxxxxxxx
724  if (b[n] == 0xe8 && !memcmp(b + n + 5, "\x83\xc4\x04", 3) && b[n + 8] == 0xe8 && b[n + 13] == 0x89 && b[n + 16] == 0xe8) {
725  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 8);
726  int j, calls = 0;
727  for (j = 0; j < sizeof(b) - 4; j++) {
728  if (b[j] == 0xe8) {
729  // E8 xx xx xx xx call xxxxxxxx
730  calls++;
731  if (calls == 4) {
732  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, j);
733  return entry;
734  }
735  }
736  }
737  }
738  }
739  }
740  }
741 
742  // MSVC AMD64
743  int i;
744  for (i = 0; i < sizeof(b) - 14; i++) {
745  if (b[i] == 0x48 && b[i + 1] == 0x83 && b[i + 2] == 0xEC) {
746  break;
747  }
748  }
749  bool found_caller = false;
750  if (b[i + 13] == 0xe9) {
751  // 48 83 EC 28 sub rsp, 0x28
752  // E8 xx xx xx xx call xxxxxxxx
753  // 48 83 C4 28 add rsp, 0x28
754  // E9 xx xx xx xx jmp xxxxxxxx <- Follow this
755  found_caller = follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, i + 13);
756  } else {
757  // Debug
758  // 48 83 EC 28 sub rsp, 0x28
759  // E8 xx xx xx xx call xxxxxxxx
760  // 48 83 C4 28 add rsp, 0x28
761  // C3 ret
762  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, i + 4);
763  if (b[9] == 0xe8) {
764  // 48 83 EC 28 sub rsp, 0x28
765  // E8 xx xx xx xx call xxxxxxxx
766  // E8 xx xx xx xx call xxxxxxxx <- Follow this
767  // 48 83 C4 28 add rsp, 0x28
768  // C3 ret
769  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 9);
770  if (b[0x129] == 0xe8) {
771  // E8 xx xx xx xx call xxxxxxxx
772  found_caller = follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 0x129);
773  }
774  }
775  }
776  if (found_caller) {
777  // from des address of jmp, search for 4C ... 48 ... 8B ... E8
778  // 4C 8B C0 mov r8, rax
779  // 48 8B 17 mov rdx, qword [rdi]
780  // 8B 0B mov ecx, dword [rbx]
781  // E8 xx xx xx xx call main
782  // or
783  // 4C 8B 44 24 28 mov r8, qword [rsp + 0x28]
784  // 48 8B 54 24 30 mov rdx, qword [rsp + 0x30]
785  // 8B 4C 24 20 mov ecx, dword [rsp + 0x20]
786  // E8 xx xx xx xx call main
787  for (n = 0; n < sizeof(b) - 13; n++) {
788  if (b[n] == 0x4c && b[n + 3] == 0x48 && b[n + 6] == 0x8b && b[n + 8] == 0xe8) {
789  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 8);
790  return entry;
791  } else if (b[n] == 0x4c && b[n + 5] == 0x48 && b[n + 10] == 0x8b && b[n + 14] == 0xe8) {
792  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, n + 14);
793  return entry;
794  }
795  }
796  }
797  // Microsoft Visual-C
798  // 50 push eax
799  // FF 75 9C push dword [ebp - local_64h]
800  // 56 push esi
801  // 56 push esi
802  // FF 15 CC C0 44 00 call dword [sym.imp.KERNEL32.dll_GetModuleHandleA]
803  // 50 push eax
804  // E8 DB DA 00 00 call main
805  // 89 45 A0 mov dword [ebp - local_60h], eax
806  // 50 push eax
807  // E8 2D 00 00 00 call 0x4015a6
808  if (b[188] == 0x50 && b[201] == 0xe8) {
809  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 201);
810  return entry;
811  }
812 
813  if (b[292] == 0x50 && b[303] == 0xe8) {
814  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 303);
815  return entry;
816  }
817 
818  free(entry);
819  return NULL;
820 }
static bool read_and_follow_jump(struct rz_bin_pe_addr_t *entry, RzBuffer *buf, ut8 *b, int len, bool big_endian)
Definition: pe_info.c:603
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497

References b, follow_offset(), free(), i, n, NULL, PE_, PFMT64x, read_and_follow_jump(), rz_bin_pe_get_entrypoint(), rz_buf_read_at(), RZ_LOG_INFO, rz_read_ble32(), rz_return_val_if_fail, and ZERO_FILL.

Referenced by rz_bin_pe_get_main_vaddr().

◆ check_unknow()

struct rz_bin_pe_addr_t* PE_() check_unknow ( RzBinPEObj bin)

Definition at line 879 of file pe_info.c.

879  {
880  struct rz_bin_pe_addr_t *entry;
881  if (!bin || !bin->b) {
882  return 0LL;
883  }
884  ut8 b[512];
885  ZERO_FILL(b);
887  // option2: /x 8bff558bec83ec20
888  if (rz_buf_read_at(bin->b, entry->paddr, b, 512) < 1) {
889  RZ_LOG_INFO("Cannot read entry at 0x%08" PFMT64x "\n", entry->paddr);
890  free(entry);
891  return NULL;
892  }
893  /* Decode the jmp instruction, this gets the address of the 'main'
894  function for PE produced by a compiler whose name someone forgot to
895  write down. */
896  // this is dirty only a single byte check, can return false positives
897  if (b[367] == 0xe8) {
898  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, 367);
899  return entry;
900  }
901  size_t i;
902  for (i = 0; i < 512 - 16; i++) {
903  // 5. ff 15 .. .. .. .. 50 e8 [main]
904  if (!memcmp(b + i, "\xff\x15", 2)) {
905  if (b[i + 6] == 0x50) {
906  if (b[i + 7] == 0xe8) {
907  follow_offset(entry, bin->b, b, sizeof(b), bin->big_endian, i + 7);
908  return entry;
909  }
910  }
911  }
912  }
913  free(entry);
914  return NULL;
915 }

References b, follow_offset(), free(), i, NULL, PE_, PFMT64x, rz_bin_pe_get_entrypoint(), rz_buf_read_at(), RZ_LOG_INFO, and ZERO_FILL.

Referenced by rz_bin_pe_get_main_vaddr().

◆ free_security_directory()

void PE_() free_security_directory ( Pe_image_security_directory security_directory)

Definition at line 156 of file pe_security.c.

156  {
157  if (!security_directory) {
158  return;
159  }
160  size_t numCert = 0;
161  for (; numCert < security_directory->length; numCert++) {
162  free(security_directory->certificates[numCert]);
163  }
164  free(security_directory->certificates);
165  free(security_directory);
166 }

References free().

Referenced by rz_bin_pe_free().

◆ PE_()

struct PE_ ( rz_bin_pe_obj_t  )

Definition at line 1 of file pe.h.

127  {
128  // these pointers contain a copy of the headers and sections!
129  PE_(image_dos_header) * dos_header;
130  PE_(image_nt_headers) * nt_headers;
131  PE_(image_optional_header) * optional_header; // not free this just pointer into nt_headers
132  PE_(image_data_directory) * data_directory; // not free this just pointer into nt_headers
133  PE_(image_section_header) * section_header;
134  PE_(image_export_directory) * export_directory;
135  PE_(image_import_directory) * import_directory;
136  PE_(image_tls_directory) * tls_directory;
137  Pe_image_resource_directory *resource_directory;
138  PE_(image_delay_import_directory) * delay_import_directory;
139  Pe_image_security_directory *security_directory;
140 
141  Pe_image_clr *clr; // dotnet information
142 
143  /* store the section information for future use */
145 
146  // these values define the real offset into the untouched binary
147  ut64 rich_header_offset;
148  ut64 nt_header_offset;
149  ut64 section_header_offset;
150  ut64 import_directory_offset;
151  ut64 export_directory_offset;
152  ut64 resource_directory_offset;
153  ut64 delay_import_directory_offset;
154 
155  int import_directory_size;
156  ut64 size;
157  int num_sections;
158  int endian;
159  bool verbose;
160  int big_endian;
161  RzList *rich_entries;
162  RzList *relocs;
163  RzList *resources; // RzList of rz_pe_resources
164  const char *file;
165  RzBuffer *b;
166  Sdb *kv;
167  RCMS *cms;
168  SpcIndirectDataContent *spcinfo;
169  char *authentihash;
170  bool is_authhash_valid;
171  bool is_signed;
172  RzHash *hash;
173 };
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
RzList * relocs(RzBinFile *bf)
Definition: bin_ne.c:114
struct PE_(rz_bin_pe_obj_t)
Definition: pe.h:127
Definition: sdb.h:63
static int verbose
Definition: z80asm.c:73
static int file
Definition: z80asm.c:58

◆ read_image_delay_import_directory()

int PE_() read_image_delay_import_directory ( RzBuffer b,
ut64  addr,
PE_(image_delay_import_directory) *  directory 
)

Definition at line 24 of file pe_imports.c.

24  {
25  st64 o_addr = rz_buf_seek(b, 0, RZ_BUF_CUR);
26  if (rz_buf_seek(b, addr, RZ_BUF_SET) < 0) {
27  return -1;
28  }
29  ut8 buf[sizeof(PE_(image_delay_import_directory))];
30  rz_buf_read(b, buf, sizeof(buf));
31  PE_READ_STRUCT_FIELD(directory, PE_(image_delay_import_directory), Attributes, 32);
32  PE_READ_STRUCT_FIELD(directory, PE_(image_delay_import_directory), Name, 32);
33  PE_READ_STRUCT_FIELD(directory, PE_(image_delay_import_directory), ModulePlugin, 32);
34  PE_READ_STRUCT_FIELD(directory, PE_(image_delay_import_directory), DelayImportAddressTable, 32);
35  PE_READ_STRUCT_FIELD(directory, PE_(image_delay_import_directory), DelayImportNameTable, 32);
36  PE_READ_STRUCT_FIELD(directory, PE_(image_delay_import_directory), BoundDelayImportTable, 32);
37  PE_READ_STRUCT_FIELD(directory, PE_(image_delay_import_directory), UnloadDelayImportTable, 32);
38  PE_READ_STRUCT_FIELD(directory, PE_(image_delay_import_directory), TimeStamp, 32);
39  rz_buf_seek(b, o_addr, RZ_BUF_SET);
40  return sizeof(PE_(image_delay_import_directory));
41 }
directory
Definition: regress.py:17
#define PE_READ_STRUCT_FIELD(var, struct_type, field, size)
Definition: pe.h:177
RZ_API st64 rz_buf_seek(RZ_NONNULL RzBuffer *b, st64 addr, int whence)
Modify the current cursor position in the buffer.
Definition: buf.c:1166
#define RZ_BUF_CUR
Definition: rz_buf.h:15
#define RZ_BUF_SET
Definition: rz_buf.h:14
RZ_API st64 rz_buf_read(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
#define st64
Definition: rz_types_base.h:10
static int addr
Definition: z80asm.c:58

References addr, b, regress::directory, PE_, PE_READ_STRUCT_FIELD, RZ_BUF_CUR, rz_buf_read(), rz_buf_seek(), RZ_BUF_SET, and st64.

Referenced by bin_pe_init_imports(), rz_bin_pe_get_imports(), and rz_bin_pe_get_libs().

◆ read_image_import_directory()

int PE_() read_image_import_directory ( RzBuffer b,
ut64  addr,
PE_(image_import_directory) *  import_dir 
)

Definition at line 8 of file pe_imports.c.

8  {
9  st64 o_addr = rz_buf_seek(b, 0, RZ_BUF_CUR);
10  if (rz_buf_seek(b, addr, RZ_BUF_SET) < 0) {
11  return -1;
12  }
13  ut8 buf[sizeof(PE_(image_import_directory))];
14  rz_buf_read(b, buf, sizeof(buf));
15  PE_READ_STRUCT_FIELD(import_dir, PE_(image_import_directory), Characteristics, 32);
16  PE_READ_STRUCT_FIELD(import_dir, PE_(image_import_directory), TimeDateStamp, 32);
17  PE_READ_STRUCT_FIELD(import_dir, PE_(image_import_directory), ForwarderChain, 32);
18  PE_READ_STRUCT_FIELD(import_dir, PE_(image_import_directory), Name, 32);
19  PE_READ_STRUCT_FIELD(import_dir, PE_(image_import_directory), FirstThunk, 32);
20  rz_buf_seek(b, o_addr, RZ_BUF_SET);
21  return sizeof(PE_(image_import_directory));
22 }

References addr, b, PE_, PE_READ_STRUCT_FIELD, RZ_BUF_CUR, rz_buf_read(), rz_buf_seek(), RZ_BUF_SET, and st64.

Referenced by bin_pe_init_imports(), rz_bin_pe_get_imports(), and rz_bin_pe_get_libs().

◆ rz_bin_pe_check_sections()

void PE_() rz_bin_pe_check_sections ( RzBinPEObj bin,
struct rz_bin_pe_section_t **  sects 
)

Definition at line 10 of file pe_section.c.

10  {
11  int i = 0;
12  struct rz_bin_pe_section_t *sections = *sects;
13  ut64 addr_beg, addr_end, new_section_size, new_perm, base_addr;
15 
16  if (!entry) {
17  return;
18  }
19  new_section_size = bin->size;
20  new_section_size -= entry->paddr > bin->size ? 0 : entry->paddr;
22  base_addr = PE_(rz_bin_pe_get_image_base)(bin);
23 
24  for (i = 0; !sections[i].last; i++) {
25  // strcmp against .text doesn't work in somes cases
26  if (strstr((const char *)sections[i].name, "text")) {
27  bool fix = false;
28  int j;
29  // check paddr boundaries
30  addr_beg = sections[i].paddr;
31  addr_end = addr_beg + sections[i].size;
32  if (entry->paddr < addr_beg || entry->paddr > addr_end) {
33  fix = true;
34  }
35  // check vaddr boundaries
36  addr_beg = sections[i].vaddr + base_addr;
37  addr_end = addr_beg + sections[i].vsize;
38  if (entry->vaddr < addr_beg || entry->vaddr > addr_end) {
39  fix = true;
40  }
41  // look for other segment with x that is already mapped and hold entrypoint
42  for (j = 0; !sections[j].last; j++) {
43  addr_beg = sections[j].paddr;
44  addr_end = addr_beg + sections[j].size;
45  if (addr_beg <= entry->paddr && entry->paddr < addr_end) {
46  if (!sections[j].vsize) {
47  sections[j].vsize = sections[j].size;
48  }
49  addr_beg = sections[j].vaddr + base_addr;
50  addr_end = addr_beg + sections[j].vsize;
51  if (addr_beg <= entry->vaddr || entry->vaddr < addr_end) {
52  if (!(sections[j].perm & PE_IMAGE_SCN_MEM_EXECUTE)) {
53  if (bin->verbose) {
54  RZ_LOG_ERROR("Found entrypoint in non-executable section.\n");
55  }
57  }
58  fix = false;
59  break;
60  }
61  }
62  }
63  // if either vaddr or paddr fail we should update this section
64  if (fix) {
65  strcpy((char *)sections[i].name, "blob");
66  sections[i].paddr = entry->paddr;
67  sections[i].vaddr = entry->vaddr - base_addr;
68  sections[i].size = sections[i].vsize = new_section_size;
69  sections[i].perm = new_perm;
70  }
71  goto out_function;
72  }
73  }
74  // if we arrive til here means there is no text section find one that is holding the code
75  for (i = 0; !sections[i].last; i++) {
76  if (sections[i].size > bin->size) {
77  continue;
78  }
79  addr_beg = sections[i].paddr;
80  addr_end = addr_beg + sections[i].size;
81  if (addr_beg <= entry->paddr && entry->paddr < addr_end) {
82  if (!sections[i].vsize) {
83  sections[i].vsize = sections[i].size;
84  }
85  addr_beg = sections[i].vaddr + base_addr;
86  addr_end = addr_beg + sections[i].vsize;
87  if (entry->vaddr < addr_beg || entry->vaddr > addr_end) {
88  sections[i].vaddr = entry->vaddr - base_addr;
89  }
90  goto out_function;
91  }
92  }
93  // we need to create another section in order to load the entrypoint
94  void *ss = realloc(sections, (bin->num_sections + 2) * sizeof(struct rz_bin_pe_section_t));
95  if (!ss) {
96  goto out_function;
97  }
98  bin->sections = sections = ss;
99  i = bin->num_sections;
100  sections[i].last = 0;
101  strcpy((char *)sections[i].name, "blob");
102  sections[i].paddr = entry->paddr;
103  sections[i].vaddr = entry->vaddr - base_addr;
104  sections[i].size = sections[i].vsize = new_section_size;
105  sections[i].perm = new_perm;
106  sections[i + 1].last = 1;
107  *sects = sections;
108 out_function:
109  free(entry);
110  return;
111 }
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_entrypoint(RzBinPEObj *bin)
Definition: pe_info.c:509
#define PE_IMAGE_SCN_MEM_EXECUTE
Definition: pe_specs.h:355
#define PE_IMAGE_SCN_MEM_WRITE
Definition: pe_specs.h:357
#define PE_IMAGE_SCN_MEM_READ
Definition: pe_specs.h:356
ut64 vaddr
Definition: pe.h:58
ut64 paddr
Definition: pe.h:59

References free(), i, rz_bin_pe_addr_t::paddr, PE_, PE_IMAGE_SCN_MEM_EXECUTE, PE_IMAGE_SCN_MEM_READ, PE_IMAGE_SCN_MEM_WRITE, realloc(), rz_bin_pe_get_entrypoint(), rz_bin_pe_get_image_base(), RZ_LOG_ERROR, sections(), ut64(), and rz_bin_pe_addr_t::vaddr.

Referenced by rz_bin_mdmp_pe_get_sections().

◆ rz_bin_pe_free()

void* PE_() rz_bin_pe_free ( RzBinPEObj bin)

Definition at line 88 of file pe.c.

88  {
89  if (!bin) {
90  return NULL;
91  }
92  free(bin->dos_header);
93  free(bin->nt_headers);
94  free(bin->section_header);
95  free(bin->export_directory);
96  free(bin->import_directory);
97  free(bin->resource_directory);
99  (bin->security_directory);
100  free(bin->delay_import_directory);
102  free(bin->tls_directory);
103  free(bin->sections);
104  free(bin->authentihash);
105  rz_list_free(bin->rich_entries);
106  rz_list_free(bin->resources);
107  rz_pkcs7_free_cms(bin->cms);
108  rz_pkcs7_free_spcinfo(bin->spcinfo);
109  rz_hash_free(bin->hash);
110  rz_buf_free(bin->b);
111  bin->b = NULL;
112  free(bin);
113  return NULL;
114 }
void bin_pe_dotnet_destroy_clr(Pe_image_clr *clr)
Definition: dotnet.c:968
RZ_API void rz_hash_free(RzHash *rh)
Definition: hash.c:597
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void PE_() free_security_directory(Pe_image_security_directory *security_directory)
Definition: pe_security.c:156
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API void rz_pkcs7_free_cms(RCMS *container)
Definition: pkcs7.c:341
RZ_API void rz_pkcs7_free_spcinfo(SpcIndirectDataContent *spcinfo)
Definition: pkcs7.c:729

References bin_pe_dotnet_destroy_clr(), free(), free_security_directory(), NULL, PE_, rz_buf_free(), rz_hash_free(), rz_list_free(), rz_pkcs7_free_cms(), and rz_pkcs7_free_spcinfo().

Referenced by rz_bin_pe_new_buf(), rz_bin_pemixed_free(), rz_bin_pemixed_from_bytes_new(), and rz_bin_pemixed_init_dos().

◆ rz_bin_pe_get_arch()

char* PE_() rz_bin_pe_get_arch ( RzBinPEObj bin)

Definition at line 114 of file pe_info.c.

114  {
115  char *arch;
116  if (!bin || !bin->nt_headers) {
117  return strdup("x86");
118  }
119  switch (bin->nt_headers->file_header.Machine) {
122  arch = strdup("alpha");
123  break;
127  arch = strdup("arm");
128  break;
130  arch = strdup("m68k");
131  break;
136  arch = strdup("mips");
137  break;
140  arch = strdup("ppc");
141  break;
143  arch = strdup("ebc");
144  break;
146  arch = strdup("arm");
147  break;
151  arch = strdup("riscv");
152  break;
153  default:
154  arch = strdup("x86");
155  }
156  return arch;
157 }
cs_arch arch
Definition: cstool.c:13
#define PE_IMAGE_FILE_MACHINE_M68K
Definition: pe_specs.h:79
#define PE_IMAGE_FILE_MACHINE_MIPSFPU16
Definition: pe_specs.h:82
#define PE_IMAGE_FILE_MACHINE_ARMNT
Definition: pe_specs.h:70
#define PE_IMAGE_FILE_MACHINE_ARM
Definition: pe_specs.h:69
#define PE_IMAGE_FILE_MACHINE_ALPHA
Definition: pe_specs.h:65
#define PE_IMAGE_FILE_MACHINE_RISCV64
Definition: pe_specs.h:97
#define PE_IMAGE_FILE_MACHINE_THUMB
Definition: pe_specs.h:93
#define PE_IMAGE_FILE_MACHINE_ARM64
Definition: pe_specs.h:71
#define PE_IMAGE_FILE_MACHINE_EBC
Definition: pe_specs.h:75
#define PE_IMAGE_FILE_MACHINE_RISCV128
Definition: pe_specs.h:98
#define PE_IMAGE_FILE_MACHINE_RISCV32
Definition: pe_specs.h:96
#define PE_IMAGE_FILE_MACHINE_WCEMIPSV2
Definition: pe_specs.h:95
#define PE_IMAGE_FILE_MACHINE_MIPS16
Definition: pe_specs.h:80
#define PE_IMAGE_FILE_MACHINE_MIPSFPU
Definition: pe_specs.h:81
#define PE_IMAGE_FILE_MACHINE_POWERPC
Definition: pe_specs.h:83
#define PE_IMAGE_FILE_MACHINE_POWERPCFP
Definition: pe_specs.h:84
#define PE_IMAGE_FILE_MACHINE_ALPHA64
Definition: pe_specs.h:66

References arch, PE_IMAGE_FILE_MACHINE_ALPHA, PE_IMAGE_FILE_MACHINE_ALPHA64, PE_IMAGE_FILE_MACHINE_ARM, PE_IMAGE_FILE_MACHINE_ARM64, PE_IMAGE_FILE_MACHINE_ARMNT, PE_IMAGE_FILE_MACHINE_EBC, PE_IMAGE_FILE_MACHINE_M68K, PE_IMAGE_FILE_MACHINE_MIPS16, PE_IMAGE_FILE_MACHINE_MIPSFPU, PE_IMAGE_FILE_MACHINE_MIPSFPU16, PE_IMAGE_FILE_MACHINE_POWERPC, PE_IMAGE_FILE_MACHINE_POWERPCFP, PE_IMAGE_FILE_MACHINE_RISCV128, PE_IMAGE_FILE_MACHINE_RISCV32, PE_IMAGE_FILE_MACHINE_RISCV64, PE_IMAGE_FILE_MACHINE_THUMB, PE_IMAGE_FILE_MACHINE_WCEMIPSV2, and strdup().

◆ rz_bin_pe_get_bits()

int PE_() rz_bin_pe_get_bits ( RzBinPEObj bin)

Definition at line 306 of file pe_info.c.

306  {
307  int bits = 32;
308  if (bin && bin->nt_headers) {
309  if (is_arm(bin) && is_thumb(bin)) {
310  bits = 16;
311  } else {
312  switch (bin->nt_headers->optional_header.Magic) {
313  case PE_IMAGE_FILE_TYPE_PE32: bits = 32; break;
314  case PE_IMAGE_FILE_TYPE_PE32PLUS: bits = 64; break;
315  default: bits = -1;
316  }
317  }
318  }
319  return bits;
320 }
int bits(struct state *s, int need)
Definition: blast.c:72
static int is_thumb(RzBinPEObj *bin)
Definition: pe_info.c:8
static int is_arm(RzBinPEObj *bin)
Definition: pe_info.c:12
#define PE_IMAGE_FILE_TYPE_PE32
Definition: pe_specs.h:61
#define PE_IMAGE_FILE_TYPE_PE32PLUS
Definition: pe_specs.h:62

References bits(), is_arm(), is_thumb(), PE_IMAGE_FILE_TYPE_PE32, and PE_IMAGE_FILE_TYPE_PE32PLUS.

◆ rz_bin_pe_get_cc()

char* PE_() rz_bin_pe_get_cc ( RzBinPEObj bin)

Definition at line 201 of file pe_info.c.

201  {
202  if (bin && bin->nt_headers) {
203  if (is_arm(bin)) {
204  if (is_thumb(bin)) {
205  return strdup("arm16");
206  }
207  switch (bin->nt_headers->optional_header.Magic) {
208  case PE_IMAGE_FILE_TYPE_PE32: return strdup("arm32");
209  case PE_IMAGE_FILE_TYPE_PE32PLUS: return strdup("arm64");
210  }
211  } else {
212  switch (bin->nt_headers->optional_header.Magic) {
213  case PE_IMAGE_FILE_TYPE_PE32: return strdup("cdecl");
214  case PE_IMAGE_FILE_TYPE_PE32PLUS: return strdup("ms");
215  }
216  }
217  }
218  return NULL;
219 }

References is_arm(), is_thumb(), NULL, PE_IMAGE_FILE_TYPE_PE32, PE_IMAGE_FILE_TYPE_PE32PLUS, and strdup().

◆ rz_bin_pe_get_class()

char* PE_() rz_bin_pe_get_class ( RzBinPEObj bin)

Definition at line 103 of file pe_info.c.

103  {
104  if (bin && bin->nt_headers) {
105  switch (bin->nt_headers->optional_header.Magic) {
106  case PE_IMAGE_FILE_TYPE_PE32: return strdup("PE32");
107  case PE_IMAGE_FILE_TYPE_PE32PLUS: return strdup("PE32+");
108  default: return strdup("Unknown");
109  }
110  }
111  return NULL;
112 }

References NULL, PE_IMAGE_FILE_TYPE_PE32, PE_IMAGE_FILE_TYPE_PE32PLUS, and strdup().

◆ rz_bin_pe_get_clr_methoddef_offset()

ut64 PE_() rz_bin_pe_get_clr_methoddef_offset ( RzBinPEObj bin,
Pe_image_metadata_methoddef methoddef 
)

Definition at line 104 of file pe_clr.c.

104  {
105  if (!bin || !bin->clr || !methoddef) {
106  return UT64_MAX;
107  }
108 
109  RzBinSymbol sym;
110  sym.vaddr = PE_(bin_pe_rva_to_va)(bin, methoddef->rva);
111  sym.paddr = PE_(bin_pe_rva_to_paddr)(bin, methoddef->rva);
112 
113  if (!(methoddef->implflags & 0x01) && methoddef->rva) { // not native
114  if (bin_pe_dotnet_read_method_header(bin->clr, bin->b, &sym) < 0) {
115  return UT64_MAX;
116  }
117  }
118 
119  return sym.vaddr;
120 }
int bin_pe_dotnet_read_method_header(Pe_image_clr *clr, RzBuffer *b, RzBinSymbol *sym)
Definition: dotnet.c:745
PE_DWord PE_() bin_pe_rva_to_va(RzBinPEObj *bin, PE_DWord rva)
Definition: pe.c:28
#define UT64_MAX
Definition: rz_types_base.h:86

References bin_pe_dotnet_read_method_header(), bin_pe_rva_to_paddr(), bin_pe_rva_to_va(), rz_bin_symbol_t::paddr, PE_, UT64_MAX, and rz_bin_symbol_t::vaddr.

◆ rz_bin_pe_get_clr_symbols()

RZ_OWN RzList* PE_() rz_bin_pe_get_clr_symbols ( RzBinPEObj bin)

Definition at line 8 of file pe_clr.c.

8  {
9  if (!bin || !bin->clr || !bin->clr->methoddefs) {
10  return NULL;
11  }
12  RzList /* RzBinSymbol */ *methods = rz_list_newf((RzListFree)rz_bin_symbol_free);
13  if (!methods) {
14  return NULL;
15  }
16 
17  // Namespace and classes
18 
19  // Each typedef contains a methodlist field which indexes into
20  // the MethodDef table and marks the start of methods
21  // belonging to that type
22 
23  // In order to determine the end of the methods of that type,
24  // we mark the start of the next run with `type_methods_end`
25  RzListIter *type_it = rz_list_iterator(bin->clr->typedefs);
26 
27  char *type_name = NULL;
28  char *type_namespace = NULL;
29 
30  ut32 type_methods_start = rz_pvector_len(bin->clr->methoddefs) + 1;
31  ut32 type_methods_end = type_methods_start;
32 
33  if (type_it) {
34  Pe_image_metadata_typedef *typedef_ = type_it->data;
35  type_name = rz_buf_get_string(bin->clr->strings, typedef_->name);
36  type_namespace = rz_buf_get_string(bin->clr->strings, typedef_->namespace);
37 
38  type_methods_start = ((Pe_image_metadata_typedef *)type_it->data)->methodlist;
39  type_methods_end = rz_pvector_len(bin->clr->methoddefs) + 1;
40 
41  type_it = type_it->n;
42  if (type_it) {
43  type_methods_end = ((Pe_image_metadata_typedef *)type_it->data)->methodlist;
44  }
45  }
46 
47  int i = 1;
48  void **it;
49  rz_pvector_foreach (bin->clr->methoddefs, it) {
50  Pe_image_metadata_methoddef *methoddef = *it;
51 
52  if ((type_name || type_namespace) && i >= type_methods_start && i >= type_methods_end) {
53  // Update class and namespace
54  free(type_name);
55  free(type_namespace);
56 
57  Pe_image_metadata_typedef *typedef_ = type_it->data;
58  type_name = rz_buf_get_string(bin->clr->strings, typedef_->name);
59  type_namespace = rz_buf_get_string(bin->clr->strings, typedef_->namespace);
60 
61  // Update next end
62  type_it = type_it->n;
63  if (type_it) {
64  type_methods_end = ((Pe_image_metadata_typedef *)type_it->data)->methodlist;
65  } else {
66  type_methods_end = rz_pvector_len(bin->clr->methoddefs) + 1;
67  }
68  }
69 
70  RzBinSymbol *sym;
71  if (!(sym = RZ_NEW0(RzBinSymbol))) {
72  break;
73  }
74  char *name = rz_buf_get_string(bin->clr->strings, methoddef->name);
75  sym->name = rz_str_newf("%s%s%s::%s",
76  type_namespace ? type_namespace : "",
77  type_namespace && type_namespace[0] != '\x00' ? "::" : "", // separator
78  type_name ? type_name : "",
79  name ? name : "");
80  free(name);
81 
83  sym->vaddr = PE_(bin_pe_rva_to_va)(bin, methoddef->rva);
84  sym->paddr = PE_(bin_pe_rva_to_paddr)(bin, methoddef->rva);
85 
86  if (!(methoddef->implflags & 0x01) && methoddef->rva) { // not native
87  if (bin_pe_dotnet_read_method_header(bin->clr, bin->b, sym) < 0) {
88  free(sym);
89  break;
90  }
91  }
92 
93  rz_list_append(methods, sym);
94  i++;
95  }
96 
97  // Cleanup class / namespace strings
98  free(type_name);
99  free(type_namespace);
100 
101  return methods;
102 }
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
Definition: bin.c:175
RZ_API RZ_BORROW RzListIter * rz_list_iterator(const RzList *list)
returns the first RzList iterator int the list
Definition: list.c:51
#define RZ_BIN_TYPE_FUNC_STR
Definition: rz_bin.h:119
RZ_API RZ_OWN char * rz_buf_get_string(RZ_NONNULL RzBuffer *b, ut64 addr)
Get a string from the buffer.
Definition: buf.c:628
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
const char * type
Definition: rz_bin.h:682
char * name
Definition: rz_bin.h:675
struct rz_list_iter_t * n
Definition: rz_list.h:15
void * data
Definition: rz_list.h:14

References bin_pe_dotnet_read_method_header(), bin_pe_rva_to_paddr(), bin_pe_rva_to_va(), rz_list_iter_t::data, free(), i, Pe_image_metadata_methoddef::implflags, rz_list_iter_t::n, Pe_image_metadata_methoddef::name, Pe_image_metadata_typedef::name, rz_bin_symbol_t::name, NULL, rz_bin_symbol_t::paddr, PE_, Pe_image_metadata_methoddef::rva, rz_bin_symbol_free(), RZ_BIN_TYPE_FUNC_STR, rz_buf_get_string(), rz_list_append(), rz_list_iterator(), rz_list_newf(), RZ_NEW0, rz_pvector_foreach, rz_pvector_len(), rz_str_newf(), rz_bin_symbol_t::type, and rz_bin_symbol_t::vaddr.

◆ rz_bin_pe_get_debug_data()

int PE_() rz_bin_pe_get_debug_data ( RzBinPEObj bin,
SDebugInfo res 
)

Definition at line 158 of file pe_debug.c.

158  {
159  PE_(image_debug_directory_entry)
160  img_dbg_dir_entry = { 0 };
161  PE_(image_data_directory) *dbg_dir = NULL;
162  PE_DWord dbg_dir_offset;
163  ut8 *dbg_data = 0;
164  int result = 0;
165  if (!bin) {
166  return 0;
167  }
168  dbg_dir = &bin->nt_headers->optional_header.DataDirectory[6 /*IMAGE_DIRECTORY_ENTRY_DEBUG*/];
169  dbg_dir_offset = PE_(bin_pe_rva_to_paddr)(bin, dbg_dir->VirtualAddress);
170  if ((int)dbg_dir_offset < 0 || dbg_dir_offset >= bin->size) {
171  return false;
172  }
173  if (dbg_dir_offset >= rz_buf_size(bin->b)) {
174  return false;
175  }
176  read_image_debug_directory_entry(bin->b, dbg_dir_offset, &img_dbg_dir_entry);
177  if ((rz_buf_size(bin->b) - dbg_dir_offset) < sizeof(PE_(image_debug_directory_entry))) {
178  return false;
179  }
180  ut32 dbg_data_poff = RZ_MIN(img_dbg_dir_entry.PointerToRawData, rz_buf_size(bin->b));
181  int dbg_data_len = RZ_MIN(img_dbg_dir_entry.SizeOfData, rz_buf_size(bin->b) - dbg_data_poff);
182  if (dbg_data_len < 1) {
183  return false;
184  }
185  dbg_data = (ut8 *)calloc(1, dbg_data_len + 1);
186  if (dbg_data) {
187  rz_buf_read_at(bin->b, dbg_data_poff, dbg_data, dbg_data_len);
188  result = get_debug_info(bin, &img_dbg_dir_entry, dbg_data, dbg_data_len, res);
189  RZ_FREE(dbg_data);
190  }
191  return result;
192 }
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static int get_debug_info(RzBinPEObj *bin, PE_(image_debug_directory_entry) *dbg_dir_entry, ut8 *dbg_data, int dbg_data_len, SDebugInfo *res)
Definition: pe_debug.c:71
static int read_image_debug_directory_entry(RzBuffer *b, ut64 addr, PE_(image_debug_directory_entry) *entry)
Definition: pe_debug.c:139

References bin_pe_rva_to_paddr(), calloc(), get_debug_info(), NULL, PE_, PE_DWord, read_image_debug_directory_entry(), rz_buf_read_at(), rz_buf_size(), RZ_FREE, and RZ_MIN.

◆ rz_bin_pe_get_entrypoint()

struct rz_bin_pe_addr_t* PE_() rz_bin_pe_get_entrypoint ( RzBinPEObj bin)

Definition at line 509 of file pe_info.c.

509  {
510  struct rz_bin_pe_addr_t *entry = NULL;
511  static bool debug = false;
512  int i;
513  ut64 base_addr = PE_(rz_bin_pe_get_image_base)(bin);
514  if (!bin || !bin->optional_header) {
515  return NULL;
516  }
517  if (!(entry = malloc(sizeof(struct rz_bin_pe_addr_t)))) {
518  rz_sys_perror("malloc (entrypoint)");
519  return NULL;
520  }
521  PE_DWord pe_entry = bin->optional_header->AddressOfEntryPoint;
522  entry->vaddr = PE_(bin_pe_rva_to_va)(bin, pe_entry);
523  entry->paddr = PE_(bin_pe_rva_to_paddr)(bin, pe_entry);
524  // haddr is the address of AddressOfEntryPoint in header.
525  entry->haddr = bin->dos_header->e_lfanew + 4 + sizeof(PE_(image_file_header)) + 16;
526 
527  if (entry->paddr >= bin->size) {
528  struct rz_bin_pe_section_t *sections = bin->sections;
529  ut64 paddr = 0;
530  if (!debug) {
531  RZ_LOG_INFO("Invalid entrypoint ... "
532  "trying to fix it but i do not promise nothing\n");
533  }
534  for (i = 0; i < bin->num_sections; i++) {
536  entry->paddr = sections[i].paddr;
537  entry->vaddr = sections[i].vaddr + base_addr;
538  paddr = 1;
539  break;
540  }
541  }
542  if (!paddr) {
543  ut64 min_off = -1;
544  for (i = 0; i < bin->num_sections; i++) {
545  // get the lowest section's paddr
546  if (sections[i].paddr < min_off) {
547  entry->paddr = sections[i].paddr;
548  entry->vaddr = sections[i].vaddr + base_addr;
549  min_off = sections[i].paddr;
550  }
551  }
552  if (min_off == -1) {
553  // no section just a hack to try to fix entrypoint
554  // maybe doesn't work always
555  int sa = RZ_MAX(bin->optional_header->SectionAlignment, 0x1000);
556  entry->paddr = pe_entry & ((sa << 1) - 1);
557  entry->vaddr = entry->paddr + base_addr;
558  }
559  }
560  }
561  if (!entry->paddr) {
562  if (!debug) {
563  RZ_LOG_INFO("NULL entrypoint\n");
564  }
565  struct rz_bin_pe_section_t *sections = bin->sections;
566  for (i = 0; i < bin->num_sections; i++) {
567  // If there is a section with x without w perm is a good candidate to be the entrypoint
569  entry->paddr = sections[i].paddr;
570  entry->vaddr = sections[i].vaddr + base_addr;
571  break;
572  }
573  }
574  }
575 
576  if (is_arm(bin) && entry->vaddr & 1) {
577  entry->vaddr--;
578  if (entry->paddr & 1) {
579  entry->paddr--;
580  }
581  }
582  if (!debug) {
583  debug = true;
584  }
585  return entry;
586 }
ut64 PE_() rz_bin_pe_get_image_base(RzBinPEObj *bin)
Definition: pe_info.c:588
#define RZ_MAX(x, y)
static int debug
Definition: visual.c:21

References bin_pe_rva_to_paddr(), bin_pe_rva_to_va(), debug, i, is_arm(), malloc(), NULL, rz_bin_pe_section_t::paddr, PE_, PE_DWord, PE_IMAGE_SCN_MEM_EXECUTE, PE_IMAGE_SCN_MEM_WRITE, rz_bin_pe_section_t::perm, rz_bin_pe_get_image_base(), RZ_LOG_INFO, RZ_MAX, rz_sys_perror, sections(), and ut64().

Referenced by check_mingw(), check_msvcseh(), check_unknow(), rz_bin_mdmp_pe_get_entrypoint(), and rz_bin_pe_check_sections().

◆ rz_bin_pe_get_exports()

struct rz_bin_pe_export_t* PE_() rz_bin_pe_get_exports ( RzBinPEObj bin)

Definition at line 162 of file pe_exports.c.

162  {
164  struct rz_bin_pe_export_t *exp, *exports = NULL;
165  PE_Word function_ordinal = 0;
166  PE_VWord functions_paddr, names_paddr, ordinals_paddr, function_rva, name_vaddr, name_paddr;
167  char function_name[PE_NAME_LENGTH + 1], forwarder_name[PE_NAME_LENGTH + 1];
168  char dll_name[PE_NAME_LENGTH + 1];
169  PE_(image_data_directory) * data_dir_export;
170  PE_VWord export_dir_rva;
171  int n, i, export_dir_size;
172  st64 exports_sz = 0;
173 
174  if (!bin->data_directory) {
175  return NULL;
176  }
177  data_dir_export = &bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_EXPORT];
178  export_dir_rva = data_dir_export->VirtualAddress;
179  export_dir_size = data_dir_export->Size;
180  PE_VWord *func_rvas = NULL;
181  PE_Word *ordinals = NULL;
182  if (bin->export_directory) {
183  if (bin->export_directory->NumberOfFunctions + 1 <
184  bin->export_directory->NumberOfFunctions) {
185  // avoid integer overflow
186  return NULL;
187  }
188  exports_sz = (bin->export_directory->NumberOfFunctions + 1) * sizeof(struct rz_bin_pe_export_t);
189  // we cant exit with export_sz > bin->size, us rz_bin_pe_export_t is 256+256+8+8+8+4 bytes is easy get over file size
190  // to avoid fuzzing we can abort on export_directory->NumberOfFunctions>0xffff
191  if (exports_sz < 0 || bin->export_directory->NumberOfFunctions + 1 > 0xffff) {
192  return NULL;
193  }
194  if (!(exports = malloc(exports_sz))) {
195  return NULL;
196  }
197  if (rz_buf_read_at(bin->b, PE_(bin_pe_rva_to_paddr)(bin, bin->export_directory->Name), (ut8 *)dll_name, PE_NAME_LENGTH) < 1) {
198  // we dont stop if dll name cant be read, we set dllname to null and continue
199  RZ_LOG_INFO("read (dll name)\n");
200  dll_name[0] = '\0';
201  }
202  functions_paddr = PE_(bin_pe_rva_to_paddr)(bin, bin->export_directory->AddressOfFunctions);
203  names_paddr = PE_(bin_pe_rva_to_paddr)(bin, bin->export_directory->AddressOfNames);
204  ordinals_paddr = PE_(bin_pe_rva_to_paddr)(bin, bin->export_directory->AddressOfOrdinals);
205 
206  const size_t names_sz = bin->export_directory->NumberOfNames * sizeof(PE_Word);
207  const size_t funcs_sz = bin->export_directory->NumberOfFunctions * sizeof(PE_VWord);
208  ordinals = malloc(names_sz);
209  func_rvas = malloc(funcs_sz);
210  if (!ordinals || !func_rvas) {
211  goto beach;
212  }
213  int r = rz_buf_read_at(bin->b, ordinals_paddr, (ut8 *)ordinals, names_sz);
214  if (r != names_sz) {
215  goto beach;
216  }
217  r = rz_buf_read_at(bin->b, functions_paddr, (ut8 *)func_rvas, funcs_sz);
218  if (r != funcs_sz) {
219  goto beach;
220  }
221  for (i = 0; i < bin->export_directory->NumberOfFunctions; i++) {
222  // get vaddr from AddressOfFunctions array
223  function_rva = rz_read_at_ble32((ut8 *)func_rvas, i * sizeof(PE_VWord), bin->endian);
224  // have exports by name?
225  if (bin->export_directory->NumberOfNames > 0) {
226  // search for value of i into AddressOfOrdinals
227  name_vaddr = 0;
228  for (n = 0; n < bin->export_directory->NumberOfNames; n++) {
229  PE_Word fo = rz_read_at_ble16((ut8 *)ordinals, n * sizeof(PE_Word), bin->endian);
230  // if exist this index into AddressOfOrdinals
231  if (i == fo) {
232  function_ordinal = fo;
233  // get the VA of export name from AddressOfNames
234  if (!rz_buf_read_le32_at(bin->b, names_paddr + n * sizeof(PE_VWord), &name_vaddr)) {
235  goto beach;
236  }
237  break;
238  }
239  }
240  // have an address into name_vaddr?
241  if (name_vaddr) {
242  // get the name of the Export
243  name_paddr = PE_(bin_pe_rva_to_paddr)(bin, name_vaddr);
244  if (rz_buf_read_at(bin->b, name_paddr, (ut8 *)function_name, PE_NAME_LENGTH) < 1) {
245  RZ_LOG_INFO("read (function name)\n");
246  exports[i].last = 1;
247  return exports;
248  }
249  } else { // No name export, get the ordinal
250  function_ordinal = i;
251  snprintf(function_name, PE_NAME_LENGTH, "Ordinal_%i", i + bin->export_directory->Base);
252  }
253  } else { // if export by name dont exist, get the ordinal taking in mind the Base value.
254  snprintf(function_name, PE_NAME_LENGTH, "Ordinal_%i", i + bin->export_directory->Base);
255  }
256  // check if VA are into export directory, this mean a forwarder export
257  if (function_rva >= export_dir_rva && function_rva < (export_dir_rva + export_dir_size)) {
258  // if forwarder, the VA point to Forwarded name
259  if (rz_buf_read_at(bin->b, PE_(bin_pe_rva_to_paddr)(bin, function_rva), (ut8 *)forwarder_name, PE_NAME_LENGTH) < 1) {
260  exports[i].last = 1;
261  return exports;
262  }
263  } else { // no forwarder export
264  snprintf(forwarder_name, PE_NAME_LENGTH, "NONE");
265  }
266  dll_name[PE_NAME_LENGTH] = '\0';
267  function_name[PE_NAME_LENGTH] = '\0';
268  exports[i].vaddr = PE_(bin_pe_rva_to_va)(bin, function_rva);
269  exports[i].paddr = PE_(bin_pe_rva_to_paddr)(bin, function_rva);
270  exports[i].ordinal = function_ordinal + bin->export_directory->Base;
271  memcpy(exports[i].forwarder, forwarder_name, PE_NAME_LENGTH);
272  exports[i].forwarder[PE_NAME_LENGTH] = '\0';
273  memcpy(exports[i].name, function_name, PE_NAME_LENGTH);
274  exports[i].name[PE_NAME_LENGTH] = '\0';
275  memcpy(exports[i].libname, dll_name, PE_NAME_LENGTH);
276  exports[i].libname[PE_NAME_LENGTH] = '\0';
277  exports[i].last = 0;
278  }
279  exports[i].last = 1;
280  free(ordinals);
281  free(func_rvas);
282  }
283  exp = parse_symbol_table(bin, exports, exports_sz - sizeof(struct rz_bin_pe_export_t));
284  if (exp) {
285  exports = exp;
286  }
287  return exports;
288 beach:
289  free(exports);
290  free(ordinals);
291  free(func_rvas);
292  return NULL;
293 }
#define r
Definition: crypto_rc6.c:12
snprintf
Definition: kernel.h:364
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static struct rz_bin_pe_export_t * parse_symbol_table(RzBinPEObj *bin, struct rz_bin_pe_export_t *exports, int sz)
Definition: pe_exports.c:17
#define PE_NAME_LENGTH
Definition: pe_specs.h:36
#define PE_Word
Definition: pe_specs.h:26
#define PE_VWord
Definition: pe_specs.h:28
static ut16 rz_read_at_ble16(const void *src, size_t offset, bool big_endian)
Definition: rz_endian.h:505
static ut32 rz_read_at_ble32(const void *src, size_t offset, bool big_endian)
Definition: rz_endian.h:509
ut8 forwarder[PE_NAME_LENGTH+1]
Definition: pe.h:87
ut8 name[PE_NAME_LENGTH+1]
Definition: pe.h:85
ut64 vaddr
Definition: pe.h:88
ut8 libname[PE_NAME_LENGTH+1]
Definition: pe.h:86
ut64 paddr
Definition: pe.h:89
ut64 ordinal
Definition: pe.h:90

References bin_pe_rva_to_paddr(), bin_pe_rva_to_va(), rz_bin_pe_export_t::forwarder, free(), i, rz_bin_pe_export_t::last, rz_bin_pe_export_t::libname, malloc(), memcpy(), n, rz_bin_pe_export_t::name, NULL, rz_bin_pe_export_t::ordinal, rz_bin_pe_export_t::paddr, parse_symbol_table(), PE_, PE_IMAGE_DIRECTORY_ENTRY_EXPORT, PE_NAME_LENGTH, PE_VWord, PE_Word, r, rz_buf_read_at(), rz_buf_read_le32_at, RZ_LOG_INFO, rz_read_at_ble16(), rz_read_at_ble32(), rz_return_val_if_fail, snprintf, st64, and rz_bin_pe_export_t::vaddr.

Referenced by rz_bin_mdmp_pe_get_symbols().

◆ rz_bin_pe_get_image_base()

ut64 PE_() rz_bin_pe_get_image_base ( RzBinPEObj bin)

Definition at line 588 of file pe_info.c.

588  {
589  ut64 imageBase = 0;
590  if (!bin || !bin->nt_headers) {
591  return 0LL;
592  }
593  imageBase = bin->nt_headers->optional_header.ImageBase;
594  if (!imageBase) {
595  // this should only happens with messed up binaries
596  // XXX this value should be user defined by bin.baddr
597  // but from here we can not access config API
598  imageBase = 0x10000;
599  }
600  return imageBase;
601 }

References ut64().

Referenced by bin_pe_rva_to_va(), bin_pe_va_to_rva(), rz_bin_pe_check_sections(), rz_bin_pe_get_entrypoint(), and rz_bin_pe_get_imports().

◆ rz_bin_pe_get_image_size()

int PE_() rz_bin_pe_get_image_size ( RzBinPEObj bin)

Definition at line 505 of file pe_info.c.

505  {
506  return bin->nt_headers->optional_header.SizeOfImage;
507 }

◆ rz_bin_pe_get_imports()

struct rz_bin_pe_import_t* PE_() rz_bin_pe_get_imports ( RzBinPEObj bin)

Definition at line 198 of file pe_imports.c.

198  {
199  struct rz_bin_pe_import_t *imps, *imports = NULL;
200  char dll_name[PE_NAME_LENGTH + 1];
201  int nimp = 0;
202  ut64 off; // used to cache value
203  PE_DWord dll_name_offset = 0;
204  PE_DWord paddr = 0;
205  PE_DWord import_func_name_offset;
206  PE_(image_import_directory)
207  curr_import_dir;
208  PE_(image_delay_import_directory)
209  curr_delay_import_dir;
210 
211  if (!bin) {
212  return NULL;
213  }
214  if (bin->import_directory_offset >= bin->size) {
215  return NULL;
216  }
217  if (bin->import_directory_offset + 20 > bin->size) {
218  return NULL;
219  }
220 
221  off = bin->import_directory_offset;
222  if (off < bin->size && off > 0) {
223  ut64 last;
224  int idi = 0;
225  if (off + sizeof(PE_(image_import_directory)) > bin->size) {
226  return NULL;
227  }
228  int r = PE_(read_image_import_directory)(bin->b, bin->import_directory_offset + idi * sizeof(curr_import_dir), &curr_import_dir);
229  if (r < 0) {
230  return NULL;
231  }
232 
233  if (bin->import_directory_size < 1) {
234  return NULL;
235  }
236  if (off + bin->import_directory_size > bin->size) {
237  // why chopping instead of returning and cleaning?
238  RZ_LOG_INFO("read (import directory too big)\n");
239  bin->import_directory_size = bin->size - bin->import_directory_offset;
240  }
241  last = bin->import_directory_offset + bin->import_directory_size;
242  while (r == sizeof(curr_import_dir) && bin->import_directory_offset + (idi + 1) * sizeof(curr_import_dir) <= last && (curr_import_dir.FirstThunk != 0 || curr_import_dir.Name != 0 || curr_import_dir.TimeDateStamp != 0 || curr_import_dir.Characteristics != 0 || curr_import_dir.ForwarderChain != 0)) {
243  int rr;
244  dll_name_offset = curr_import_dir.Name;
245  paddr = PE_(bin_pe_rva_to_paddr)(bin, dll_name_offset);
246  if (paddr > bin->size) {
247  goto beach;
248  }
249  if (paddr + PE_NAME_LENGTH > bin->size) {
250  rr = rz_buf_read_at(bin->b, paddr, (ut8 *)dll_name, bin->size - paddr);
251  if (rr != bin->size - paddr) {
252  goto beach;
253  }
254  dll_name[bin->size - paddr] = '\0';
255  } else {
256  rr = rz_buf_read_at(bin->b, paddr, (ut8 *)dll_name, PE_NAME_LENGTH);
257  if (rr != PE_NAME_LENGTH) {
258  goto beach;
259  }
260  dll_name[PE_NAME_LENGTH] = '\0';
261  }
262  if (!bin_pe_parse_imports(bin, &imports, &nimp, dll_name,
263  curr_import_dir.Characteristics,
264  curr_import_dir.FirstThunk)) {
265  break;
266  }
267  idi++;
268  r = PE_(read_image_import_directory)(bin->b, bin->import_directory_offset + idi * sizeof(curr_import_dir), &curr_import_dir);
269  if (r < 0) {
270  free(imports);
271  return NULL;
272  }
273  }
274  }
275  off = bin->delay_import_directory_offset;
276  if (off < bin->size && off > 0) {
277  if (off + sizeof(PE_(image_delay_import_directory)) > bin->size) {
278  goto beach;
279  }
280  int didi;
281  for (didi = 0;; didi++) {
282  int r = PE_(read_image_delay_import_directory)(bin->b, off + didi * sizeof(curr_delay_import_dir),
283  &curr_delay_import_dir);
284  if (r != sizeof(curr_delay_import_dir)) {
285  goto beach;
286  }
287  if ((curr_delay_import_dir.Name == 0) || (curr_delay_import_dir.DelayImportAddressTable == 0)) {
288  break;
289  }
290  if (!curr_delay_import_dir.Attributes) {
291  dll_name_offset = PE_(bin_pe_rva_to_paddr)(bin, curr_delay_import_dir.Name - PE_(rz_bin_pe_get_image_base)(bin));
292  import_func_name_offset = curr_delay_import_dir.DelayImportNameTable - PE_(rz_bin_pe_get_image_base)(bin);
293  } else {
294  dll_name_offset = PE_(bin_pe_rva_to_paddr)(bin, curr_delay_import_dir.Name);
295  import_func_name_offset = curr_delay_import_dir.DelayImportNameTable;
296  }
297  if (dll_name_offset > bin->size || dll_name_offset + PE_NAME_LENGTH > bin->size) {
298  goto beach;
299  }
300  int rr = rz_buf_read_at(bin->b, dll_name_offset, (ut8 *)dll_name, PE_NAME_LENGTH);
301  if (rr < 5) {
302  goto beach;
303  }
304  dll_name[PE_NAME_LENGTH] = '\0';
305  if (!bin_pe_parse_imports(bin, &imports, &nimp, dll_name, import_func_name_offset,
306  curr_delay_import_dir.DelayImportAddressTable)) {
307  break;
308  }
309  }
310  }
311 beach:
312  if (nimp) {
313  imps = realloc(imports, (nimp + 1) * sizeof(struct rz_bin_pe_import_t));
314  if (!imps) {
315  rz_sys_perror("realloc (import)");
316  free(imports);
317  return NULL;
318  }
319  imports = imps;
320  imports[nimp].last = 1;
321  }
322  return imports;
323 }
RzList * imports(RzBinFile *bf)
Definition: bin_ne.c:106
static int bin_pe_parse_imports(RzBinPEObj *bin, struct rz_bin_pe_import_t **importp, int *nimp, const char *dll_name, PE_DWord OriginalFirstThunk, PE_DWord FirstThunk)
Definition: pe_imports.c:54
ut64 paddr
Definition: pe.h:78

References bin_pe_parse_imports(), bin_pe_rva_to_paddr(), free(), imports(), rz_bin_pe_import_t::last, NULL, off, rz_bin_pe_import_t::paddr, PE_, PE_DWord, PE_NAME_LENGTH, r, read_image_delay_import_directory(), read_image_import_directory(), realloc(), rz_bin_pe_get_image_base(), rz_buf_read_at(), RZ_LOG_INFO, rz_sys_perror, and ut64().

Referenced by rz_bin_mdmp_pe_get_imports(), and rz_bin_mdmp_pe_get_symbols().

◆ rz_bin_pe_get_libs()

struct rz_bin_pe_lib_t* PE_() rz_bin_pe_get_libs ( RzBinPEObj bin)

Definition at line 384 of file pe_info.c.

384  {
385  if (!bin) {
386  return NULL;
387  }
388  struct rz_bin_pe_lib_t *libs = NULL;
389  struct rz_bin_pe_lib_t *new_libs = NULL;
390  PE_(image_import_directory)
391  curr_import_dir;
392  PE_(image_delay_import_directory)
393  curr_delay_import_dir;
394  PE_DWord name_off = 0;
395  HtPP *lib_map = NULL;
396  ut64 off; // cache value
397  int index = 0;
398  int len = 0;
399  int max_libs = 20;
400  libs = calloc(max_libs + 1, sizeof(struct rz_bin_pe_lib_t));
401  if (!libs) {
402  rz_sys_perror("malloc (libs)");
403  return NULL;
404  }
405 
406  if (bin->import_directory_offset + bin->import_directory_size > bin->size) {
407  RZ_LOG_INFO("import directory offset bigger than file\n");
408  goto out_error;
409  }
410  lib_map = sdb_ht_new();
411  off = bin->import_directory_offset;
412  if (off < bin->size && off > 0) {
413  ut64 last;
414  int iidi = 0;
415  // normal imports
416  if (off + sizeof(PE_(image_import_directory)) > bin->size) {
417  goto out_error;
418  }
419  int r = PE_(read_image_import_directory)(bin->b, off + iidi * sizeof(curr_import_dir),
420  &curr_import_dir);
421  last = off + bin->import_directory_size;
422  while (r == sizeof(curr_import_dir) && off + (iidi + 1) * sizeof(curr_import_dir) <= last && (curr_import_dir.FirstThunk || curr_import_dir.Name || curr_import_dir.TimeDateStamp || curr_import_dir.Characteristics || curr_import_dir.ForwarderChain)) {
423  name_off = PE_(bin_pe_rva_to_paddr)(bin, curr_import_dir.Name);
424  len = rz_buf_read_at(bin->b, name_off, (ut8 *)libs[index].name, PE_STRING_LENGTH);
425  if (!libs[index].name[0]) { // minimum string length
426  goto next;
427  }
428  if (len < 2 || libs[index].name[0] == 0) { // minimum string length
429  RZ_LOG_INFO("read (libs - import dirs) %d\n", len);
430  break;
431  }
432  libs[index].name[len - 1] = '\0';
433  rz_str_case(libs[index].name, 0);
434  if (!sdb_ht_find(lib_map, libs[index].name, NULL)) {
435  sdb_ht_insert(lib_map, libs[index].name, "a");
436  libs[index++].last = 0;
437  if (index >= max_libs) {
438  new_libs = realloc(libs, (max_libs * 2) * sizeof(struct rz_bin_pe_lib_t));
439  if (!new_libs) {
440  rz_sys_perror("realloc (libs)");
441  goto out_error;
442  }
443  libs = new_libs;
444  new_libs = NULL;
445  max_libs *= 2;
446  }
447  }
448  next:
449  iidi++;
450  r = PE_(read_image_import_directory)(bin->b, off + iidi * sizeof(curr_import_dir),
451  &curr_import_dir);
452  }
453  }
454  off = bin->delay_import_directory_offset;
455  if (off < bin->size && off > 0) {
456  ut64 did = 0;
457  if (off + sizeof(PE_(image_delay_import_directory)) > bin->size) {
458  goto out_error;
459  }
460  int r = PE_(read_image_delay_import_directory)(bin->b, off, &curr_delay_import_dir);
461  if (r != sizeof(curr_delay_import_dir)) {
462  goto out_error;
463  }
464  while (r == sizeof(curr_delay_import_dir) &&
465  curr_delay_import_dir.Name != 0 && curr_delay_import_dir.DelayImportNameTable != 0) {
466  name_off = PE_(bin_pe_rva_to_paddr)(bin, curr_delay_import_dir.Name);
467  if (name_off > bin->size || name_off + PE_STRING_LENGTH > bin->size) {
468  goto out_error;
469  }
470  len = rz_buf_read_at(bin->b, name_off, (ut8 *)libs[index].name, PE_STRING_LENGTH);
471  if (len != PE_STRING_LENGTH) {
472  RZ_LOG_INFO("read (libs - delay import dirs)\n");
473  break;
474  }
475  libs[index].name[len - 1] = '\0';
476  rz_str_case(libs[index].name, 0);
477  if (!sdb_ht_find(lib_map, libs[index].name, NULL)) {
478  sdb_ht_insert(lib_map, libs[index].name, "a");
479  libs[index++].last = 0;
480  if (index >= max_libs) {
481  new_libs = realloc(libs, (max_libs * 2) * sizeof(struct rz_bin_pe_lib_t));
482  if (!new_libs) {
483  rz_sys_perror("realloc (libs)");
484  goto out_error;
485  }
486  libs = new_libs;
487  new_libs = NULL;
488  max_libs *= 2;
489  }
490  }
491  did++;
492  r = PE_(read_image_delay_import_directory)(bin->b, off + did * sizeof(curr_delay_import_dir),
493  &curr_delay_import_dir);
494  }
495  }
496  sdb_ht_free(lib_map);
497  libs[index].last = 1;
498  return libs;
499 out_error:
500  sdb_ht_free(lib_map);
501  free(libs);
502  return NULL;
503 }
static RzList * libs(RzBinFile *bf)
Definition: bin_coff.c:379
int PE_() read_image_delay_import_directory(RzBuffer *b, ut64 addr, PE_(image_delay_import_directory) *directory)
Definition: pe_imports.c:24
int PE_() read_image_import_directory(RzBuffer *b, ut64 addr, PE_(image_import_directory) *import_dir)
Definition: pe_imports.c:8
#define PE_STRING_LENGTH
Definition: pe_specs.h:37
RZ_API void rz_str_case(char *str, bool up)
Definition: str.c:341
RZ_API char * sdb_ht_find(HtPP *ht, const char *key, bool *found)
Definition: sdbht.c:59
RZ_API HtPP * sdb_ht_new(void)
Definition: sdbht.c:11
RZ_API void sdb_ht_free(HtPP *ht)
Definition: sdbht.c:63
RZ_API bool sdb_ht_insert(HtPP *ht, const char *key, const char *value)
Definition: sdbht.c:43
int last
Definition: pe.h:105

References bin_pe_rva_to_paddr(), calloc(), free(), rz_bin_pe_lib_t::last, len, libs(), NULL, off, PE_, PE_DWord, PE_STRING_LENGTH, r, read_image_delay_import_directory(), read_image_import_directory(), realloc(), rz_buf_read_at(), RZ_LOG_INFO, rz_str_case(), rz_sys_perror, sdb_ht_find(), sdb_ht_free(), sdb_ht_insert(), sdb_ht_new(), and ut64().

◆ rz_bin_pe_get_machine()

char* PE_() rz_bin_pe_get_machine ( RzBinPEObj bin)

Definition at line 24 of file pe_info.c.

24  {
25  char *machine = NULL;
26 
27  if (bin && bin->nt_headers) {
28  switch (bin->nt_headers->file_header.Machine) {
29  case PE_IMAGE_FILE_MACHINE_ALPHA: machine = "Alpha"; break;
30  case PE_IMAGE_FILE_MACHINE_ALPHA64: machine = "Alpha 64"; break;
31  case PE_IMAGE_FILE_MACHINE_AM33: machine = "AM33"; break;
32  case PE_IMAGE_FILE_MACHINE_AMD64: machine = "AMD 64"; break;
33  case PE_IMAGE_FILE_MACHINE_ARM: machine = "ARM"; break;
34  case PE_IMAGE_FILE_MACHINE_ARMNT: machine = "ARM Thumb-2"; break;
35  case PE_IMAGE_FILE_MACHINE_ARM64: machine = "ARM64"; break;
36  case PE_IMAGE_FILE_MACHINE_CEE: machine = "CEE"; break;
37  case PE_IMAGE_FILE_MACHINE_CEF: machine = "CEF"; break;
38  case PE_IMAGE_FILE_MACHINE_EBC: machine = "EBC"; break;
39  case PE_IMAGE_FILE_MACHINE_I386: machine = "i386"; break;
40  case PE_IMAGE_FILE_MACHINE_IA64: machine = "ia64"; break;
41  case PE_IMAGE_FILE_MACHINE_M32R: machine = "M32R"; break;
42  case PE_IMAGE_FILE_MACHINE_M68K: machine = "M68K"; break;
43  case PE_IMAGE_FILE_MACHINE_MIPS16: machine = "Mips 16"; break;
44  case PE_IMAGE_FILE_MACHINE_MIPSFPU: machine = "Mips FPU"; break;
45  case PE_IMAGE_FILE_MACHINE_MIPSFPU16: machine = "Mips FPU 16"; break;
46  case PE_IMAGE_FILE_MACHINE_POWERPC: machine = "PowerPC"; break;
47  case PE_IMAGE_FILE_MACHINE_POWERPCFP: machine = "PowerPC FP"; break;
48  case PE_IMAGE_FILE_MACHINE_R10000: machine = "R10000"; break;
49  case PE_IMAGE_FILE_MACHINE_R3000: machine = "R3000"; break;
50  case PE_IMAGE_FILE_MACHINE_R4000: machine = "R4000"; break;
51  case PE_IMAGE_FILE_MACHINE_SH3: machine = "SH3"; break;
52  case PE_IMAGE_FILE_MACHINE_SH3DSP: machine = "SH3DSP"; break;
53  case PE_IMAGE_FILE_MACHINE_SH3E: machine = "SH3E"; break;
54  case PE_IMAGE_FILE_MACHINE_SH4: machine = "SH4"; break;
55  case PE_IMAGE_FILE_MACHINE_SH5: machine = "SH5"; break;
56  case PE_IMAGE_FILE_MACHINE_THUMB: machine = "Thumb"; break;
57  case PE_IMAGE_FILE_MACHINE_TRICORE: machine = "Tricore"; break;
58  case PE_IMAGE_FILE_MACHINE_WCEMIPSV2: machine = "WCE Mips V2"; break;
59  case PE_IMAGE_FILE_MACHINE_RISCV32: machine = "RISC-V 32-bit"; break;
60  case PE_IMAGE_FILE_MACHINE_RISCV64: machine = "RISC-V 64-bit"; break;
61  case PE_IMAGE_FILE_MACHINE_RISCV128: machine = "RISC-V 128-bit"; break;
62  default: machine = "unknown";
63  }
64  }
65  return machine ? strdup(machine) : NULL;
66 }
#define PE_IMAGE_FILE_MACHINE_CEE
Definition: pe_specs.h:73
#define PE_IMAGE_FILE_MACHINE_SH5
Definition: pe_specs.h:92
#define PE_IMAGE_FILE_MACHINE_IA64
Definition: pe_specs.h:77
#define PE_IMAGE_FILE_MACHINE_R10000
Definition: pe_specs.h:85
#define PE_IMAGE_FILE_MACHINE_SH3E
Definition: pe_specs.h:90
#define PE_IMAGE_FILE_MACHINE_SH4
Definition: pe_specs.h:91
#define PE_IMAGE_FILE_MACHINE_CEF
Definition: pe_specs.h:74
#define PE_IMAGE_FILE_MACHINE_R4000
Definition: pe_specs.h:87
#define PE_IMAGE_FILE_MACHINE_AM33
Definition: pe_specs.h:67
#define PE_IMAGE_FILE_MACHINE_AMD64
Definition: pe_specs.h:68
#define PE_IMAGE_FILE_MACHINE_TRICORE
Definition: pe_specs.h:94
#define PE_IMAGE_FILE_MACHINE_R3000
Definition: pe_specs.h:86
#define PE_IMAGE_FILE_MACHINE_SH3
Definition: pe_specs.h:88
#define PE_IMAGE_FILE_MACHINE_M32R
Definition: pe_specs.h:78
#define PE_IMAGE_FILE_MACHINE_SH3DSP
Definition: pe_specs.h:89
#define PE_IMAGE_FILE_MACHINE_I386
Definition: pe_specs.h:76

References NULL, PE_IMAGE_FILE_MACHINE_ALPHA, PE_IMAGE_FILE_MACHINE_ALPHA64, PE_IMAGE_FILE_MACHINE_AM33, PE_IMAGE_FILE_MACHINE_AMD64, PE_IMAGE_FILE_MACHINE_ARM, PE_IMAGE_FILE_MACHINE_ARM64, PE_IMAGE_FILE_MACHINE_ARMNT, PE_IMAGE_FILE_MACHINE_CEE, PE_IMAGE_FILE_MACHINE_CEF, PE_IMAGE_FILE_MACHINE_EBC, PE_IMAGE_FILE_MACHINE_I386, PE_IMAGE_FILE_MACHINE_IA64, PE_IMAGE_FILE_MACHINE_M32R, PE_IMAGE_FILE_MACHINE_M68K, PE_IMAGE_FILE_MACHINE_MIPS16, PE_IMAGE_FILE_MACHINE_MIPSFPU, PE_IMAGE_FILE_MACHINE_MIPSFPU16, PE_IMAGE_FILE_MACHINE_POWERPC, PE_IMAGE_FILE_MACHINE_POWERPCFP, PE_IMAGE_FILE_MACHINE_R10000, PE_IMAGE_FILE_MACHINE_R3000, PE_IMAGE_FILE_MACHINE_R4000, PE_IMAGE_FILE_MACHINE_RISCV128, PE_IMAGE_FILE_MACHINE_RISCV32, PE_IMAGE_FILE_MACHINE_RISCV64, PE_IMAGE_FILE_MACHINE_SH3, PE_IMAGE_FILE_MACHINE_SH3DSP, PE_IMAGE_FILE_MACHINE_SH3E, PE_IMAGE_FILE_MACHINE_SH4, PE_IMAGE_FILE_MACHINE_SH5, PE_IMAGE_FILE_MACHINE_THUMB, PE_IMAGE_FILE_MACHINE_TRICORE, PE_IMAGE_FILE_MACHINE_WCEMIPSV2, and strdup().

◆ rz_bin_pe_get_main_vaddr()

struct rz_bin_pe_addr_t* PE_() rz_bin_pe_get_main_vaddr ( RzBinPEObj bin)

Definition at line 917 of file pe_info.c.

917  {
918  struct rz_bin_pe_addr_t *winmain = PE_(check_msvcseh)(bin);
919  if (!winmain) {
920  winmain = PE_(check_mingw)(bin);
921  if (!winmain) {
922  winmain = PE_(check_unknow)(bin);
923  }
924  }
925  return winmain;
926 }
struct rz_bin_pe_addr_t *PE_() check_unknow(RzBinPEObj *bin)
Definition: pe_info.c:879
struct rz_bin_pe_addr_t *PE_() check_msvcseh(RzBinPEObj *bin)
Definition: pe_info.c:623
struct rz_bin_pe_addr_t *PE_() check_mingw(RzBinPEObj *bin)
Definition: pe_info.c:822

References check_mingw(), check_msvcseh(), check_unknow(), and PE_.

◆ rz_bin_pe_get_os()

char* PE_() rz_bin_pe_get_os ( RzBinPEObj bin)

Definition at line 69 of file pe_info.c.

69  {
70  char *os;
71  if (!bin || !bin->nt_headers) {
72  return NULL;
73  }
74  switch (bin->nt_headers->optional_header.Subsystem) {
76  os = strdup("native");
77  break;
81  os = strdup("windows");
82  break;
84  os = strdup("posix");
85  break;
90  os = strdup("efi");
91  break;
93  os = strdup("xbox");
94  break;
95  default:
96  // XXX: this is unknown
97  os = strdup("windows");
98  }
99  return os;
100 }
#define PE_IMAGE_SUBSYSTEM_EFI_ROM
Definition: pe_specs.h:169
#define PE_IMAGE_SUBSYSTEM_POSIX_CUI
Definition: pe_specs.h:164
#define PE_IMAGE_SUBSYSTEM_XBOX
Definition: pe_specs.h:170
#define PE_IMAGE_SUBSYSTEM_NATIVE
Definition: pe_specs.h:161
#define PE_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
Definition: pe_specs.h:167
#define PE_IMAGE_SUBSYSTEM_EFI_APPLICATION
Definition: pe_specs.h:166
#define PE_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
Definition: pe_specs.h:168
#define PE_IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: pe_specs.h:163
#define PE_IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: pe_specs.h:162
#define PE_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
Definition: pe_specs.h:165

References NULL, PE_IMAGE_SUBSYSTEM_EFI_APPLICATION, PE_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, PE_IMAGE_SUBSYSTEM_EFI_ROM, PE_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, PE_IMAGE_SUBSYSTEM_NATIVE, PE_IMAGE_SUBSYSTEM_POSIX_CUI, PE_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, PE_IMAGE_SUBSYSTEM_WINDOWS_CUI, PE_IMAGE_SUBSYSTEM_WINDOWS_GUI, PE_IMAGE_SUBSYSTEM_XBOX, and strdup().

◆ rz_bin_pe_get_sections()

struct rz_bin_pe_section_t* PE_() rz_bin_pe_get_sections ( RzBinPEObj bin)

Definition at line 243 of file pe_section.c.

243  {
245  PE_(image_section_header) * shdr;
246  int i, j, section_count = 0;
247 
248  if (!bin || !bin->nt_headers) {
249  return NULL;
250  }
251  shdr = bin->section_header;
252  for (i = 0; i < bin->num_sections; i++) {
253  // just allocate the needed
254  if (shdr[i].SizeOfRawData || shdr[i].Misc.VirtualSize) {
255  section_count++;
256  }
257  }
258  sections = calloc(section_count + 1, sizeof(struct rz_bin_pe_section_t));
259  if (!sections) {
260  rz_sys_perror("malloc (sections)");
261  return NULL;
262  }
263  for (i = 0, j = 0; i < bin->num_sections; i++) {
264  if (!shdr[i].SizeOfRawData && !shdr[i].Misc.VirtualSize) {
265  continue;
266  }
267  if (shdr[i].Name[0] == '\0') {
268  char *new_name = rz_str_newf("sect_%d", j);
269  strncpy((char *)sections[j].name, new_name, RZ_ARRAY_SIZE(sections[j].name) - 1);
270  free(new_name);
271  } else if (shdr[i].Name[0] == '/') {
272  // long name is something deprecated but still used
273  int idx = atoi((const char *)shdr[i].Name + 1);
274  ut64 sym_tbl_off = bin->nt_headers->file_header.PointerToSymbolTable;
275  int num_symbols = bin->nt_headers->file_header.NumberOfSymbols;
276  st64 off = num_symbols * COFF_SYMBOL_SIZE;
277  if (off > 0 && sym_tbl_off &&
278  sym_tbl_off + off + idx < bin->size &&
279  sym_tbl_off + off + idx > off) {
280  int sz = PE_IMAGE_SIZEOF_SHORT_NAME * 3;
281  char *buf[64] = { 0 };
282  if (rz_buf_read_at(bin->b,
283  sym_tbl_off + off + idx,
284  (ut8 *)buf, 64)) {
285  memcpy(sections[j].name, buf, sz);
286  sections[j].name[sz - 1] = '\0';
287  }
288  }
289  } else {
291  sections[j].name[PE_IMAGE_SIZEOF_SHORT_NAME] = '\0';
292  }
293  sections[j].vaddr = shdr[i].VirtualAddress;
294  sections[j].size = shdr[i].SizeOfRawData;
295  if (shdr[i].Misc.VirtualSize) {
296  sections[j].vsize = shdr[i].Misc.VirtualSize;
297  } else {
298  sections[j].vsize = shdr[i].SizeOfRawData;
299  }
300  sections[j].paddr = shdr[i].PointerToRawData;
301  sections[j].flags = shdr[i].Characteristics;
302  if (bin->optional_header) {
303  ut32 sa = bin->optional_header->SectionAlignment;
304  if (sa) {
305  ut64 diff = sections[j].vsize % sa;
306  if (diff) {
307  sections[j].vsize += sa - diff;
308  }
309  if (sections[j].vaddr % sa) {
310  RZ_LOG_INFO("section %s not aligned to SectionAlignment.\n",
311  sections[j].name);
312  }
313  }
314  const ut32 fa = bin->optional_header->FileAlignment;
315  if (fa) {
316  const ut64 diff = sections[j].paddr % fa;
317  if (diff) {
318  RZ_LOG_INFO("section %s not aligned to FileAlignment.\n", sections[j].name);
319  sections[j].paddr -= diff;
320  sections[j].size += diff;
321  }
322  }
323  }
324  sections[j].perm = shdr[i].Characteristics;
325  sections[j].last = 0;
326  j++;
327  }
328  sections[j].last = 1;
329  bin->num_sections = section_count;
330  return sections;
331 }
int idx
Definition: setup.py:197
#define COFF_SYMBOL_SIZE
Definition: pe.h:176
#define PE_IMAGE_SIZEOF_SHORT_NAME
Definition: pe_specs.h:352
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
ut64 vaddr
Definition: pe.h:67

References calloc(), COFF_SYMBOL_SIZE, free(), i, setup::idx, memcpy(), NULL, off, PE_, PE_IMAGE_SIZEOF_SHORT_NAME, RZ_ARRAY_SIZE, rz_buf_read_at(), RZ_LOG_INFO, rz_str_newf(), rz_sys_perror, sections(), st64, ut64(), and rz_bin_pe_section_t::vaddr.

Referenced by bin_pe_init().

◆ rz_bin_pe_get_subsystem()

char* PE_() rz_bin_pe_get_subsystem ( RzBinPEObj bin)

Definition at line 159 of file pe_info.c.

159  {
160  char *subsystem = NULL;
161  if (bin && bin->nt_headers) {
162  switch (bin->nt_headers->optional_header.Subsystem) {
164  subsystem = "Native";
165  break;
167  subsystem = "Windows GUI";
168  break;
170  subsystem = "Windows CUI";
171  break;
173  subsystem = "POSIX CUI";
174  break;
176  subsystem = "Windows CE GUI";
177  break;
179  subsystem = "EFI Application";
180  break;
182  subsystem = "EFI Boot Service Driver";
183  break;
185  subsystem = "EFI Runtime Driver";
186  break;
188  subsystem = "EFI ROM";
189  break;
191  subsystem = "XBOX";
192  break;
193  default:
194  subsystem = "Unknown";
195  break;
196  }
197  }
198  return subsystem ? strdup(subsystem) : NULL;
199 }

References NULL, PE_IMAGE_SUBSYSTEM_EFI_APPLICATION, PE_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, PE_IMAGE_SUBSYSTEM_EFI_ROM, PE_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, PE_IMAGE_SUBSYSTEM_NATIVE, PE_IMAGE_SUBSYSTEM_POSIX_CUI, PE_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, PE_IMAGE_SUBSYSTEM_WINDOWS_CUI, PE_IMAGE_SUBSYSTEM_WINDOWS_GUI, PE_IMAGE_SUBSYSTEM_XBOX, and strdup().

◆ rz_bin_pe_is_big_endian()

int PE_() rz_bin_pe_is_big_endian ( RzBinPEObj bin)

Definition at line 343 of file pe_info.c.

343  {
344  ut16 arch;
345  if (!bin || !bin->nt_headers) {
346  return false;
347  }
348  arch = bin->nt_headers->file_header.Machine;
351  return false;
352  }
354 }
#define HASCHR(x)
Definition: pe_info.c:322
#define PE_IMAGE_FILE_BYTES_REVERSED_HI
Definition: pe_specs.h:115

References arch, HASCHR, PE_IMAGE_FILE_BYTES_REVERSED_HI, PE_IMAGE_FILE_MACHINE_AMD64, and PE_IMAGE_FILE_MACHINE_I386.

Referenced by bin_pe_init().

◆ rz_bin_pe_is_dll()

int PE_() rz_bin_pe_is_dll ( RzBinPEObj bin)

Definition at line 324 of file pe_info.c.

324  {
325  if (!bin || !bin->nt_headers) {
326  return false;
327  }
328  return HASCHR(PE_IMAGE_FILE_DLL);
329 }
#define PE_IMAGE_FILE_DLL
Definition: pe_specs.h:113

References HASCHR, and PE_IMAGE_FILE_DLL.

◆ rz_bin_pe_is_stripped_debug()

int PE_() rz_bin_pe_is_stripped_debug ( RzBinPEObj bin)

Definition at line 377 of file pe_info.c.

377  {
378  if (!bin || !bin->nt_headers) {
379  return false;
380  }
382 }
#define PE_IMAGE_FILE_DEBUG_STRIPPED
Definition: pe_specs.h:109

References HASCHR, and PE_IMAGE_FILE_DEBUG_STRIPPED.

◆ rz_bin_pe_is_stripped_line_nums()

int PE_() rz_bin_pe_is_stripped_line_nums ( RzBinPEObj bin)

Definition at line 363 of file pe_info.c.

363  {
364  if (!bin || !bin->nt_headers) {
365  return false;
366  }
368 }
#define PE_IMAGE_FILE_LINE_NUMS_STRIPPED
Definition: pe_specs.h:102

References HASCHR, and PE_IMAGE_FILE_LINE_NUMS_STRIPPED.

◆ rz_bin_pe_is_stripped_local_syms()

int PE_() rz_bin_pe_is_stripped_local_syms ( RzBinPEObj bin)

Definition at line 370 of file pe_info.c.

370  {
371  if (!bin || !bin->nt_headers) {
372  return false;
373  }
375 }
#define PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED
Definition: pe_specs.h:103

References HASCHR, and PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED.

◆ rz_bin_pe_is_stripped_relocs()

int PE_() rz_bin_pe_is_stripped_relocs ( RzBinPEObj bin)

Definition at line 356 of file pe_info.c.

356  {
357  if (!bin || !bin->nt_headers) {
358  return false;
359  }
361 }
#define PE_IMAGE_FILE_RELOCS_STRIPPED
Definition: pe_specs.h:100

References HASCHR, and PE_IMAGE_FILE_RELOCS_STRIPPED.

◆ rz_bin_pe_new()

RzBinPEObj* PE_() rz_bin_pe_new ( const char *  file,
bool  verbose 
)

◆ rz_bin_pe_new_buf()

RzBinPEObj* PE_() rz_bin_pe_new_buf ( RzBuffer buf,
bool  verbose 
)

Definition at line 116 of file pe.c.

116  {
118  if (!bin) {
119  return NULL;
120  }
121  bin->kv = sdb_new0();
122  bin->b = rz_buf_ref(buf);
123  bin->verbose = verbose;
124  bin->size = rz_buf_size(buf);
125  bin->hash = rz_hash_new();
126  if (!bin_pe_init(bin)) {
127  return PE_(rz_bin_pe_free)(bin);
128  }
129  return bin;
130 }
RZ_API RzHash * rz_hash_new(void)
Definition: hash.c:585
static int bin_pe_init(RzBinPEObj *bin)
Definition: pe.c:40
void *PE_() rz_bin_pe_free(RzBinPEObj *bin)
Definition: pe.c:88
#define RzBinPEObj
Definition: pe.h:126
RZ_API RzBuffer * rz_buf_ref(RzBuffer *b)
Increment the reference count of the buffer.
Definition: buf.c:668
RZ_API Sdb * sdb_new0(void)
Definition: sdb.c:43

References bin_pe_init(), NULL, PE_, rz_bin_pe_free(), rz_buf_ref(), rz_buf_size(), rz_hash_new(), RZ_NEW0, RzBinPEObj, sdb_new0(), and verbose.

Referenced by rz_bin_pemixed_from_bytes_new().

◆ section_flag_to_rzlist()

RzList* PE_() section_flag_to_rzlist ( ut64  flag)

Definition at line 2378 of file mach0.c.

2378  {
2379  RzList *flag_list = rz_list_new();
2380  if (flag & S_ATTR_PURE_INSTRUCTIONS) {
2381  rz_list_append(flag_list, "PURE_INSTRUCTIONS");
2382  }
2383  if (flag & S_ATTR_NO_TOC) {
2384  rz_list_append(flag_list, "NO_TOC");
2385  }
2386  if (flag & S_ATTR_SOME_INSTRUCTIONS) {
2387  rz_list_append(flag_list, "SOME_INSTRUCTIONS");
2388  }
2389  if (flag & S_ATTR_EXT_RELOC) {
2390  rz_list_append(flag_list, "EXT_RELOC");
2391  }
2392  if (flag & S_ATTR_SELF_MODIFYING_CODE) {
2393  rz_list_append(flag_list, "SELF_MODIFYING_CODE");
2394  }
2395  if (flag & S_ATTR_DEBUG) {
2396  rz_list_append(flag_list, "DEBUG");
2397  }
2398  if (flag & S_ATTR_LIVE_SUPPORT) {
2399  rz_list_append(flag_list, "LIVE_SUPPORT");
2400  }
2401  if (flag & S_ATTR_STRIP_STATIC_SYMS) {
2402  rz_list_append(flag_list, "STRIP_STATIC_SYMS");
2403  }
2404  if (flag & S_ATTR_NO_DEAD_STRIP) {
2405  rz_list_append(flag_list, "NO_DEAD_STRIP");
2406  }
2407  return flag_list;
2408 }
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
@ S_ATTR_SOME_INSTRUCTIONS
S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
@ S_ATTR_NO_TOC
@ S_ATTR_STRIP_STATIC_SYMS
@ S_ATTR_EXT_RELOC
S_ATTR_EXT_RELOC - Section has external relocation entries.
@ S_ATTR_DEBUG
S_ATTR_DEBUG - A debug section.
@ S_ATTR_LIVE_SUPPORT
S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
@ S_ATTR_NO_DEAD_STRIP
S_ATTR_NO_DEAD_STRIP - No dead stripping.
@ S_ATTR_PURE_INSTRUCTIONS
@ S_ATTR_SELF_MODIFYING_CODE

References IMAGE_SCN_ALIGN_1024BYTES, IMAGE_SCN_ALIGN_128BYTES, IMAGE_SCN_ALIGN_16BYTES, IMAGE_SCN_ALIGN_1BYTES, IMAGE_SCN_ALIGN_2048BYTES, IMAGE_SCN_ALIGN_256BYTES, IMAGE_SCN_ALIGN_2BYTES, IMAGE_SCN_ALIGN_32BYTES, IMAGE_SCN_ALIGN_4096BYTES, IMAGE_SCN_ALIGN_4BYTES, IMAGE_SCN_ALIGN_512BYTES, IMAGE_SCN_ALIGN_64BYTES, IMAGE_SCN_ALIGN_8192BYTES, IMAGE_SCN_ALIGN_8BYTES, IMAGE_SCN_CNT_CODE, IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_GPREL, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_NRELOC_OVFL, IMAGE_SCN_LNK_OTHER, IMAGE_SCN_LNK_REMOVE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_LOCKED, IMAGE_SCN_MEM_NOT_CACHED, IMAGE_SCN_MEM_NOT_PAGED, IMAGE_SCN_MEM_PRELOAD, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_TYPE_NO_PAD, PE_SCN_ALIGN_MASK, rz_list_append(), rz_list_new(), S_ATTR_DEBUG, S_ATTR_EXT_RELOC, S_ATTR_LIVE_SUPPORT, S_ATTR_NO_DEAD_STRIP, S_ATTR_NO_TOC, S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SELF_MODIFYING_CODE, S_ATTR_SOME_INSTRUCTIONS, and S_ATTR_STRIP_STATIC_SYMS.