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

Go to the source code of this file.

Classes

struct  checksum_ctx
 

Macros

#define HASCHR(x)   (bin->nt_headers->file_header.Characteristics & (x))
 

Functions

static int is_thumb (RzBinPEObj *bin)
 
static int is_arm (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)
 
char *PE_() rz_bin_pe_get_arch (RzBinPEObj *bin)
 
char *PE_() rz_bin_pe_get_subsystem (RzBinPEObj *bin)
 
char *PE_() rz_bin_pe_get_cc (RzBinPEObj *bin)
 
int PE_() bin_pe_get_claimed_checksum (RzBinPEObj *bin)
 
static ut64 buf_fwd_checksum (const ut8 *buf, ut64 size, void *user)
 
int PE_() bin_pe_get_actual_checksum (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_get_bits (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_is_dll (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_is_pie (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)
 
struct rz_bin_pe_lib_t *PE_() rz_bin_pe_get_libs (RzBinPEObj *bin)
 
int PE_() rz_bin_pe_get_image_size (RzBinPEObj *bin)
 
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_entrypoint (RzBinPEObj *bin)
 
ut64 PE_() rz_bin_pe_get_image_base (RzBinPEObj *bin)
 
static bool read_and_follow_jump (struct rz_bin_pe_addr_t *entry, RzBuffer *buf, ut8 *b, int len, bool big_endian)
 
static bool follow_offset (struct rz_bin_pe_addr_t *entry, RzBuffer *buf, ut8 *b, int len, bool big_endian, size_t instr_off)
 
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_() check_unknow (RzBinPEObj *bin)
 
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_main_vaddr (RzBinPEObj *bin)
 

Macro Definition Documentation

◆ HASCHR

#define HASCHR (   x)    (bin->nt_headers->file_header.Characteristics & (x))

Definition at line 322 of file pe_info.c.

Function Documentation

◆ 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
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
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
#define PE_(name)
Definition: pe_specs.h:23
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
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
Definition: malloc.c:26
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_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 }

◆ buf_fwd_checksum()

static ut64 buf_fwd_checksum ( const ut8 buf,
ut64  size,
void *  user 
)
static

Definition at line 233 of file pe_info.c.

233  {
234  checksum_ctx *ctx = user;
235  ut64 computed_cs = *ctx->computed_cs;
236  ut64 i;
237  for (i = 0; i < size; i += 4) {
238  ut32 cur = rz_read_at_ble32(buf, i, ctx->big_endian);
239 
240  computed_cs = (computed_cs & 0xFFFFFFFF) + cur + (computed_cs >> 32);
241  if (computed_cs >> 32) {
242  computed_cs = (computed_cs & 0xFFFFFFFF) + (computed_cs >> 32);
243  }
244  }
245  *ctx->computed_cs = computed_cs;
246  return i;
247 }
voidpf void uLong size
Definition: ioapi.h:138
static ut32 rz_read_at_ble32(const void *src, size_t offset, bool big_endian)
Definition: rz_endian.h:509

References i, rz_read_at_ble32(), and ut64().

Referenced by bin_pe_get_actual_checksum().

◆ 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 }
#define NULL
Definition: cris-opc.c:27
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 RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define ZERO_FILL(x)
Definition: rz_types.h:281
#define PFMT64x
Definition: rz_types.h:393
#define b(i)
Definition: sha256.c:42
Definition: zipcmp.c:77

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().

◆ follow_offset()

static bool follow_offset ( struct rz_bin_pe_addr_t entry,
RzBuffer buf,
ut8 b,
int  len,
bool  big_endian,
size_t  instr_off 
)
inlinestatic

Definition at line 616 of file pe_info.c.

616  {
617  const st32 dst_offset = rz_read_ble32(b + instr_off + 1, big_endian) + instr_off + 5;
618  entry->paddr += dst_offset;
619  entry->vaddr += dst_offset;
620  return read_and_follow_jump(entry, buf, b, len, big_endian);
621 }
size_t len
Definition: 6502dis.c:15
#define st32
Definition: rz_types_base.h:12

References b, len, read_and_follow_jump(), rz_read_ble32(), and st32.

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

◆ is_arm()

static int is_arm ( RzBinPEObj bin)
inlinestatic

Definition at line 12 of file pe_info.c.

12  {
13  switch (bin->nt_headers->file_header.Machine) {
18  return 1;
19  }
20  return 0;
21 }
#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_THUMB
Definition: pe_specs.h:93
#define PE_IMAGE_FILE_MACHINE_ARM64
Definition: pe_specs.h:71

References PE_IMAGE_FILE_MACHINE_ARM, PE_IMAGE_FILE_MACHINE_ARM64, PE_IMAGE_FILE_MACHINE_ARMNT, and PE_IMAGE_FILE_MACHINE_THUMB.

Referenced by create(), run_basic_block_analysis(), rz_analysis_function_resize(), rz_analysis_vtable_begin(), rz_analysis_walkthrough_jmptbl(), rz_bin_pe_get_bits(), rz_bin_pe_get_cc(), rz_bin_pe_get_entrypoint(), and rz_core_bin_apply_symbols().

◆ is_thumb()

static int is_thumb ( RzBinPEObj bin)
inlinestatic

Definition at line 8 of file pe_info.c.

8  {
9  return bin->nt_headers->optional_header.AddressOfEntryPoint & 1;
10 }

Referenced by rz_bin_pe_get_bits(), and rz_bin_pe_get_cc().

◆ read_and_follow_jump()

static bool read_and_follow_jump ( struct rz_bin_pe_addr_t entry,
RzBuffer buf,
ut8 b,
int  len,
bool  big_endian 
)
inlinestatic

Definition at line 603 of file pe_info.c.

603  {
604  if (!rz_buf_read_at(buf, entry->paddr, b, len)) {
605  return false;
606  }
607  if (b[0] != 0xe9) {
608  return true;
609  }
610  const st32 jmp_dst = rz_read_ble32(b + 1, big_endian) + 5;
611  entry->paddr += jmp_dst;
612  entry->vaddr += jmp_dst;
613  return rz_buf_read_at(buf, entry->paddr, b, len) > 0;
614 }

References b, len, rz_buf_read_at(), rz_read_ble32(), and st32.

Referenced by check_msvcseh(), and follow_offset().

◆ 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
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")
#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_ALPHA
Definition: pe_specs.h:65
#define PE_IMAGE_FILE_MACHINE_RISCV64
Definition: pe_specs.h:97
#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_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 }
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
PE_DWord PE_() bin_pe_rva_to_paddr(RzBinPEObj *bin, PE_DWord rva)
Definition: pe.c:15
PE_DWord PE_() bin_pe_rva_to_va(RzBinPEObj *bin, PE_DWord rva)
Definition: pe.c:28
ut64 PE_() rz_bin_pe_get_image_base(RzBinPEObj *bin)
Definition: pe_info.c:588
#define PE_IMAGE_SCN_MEM_EXECUTE
Definition: pe_specs.h:355
#define PE_IMAGE_SCN_MEM_WRITE
Definition: pe_specs.h:357
#define PE_DWord
Definition: pe_specs.h:27
#define rz_sys_perror(x)
Definition: rz_types.h:336
#define RZ_MAX(x, y)
ut64 paddr
Definition: pe.h:68
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_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_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
#define r
Definition: crypto_rc6.c:12
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
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_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
Definition: z80asm.h:102
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_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 }
uint16_t ut16
#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_pie()

int PE_() rz_bin_pe_is_pie ( RzBinPEObj bin)

Definition at line 331 of file pe_info.c.

331  {
332  if (!bin || !bin->nt_headers) {
333  return false;
334  }
336 #if 0
337  BOOL aslr = inh->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
338 //TODO: implement dep?
339  BOOL dep = inh->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
340 #endif
341 }
#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
Definition: pe_specs.h:118

References HASCHR, and IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE.

◆ 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.