Rizin
unix-like reverse engineering framework and cli tools
pe_info.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2008-2019 nibble <nibble.ds@gmail.com>
2 // SPDX-FileCopyrightText: 2008-2019 pancake <pancake@nopcode.org>
3 // SPDX-FileCopyrightText: 2008-2019 inisider <inisider@gmail.com>
4 // SPDX-License-Identifier: LGPL-3.0-only
5 
6 #include "pe.h"
7 
8 static inline int is_thumb(RzBinPEObj *bin) {
9  return bin->nt_headers->optional_header.AddressOfEntryPoint & 1;
10 }
11 
12 static inline int is_arm(RzBinPEObj *bin) {
13  switch (bin->nt_headers->file_header.Machine) {
18  return 1;
19  }
20  return 0;
21 }
22 
23 // TODO: make it const! like in elf
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 }
67 
68 // TODO: make it const! like in elf
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 }
101 
102 // TODO: make it const
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 }
113 
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 }
158 
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 }
200 
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 }
220 
222  if (!bin || !bin->optional_header) {
223  return 0;
224  }
225  return bin->optional_header->CheckSum;
226 }
227 
228 typedef struct {
231 } checksum_ctx;
232 
233 static ut64 buf_fwd_checksum(const ut8 *buf, ut64 size, void *user) {
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 }
248 
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 }
305 
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 }
321 
322 #define HASCHR(x) (bin->nt_headers->file_header.Characteristics & (x))
323 
325  if (!bin || !bin->nt_headers) {
326  return false;
327  }
328  return HASCHR(PE_IMAGE_FILE_DLL);
329 }
330 
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 }
342 
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 }
355 
357  if (!bin || !bin->nt_headers) {
358  return false;
359  }
361 }
362 
364  if (!bin || !bin->nt_headers) {
365  return false;
366  }
368 }
369 
371  if (!bin || !bin->nt_headers) {
372  return false;
373  }
375 }
376 
378  if (!bin || !bin->nt_headers) {
379  return false;
380  }
382 }
383 
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 }
504 
506  return bin->nt_headers->optional_header.SizeOfImage;
507 }
508 
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 }
587 
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 }
602 
603 static inline bool read_and_follow_jump(struct rz_bin_pe_addr_t *entry, RzBuffer *buf, ut8 *b, int len, bool big_endian) {
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 }
615 
616 static inline bool follow_offset(struct rz_bin_pe_addr_t *entry, RzBuffer *buf, ut8 *b, int len, bool big_endian, size_t instr_off) {
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 }
622 
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 }
821 
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 }
878 
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 }
916 
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 }
size_t len
Definition: 6502dis.c:15
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
static RzList * libs(RzBinFile *bf)
Definition: bin_coff.c:379
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
int bits(struct state *s, int need)
Definition: blast.c:72
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
cs_arch arch
Definition: cstool.c:13
uint16_t ut16
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
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")
int n
Definition: mipsasm.c:19
int off
Definition: pal.c:13
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
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 RzBinPEObj
Definition: pe.h:126
int PE_() rz_bin_pe_is_stripped_debug(RzBinPEObj *bin)
Definition: pe_info.c:377
#define HASCHR(x)
Definition: pe_info.c:322
struct rz_bin_pe_addr_t *PE_() check_unknow(RzBinPEObj *bin)
Definition: pe_info.c:879
int PE_() rz_bin_pe_get_image_size(RzBinPEObj *bin)
Definition: pe_info.c:505
int PE_() rz_bin_pe_is_pie(RzBinPEObj *bin)
Definition: pe_info.c:331
int PE_() rz_bin_pe_is_big_endian(RzBinPEObj *bin)
Definition: pe_info.c:343
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_main_vaddr(RzBinPEObj *bin)
Definition: pe_info.c:917
static ut64 buf_fwd_checksum(const ut8 *buf, ut64 size, void *user)
Definition: pe_info.c:233
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
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_entrypoint(RzBinPEObj *bin)
Definition: pe_info.c:509
int PE_() rz_bin_pe_is_stripped_local_syms(RzBinPEObj *bin)
Definition: pe_info.c:370
char *PE_() rz_bin_pe_get_subsystem(RzBinPEObj *bin)
Definition: pe_info.c:159
char *PE_() rz_bin_pe_get_machine(RzBinPEObj *bin)
Definition: pe_info.c:24
char *PE_() rz_bin_pe_get_arch(RzBinPEObj *bin)
Definition: pe_info.c:114
int PE_() bin_pe_get_claimed_checksum(RzBinPEObj *bin)
Definition: pe_info.c:221
static int is_thumb(RzBinPEObj *bin)
Definition: pe_info.c:8
struct rz_bin_pe_lib_t *PE_() rz_bin_pe_get_libs(RzBinPEObj *bin)
Definition: pe_info.c:384
int PE_() bin_pe_get_actual_checksum(RzBinPEObj *bin)
Definition: pe_info.c:249
ut64 PE_() rz_bin_pe_get_image_base(RzBinPEObj *bin)
Definition: pe_info.c:588
char *PE_() rz_bin_pe_get_cc(RzBinPEObj *bin)
Definition: pe_info.c:201
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
int PE_() rz_bin_pe_is_stripped_relocs(RzBinPEObj *bin)
Definition: pe_info.c:356
char *PE_() rz_bin_pe_get_os(RzBinPEObj *bin)
Definition: pe_info.c:69
char *PE_() rz_bin_pe_get_class(RzBinPEObj *bin)
Definition: pe_info.c:103
int PE_() rz_bin_pe_is_dll(RzBinPEObj *bin)
Definition: pe_info.c:324
struct rz_bin_pe_addr_t *PE_() check_msvcseh(RzBinPEObj *bin)
Definition: pe_info.c:623
static int is_arm(RzBinPEObj *bin)
Definition: pe_info.c:12
int PE_() rz_bin_pe_get_bits(RzBinPEObj *bin)
Definition: pe_info.c:306
int PE_() rz_bin_pe_is_stripped_line_nums(RzBinPEObj *bin)
Definition: pe_info.c:363
struct rz_bin_pe_addr_t *PE_() check_mingw(RzBinPEObj *bin)
Definition: pe_info.c:822
#define PE_IMAGE_FILE_DEBUG_STRIPPED
Definition: pe_specs.h:109
#define PE_(name)
Definition: pe_specs.h:23
#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_SUBSYSTEM_EFI_ROM
Definition: pe_specs.h:169
#define PE_IMAGE_FILE_MACHINE_IA64
Definition: pe_specs.h:77
#define PE_IMAGE_FILE_MACHINE_M68K
Definition: pe_specs.h:79
#define PE_STRING_LENGTH
Definition: pe_specs.h:37
#define PE_IMAGE_FILE_MACHINE_MIPSFPU16
Definition: pe_specs.h:82
#define PE_IMAGE_SCN_MEM_EXECUTE
Definition: pe_specs.h:355
#define PE_IMAGE_FILE_MACHINE_R10000
Definition: pe_specs.h:85
#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_SUBSYSTEM_POSIX_CUI
Definition: pe_specs.h:164
#define PE_IMAGE_FILE_MACHINE_ALPHA
Definition: pe_specs.h:65
#define PE_IMAGE_FILE_MACHINE_RISCV64
Definition: pe_specs.h:97
#define IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
Definition: pe_specs.h:118
#define PE_IMAGE_FILE_MACHINE_THUMB
Definition: pe_specs.h:93
#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_TYPE_PE32
Definition: pe_specs.h:61
#define PE_IMAGE_SUBSYSTEM_XBOX
Definition: pe_specs.h:170
#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_TYPE_PE32PLUS
Definition: pe_specs.h:62
#define PE_IMAGE_FILE_BYTES_REVERSED_HI
Definition: pe_specs.h:115
#define PE_IMAGE_SCN_MEM_WRITE
Definition: pe_specs.h:357
#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_SUBSYSTEM_NATIVE
Definition: pe_specs.h:161
#define PE_IMAGE_FILE_MACHINE_RISCV128
Definition: pe_specs.h:98
#define PE_IMAGE_FILE_LOCAL_SYMS_STRIPPED
Definition: pe_specs.h:103
#define PE_IMAGE_FILE_MACHINE_RISCV32
Definition: pe_specs.h:96
#define PE_IMAGE_FILE_MACHINE_TRICORE
Definition: pe_specs.h:94
#define PE_IMAGE_FILE_MACHINE_R3000
Definition: pe_specs.h:86
#define PE_DWord
Definition: pe_specs.h:27
#define PE_IMAGE_FILE_RELOCS_STRIPPED
Definition: pe_specs.h:100
#define PE_IMAGE_FILE_MACHINE_SH3
Definition: pe_specs.h:88
#define PE_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
Definition: pe_specs.h:167
#define PE_IMAGE_FILE_MACHINE_WCEMIPSV2
Definition: pe_specs.h:95
#define PE_IMAGE_FILE_LINE_NUMS_STRIPPED
Definition: pe_specs.h:102
#define PE_IMAGE_FILE_MACHINE_MIPS16
Definition: pe_specs.h:80
#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_FILE_DLL
Definition: pe_specs.h:113
#define PE_IMAGE_FILE_MACHINE_M32R
Definition: pe_specs.h:78
#define PE_IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: pe_specs.h:163
#define PE_IMAGE_FILE_MACHINE_SH3DSP
Definition: pe_specs.h:89
#define PE_IMAGE_FILE_MACHINE_I386
Definition: pe_specs.h:76
#define PE_IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: pe_specs.h:162
#define PE_IMAGE_FILE_MACHINE_MIPSFPU
Definition: pe_specs.h:81
#define PE_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
Definition: pe_specs.h:165
#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
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
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
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497
static ut32 rz_read_at_ble32(const void *src, size_t offset, bool big_endian)
Definition: rz_endian.h:509
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
RZ_API void rz_str_case(char *str, bool up)
Definition: str.c:341
#define rz_sys_perror(x)
Definition: rz_types.h:336
#define ZERO_FILL(x)
Definition: rz_types.h:281
#define PFMT64x
Definition: rz_types.h:393
#define RZ_MAX(x, y)
#define st32
Definition: rz_types_base.h:12
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
#define b(i)
Definition: sha256.c:42
Definition: malloc.c:26
bool big_endian
Definition: pe_info.c:230
ut64 * computed_cs
Definition: pe_info.c:229
Definition: zipcmp.c:77
Definition: z80asm.h:102
int last
Definition: pe.h:105
ut64 paddr
Definition: pe.h:68
static int debug
Definition: visual.c:21
ut64(WINAPI *w32_GetEnabledXStateFeatures)()