2 #include <featureTests.h>
3 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
4 #include "sage3basic.h"
6 #include <Rose/Diagnostics.h>
10 #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
17 printf(
"Error: operator<< not implemented! \n");
37 SgAsmNERelocEntry::iref_type::iref_type()
44 SgAsmNERelocEntry::iord_type::iord_type()
51 SgAsmNERelocEntry::iname_type::iname_type()
58 SgAsmNERelocEntry::osfixup_type::osfixup_type()
73 set_size(
sizeof(NEFileHeader_disk));
77 set_synthesized(
true);
78 set_purpose(SP_HEADER);
84 read_content_local(0, &fh,
sizeof fh);
87 if (fh.e_magic[0] !=
'N' || fh.e_magic[1] !=
'E')
88 throw FormatError(
"Bad NE magic number");
91 p_e_linker_major = ByteOrder::le_to_host(fh.e_linker_major);
92 p_e_linker_minor = ByteOrder::le_to_host(fh.e_linker_minor);
93 p_e_entrytab_rfo = ByteOrder::le_to_host(fh.e_entrytab_rfo);
94 p_e_entrytab_size = ByteOrder::le_to_host(fh.e_entrytab_size);
95 p_e_checksum = ByteOrder::le_to_host(fh.e_checksum);
96 p_e_flags1 = ByteOrder::le_to_host(fh.e_flags1);
97 p_e_autodata_sn = ByteOrder::le_to_host(fh.e_autodata_sn);
98 p_e_bss_size = ByteOrder::le_to_host(fh.e_bss_size);
99 p_e_stack_size = ByteOrder::le_to_host(fh.e_stack_size);
100 p_e_csip = ByteOrder::le_to_host(fh.e_csip);
101 p_e_sssp = ByteOrder::le_to_host(fh.e_sssp);
102 p_e_nsections = ByteOrder::le_to_host(fh.e_nsections);
103 p_e_nmodrefs = ByteOrder::le_to_host(fh.e_nmodrefs);
104 p_e_nnonresnames = ByteOrder::le_to_host(fh.e_nnonresnames);
105 p_e_sectab_rfo = ByteOrder::le_to_host(fh.e_sectab_rfo);
106 p_e_rsrctab_rfo = ByteOrder::le_to_host(fh.e_rsrctab_rfo);
107 p_e_resnametab_rfo = ByteOrder::le_to_host(fh.e_resnametab_rfo);
108 p_e_modreftab_rfo = ByteOrder::le_to_host(fh.e_modreftab_rfo);
109 p_e_importnametab_rfo = ByteOrder::le_to_host(fh.e_importnametab_rfo);
110 p_e_nonresnametab_offset = ByteOrder::le_to_host(fh.e_nonresnametab_offset);
111 p_e_nmovable_entries = ByteOrder::le_to_host(fh.e_nmovable_entries);
112 p_e_sector_align = ByteOrder::le_to_host(fh.e_sector_align);
113 p_e_nresources = ByteOrder::le_to_host(fh.e_nresources);
114 p_e_exetype = ByteOrder::le_to_host(fh.e_exetype);
115 p_e_flags2 = ByteOrder::le_to_host(fh.e_flags2);
116 p_e_fastload_sector = ByteOrder::le_to_host(fh.e_fastload_sector);
117 p_e_fastload_nsectors = ByteOrder::le_to_host(fh.e_fastload_nsectors);
118 p_e_res1 = ByteOrder::le_to_host(fh.e_res1);
119 p_e_winvers = ByteOrder::le_to_host(fh.e_winvers);
122 for (
size_t i = 0; i <
sizeof(fh.e_magic); ++i)
123 p_magic.push_back(fh.e_magic[i]);
126 p_exec_format->set_family(FAMILY_NE);
127 p_exec_format->set_purpose(p_e_flags1 & HF1_LIBRARY ? PURPOSE_LIBRARY : PURPOSE_EXECUTABLE);
128 p_exec_format->set_sex(ByteOrder::ORDER_LSB);
129 p_exec_format->set_abi(ABI_NT);
130 p_exec_format->set_abi_version(0);
131 p_exec_format->set_word_size(2);
132 ROSE_ASSERT(p_e_linker_major <= 0xff && p_e_linker_minor <= 0xff);
133 p_exec_format->set_version((p_e_linker_major<<8) | p_e_linker_minor);
134 p_exec_format->set_is_current_version(
true);
137 switch (p_e_exetype) {
139 set_isa(ISA_UNSPECIFIED);
142 throw FormatError(
"use of reserved value for Windows NE header e_exetype");
144 set_isa(ISA_IA32_386);
148 throw FormatError(
"use of reserved value for Windows NE header e_exetype");
166 bool was_tracking = file->get_tracking_references();
167 file->set_tracking_references(
false);
171 unsigned char dos_magic[2];
173 if (
'M'!=dos_magic[0] ||
'Z'!=dos_magic[1])
177 uint32_t lfanew_disk;
178 file->
read_content(0x3c, &lfanew_disk,
sizeof lfanew_disk);
179 rose_addr_t ne_offset = ByteOrder::le_to_host(lfanew_disk);
182 unsigned char ne_magic[2];
183 file->
read_content(ne_offset, ne_magic,
sizeof ne_magic);
184 if (
'N'!=ne_magic[0] ||
'E'!=ne_magic[1])
187 file->set_tracking_references(was_tracking);
191 file->set_tracking_references(was_tracking);
199 for (
size_t i = 0; i < NELMTS(disk->e_magic); i++)
200 disk->e_magic[i] = get_magic()[i];
201 ByteOrder::host_to_le(p_e_linker_major, &(disk->e_linker_major));
202 ByteOrder::host_to_le(p_e_linker_minor, &(disk->e_linker_minor));
203 ByteOrder::host_to_le(p_e_entrytab_rfo, &(disk->e_entrytab_rfo));
204 ByteOrder::host_to_le(p_e_entrytab_size, &(disk->e_entrytab_size));
205 ByteOrder::host_to_le(p_e_checksum, &(disk->e_checksum));
206 ByteOrder::host_to_le(p_e_flags1, &(disk->e_flags1));
207 ByteOrder::host_to_le(p_e_autodata_sn, &(disk->e_autodata_sn));
208 ByteOrder::host_to_le(p_e_bss_size, &(disk->e_bss_size));
209 ByteOrder::host_to_le(p_e_stack_size, &(disk->e_stack_size));
210 ByteOrder::host_to_le(p_e_csip, &(disk->e_csip));
211 ByteOrder::host_to_le(p_e_sssp, &(disk->e_sssp));
212 ByteOrder::host_to_le(p_e_nsections, &(disk->e_nsections));
213 ByteOrder::host_to_le(p_e_nmodrefs, &(disk->e_nmodrefs));
214 ByteOrder::host_to_le(p_e_nnonresnames, &(disk->e_nnonresnames));
215 ByteOrder::host_to_le(p_e_sectab_rfo, &(disk->e_sectab_rfo));
216 ByteOrder::host_to_le(p_e_rsrctab_rfo, &(disk->e_rsrctab_rfo));
217 ByteOrder::host_to_le(p_e_resnametab_rfo, &(disk->e_resnametab_rfo));
218 ByteOrder::host_to_le(p_e_modreftab_rfo, &(disk->e_modreftab_rfo));
219 ByteOrder::host_to_le(p_e_importnametab_rfo, &(disk->e_importnametab_rfo));
220 ByteOrder::host_to_le(p_e_nonresnametab_offset, &(disk->e_nonresnametab_offset));
221 ByteOrder::host_to_le(p_e_nmovable_entries, &(disk->e_nmovable_entries));
222 ByteOrder::host_to_le(p_e_sector_align, &(disk->e_sector_align));
223 ByteOrder::host_to_le(p_e_nresources, &(disk->e_nresources));
224 ByteOrder::host_to_le(p_e_exetype, &(disk->e_exetype));
225 ByteOrder::host_to_le(p_e_flags2, &(disk->e_flags2));
226 ByteOrder::host_to_le(p_e_fastload_sector, &(disk->e_fastload_sector));
227 ByteOrder::host_to_le(p_e_fastload_nsectors, &(disk->e_fastload_nsectors));
228 ByteOrder::host_to_le(p_e_res1, &(disk->e_res1));
229 ByteOrder::host_to_le(p_e_winvers, &(disk->e_winvers));
240 write(f, 0,
sizeof fh, &fh);
244 p_dos2_header->unparse(f);
248 p_section_table->unparse(f);
252 p_resname_table->unparse(f);
253 if (p_nonresname_table)
254 p_nonresname_table->unparse(f);
256 p_module_table->unparse(f);
258 p_entry_table->unparse(f);
267 sprintf(p,
"%sNEFileHeader[%zd].", prefix, idx);
269 sprintf(p,
"%sNEFileHeader.", prefix);
272 int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
275 fprintf(f,
"%s%-*s = %u\n", p, w,
"e_linker_major", p_e_linker_major);
276 fprintf(f,
"%s%-*s = %u\n", p, w,
"e_linker_minor", p_e_linker_minor);
277 fprintf(f,
"%s%-*s = %" PRIu64
" (%" PRIu64
" abs)\n", p, w,
"e_entrytab_rfo",
278 p_e_entrytab_rfo, p_e_entrytab_rfo+p_offset);
279 fprintf(f,
"%s%-*s = %" PRIu64
" bytes\n", p, w,
"e_entrytab_size", p_e_entrytab_size);
280 fprintf(f,
"%s%-*s = 0x%08x\n", p, w,
"e_checksum", p_e_checksum);
281 fprintf(f,
"%s%-*s = 0x%04x\n", p, w,
"e_flags1", p_e_flags1);
282 fprintf(f,
"%s%-*s = %u (1-origin)\n", p, w,
"e_autodata_sn", p_e_autodata_sn);
283 fprintf(f,
"%s%-*s = %u bytes\n", p, w,
"e_bss_size", p_e_bss_size);
284 fprintf(f,
"%s%-*s = %u bytes\n", p, w,
"e_stack_size", p_e_stack_size);
285 fprintf(f,
"%s%-*s = 0x%08x\n", p, w,
"e_csip", p_e_csip);
286 fprintf(f,
"%s%-*s = 0x%08x\n", p, w,
"e_sssp", p_e_sssp);
287 fprintf(f,
"%s%-*s = %u\n", p, w,
"e_nsections", p_e_nsections);
288 fprintf(f,
"%s%-*s = %u\n", p, w,
"e_nmodrefs", p_e_nmodrefs);
289 fprintf(f,
"%s%-*s = %u\n", p, w,
"e_nnonresnames", p_e_nnonresnames);
290 fprintf(f,
"%s%-*s = %" PRIu64
" (%" PRIu64
" abs)\n", p, w,
"e_sectab_rfo",
291 p_e_sectab_rfo, p_e_sectab_rfo+p_offset);
292 fprintf(f,
"%s%-*s = %" PRIu64
" (%" PRIu64
" abs)\n", p, w,
"e_rsrctab_rfo",
293 p_e_rsrctab_rfo, p_e_rsrctab_rfo+p_offset);
294 fprintf(f,
"%s%-*s = %" PRIu64
" (%" PRIu64
" abs)\n", p, w,
"e_resnametab_rfo",
295 p_e_resnametab_rfo, p_e_resnametab_rfo+p_offset);
296 fprintf(f,
"%s%-*s = %" PRIu64
" (%" PRIu64
" abs)\n", p, w,
"e_modreftab_rfo",
297 p_e_modreftab_rfo, p_e_modreftab_rfo+p_offset);
298 fprintf(f,
"%s%-*s = %" PRIu64
" (%" PRIu64
" abs)\n", p, w,
"e_importnametab_rfo",
299 p_e_importnametab_rfo, p_e_importnametab_rfo+p_offset);
300 fprintf(f,
"%s%-*s = %" PRIu64
" byte offset\n", p, w,
"e_nonresnametab_offset", p_e_nonresnametab_offset);
301 fprintf(f,
"%s%-*s = %u entries\n", p, w,
"e_nmovable_entries", p_e_nmovable_entries);
302 fprintf(f,
"%s%-*s = %u (log2)\n", p, w,
"e_sector_align", p_e_sector_align);
303 fprintf(f,
"%s%-*s = %u\n", p, w,
"e_nresources", p_e_nresources);
304 fprintf(f,
"%s%-*s = %u\n", p, w,
"e_exetype", p_e_exetype);
305 fprintf(f,
"%s%-*s = 0x%02x\n", p, w,
"e_flags2", p_e_flags2);
306 fprintf(f,
"%s%-*s = sector %" PRIu64
"\n", p, w,
"e_fastload_sector", p_e_fastload_sector);
307 fprintf(f,
"%s%-*s = %" PRIu64
" sectors\n", p, w,
"e_fastload_nsectors", p_e_fastload_nsectors);
308 fprintf(f,
"%s%-*s = 0x%04x\n", p, w,
"e_res1", p_e_res1);
309 fprintf(f,
"%s%-*s = 0x%04x\n", p, w,
"e_winvers", p_e_winvers);
312 fprintf(f,
"%s%-*s = [%d] \"%s\"\n", p, w,
"dos2_header",
313 p_dos2_header->get_id(), p_dos2_header->get_name()->get_string(
true).c_str());
315 fprintf(f,
"%s%-*s = none\n", p, w,
"dos2_header");
317 if (p_section_table) {
318 fprintf(f,
"%s%-*s = [%d] \"%s\"\n", p, w,
"section_table",
319 p_section_table->get_id(), p_section_table->get_name()->get_string(
true).c_str());
321 fprintf(f,
"%s%-*s = none\n", p, w,
"section_table");
323 if (p_resname_table) {
324 fprintf(f,
"%s%-*s = [%d] \"%s\"\n", p, w,
"resname_table",
325 p_resname_table->get_id(), p_resname_table->get_name()->get_string(
true).c_str());
327 fprintf(f,
"%s%-*s = none\n", p, w,
"resname_table");
329 if (p_nonresname_table) {
330 fprintf(f,
"%s%-*s = [%d] \"%s\"\n", p, w,
"nonresname_table",
331 p_nonresname_table->get_id(), p_nonresname_table->get_name()->get_string(
true).c_str());
333 fprintf(f,
"%s%-*s = none\n", p, w,
"nonresname_table");
335 if (p_module_table) {
336 fprintf(f,
"%s%-*s = [%d] \"%s\"\n", p, w,
"module_table",
337 p_module_table->get_id(), p_module_table->get_name()->get_string(
true).c_str());
339 fprintf(f,
"%s%-*s = none\n", p, w,
"module_table");
342 fprintf(f,
"%s%-*s = [%d] \"%s\"\n", p, w,
"entry_table",
343 p_entry_table->get_id(), p_entry_table->get_name()->get_string(
true).c_str());
345 fprintf(f,
"%s%-*s = none\n", p, w,
"entry_table");
354 SgAsmNESectionTableEntry::ctor(
const NESectionTableEntry_disk *disk)
356 p_sector = ByteOrder::le_to_host(disk->sector);
357 p_physical_size = ByteOrder::le_to_host(disk->physical_size);
358 if (0==p_physical_size && p_sector!=0) p_physical_size = 64*1024;
359 p_flags = ByteOrder::le_to_host(disk->flags);
360 p_virtual_size = ByteOrder::le_to_host(disk->virtual_size);
361 if (0==p_virtual_size) p_virtual_size = 64*1024;
366 SgAsmNESectionTableEntry::encode(NESectionTableEntry_disk *disk)
const
368 ByteOrder::host_to_le(p_sector, &(disk->sector));
369 unsigned x_physical_size = p_physical_size==64*1024 ? 0 : p_physical_size;
370 ByteOrder::host_to_le(x_physical_size, &(disk->physical_size));
371 ByteOrder::host_to_le(p_flags, &(disk->flags));
372 unsigned x_virtual_size = p_virtual_size==64*1024 ? 0 : p_virtual_size;
373 ByteOrder::host_to_le(x_virtual_size, &(disk->virtual_size));
379 SgAsmNESectionTableEntry::dump(FILE *f,
const char *prefix, ssize_t idx,
SgAsmNEFileHeader *fhdr)
const
383 sprintf(p,
"%sNESectionTableEntry[%zd].", prefix, idx);
385 sprintf(p,
"%sNESectionTableEntry.", prefix);
388 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
391 fprintf(f,
"%s%-*s = %u", p, w,
"sector", p_sector);
393 fprintf(f,
" (%" PRIu64
" byte offset)", (rose_addr_t) p_sector << fhdr->get_e_sector_align());
395 fprintf(f,
"%s%-*s = %" PRIu64
" bytes\n", p, w,
"physical_size", p_physical_size);
396 fprintf(f,
"%s%-*s = %" PRIu64
" bytes\n", p, w,
"virtual_size", p_virtual_size);
397 fprintf(f,
"%s%-*s = 0x%08x", p, w,
"flags", p_flags);
398 switch (p_flags & SF_TYPE_MASK) {
399 case SF_CODE: fputs(
" code", f);
break;
400 case SF_DATA: fputs(
" data", f);
break;
401 case SF_ALLOC: fputs(
" alloc", f);
break;
402 case SF_LOAD: fputs(
" load", f);
break;
403 default: fprintf(f,
" type=%u", p_flags & SF_TYPE_MASK);
break;
405 if (p_flags & SF_MOVABLE) fputs(
" movable", f);
406 if (p_flags & SF_PURE) fputs(
" pure", f);
407 if (p_flags & SF_PRELOAD) fputs(
" preload", f);
408 if (p_flags & SF_NOT_WRITABLE) fputs(
" const", f);
409 if (p_flags & SF_RELOCINFO) fputs(
" reloc", f);
410 if (p_flags & SF_DISCARDABLE) fputs(
" discardable", f);
411 if (p_flags & SF_DISCARD) fputs(
" discard", f);
412 if (p_flags & SF_RESERVED) fputs(
" *", f);
422 p_reloc_table->unparse(f);
431 sprintf(p,
"%sNESection[%zd].", prefix, idx);
433 sprintf(p,
"%sNESection.", prefix);
436 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
440 p_st_entry->
dump(f, p, -1, fhdr);
442 fprintf(f,
"%s%-*s = [%d] \"%s\"\n", p, w,
"reloc_table",
443 p_reloc_table->get_id(), p_reloc_table->get_name()->get_string(
true).c_str());
445 fprintf(f,
"%s%-*s = none\n", p, w,
"reloc_table");
451 SgAsmNESectionTable::ctor()
454 ROSE_ASSERT(fhdr!=NULL);
460 set_synthesized(
true);
462 set_purpose(SP_HEADER);
466 for (
size_t i = 0; i < fhdr->get_e_nsections(); i++) {
469 read_content_local(i*entsize, &disk, entsize);
473 rose_addr_t section_offset = entry->get_sector() << fhdr->get_e_sector_align();
476 section->
set_size(0==section_offset ? 0 : entry->get_physical_size());
481 section->set_st_entry(entry);
484 rose_addr_t mapped_rva = section_offset - fhdr->
get_offset();
489 unsigned section_type = entry->get_flags() & SgAsmNESectionTableEntry::SF_TYPE_MASK;
490 if (0 == section_offset) {
493 section->
set_mapped_wperm(entry->get_flags() & SgAsmNESectionTableEntry::SF_NOT_WRITABLE ?
false :
true);
495 }
else if (0 == section_type) {
498 section->
set_mapped_wperm(entry->get_flags() & SgAsmNESectionTableEntry::SF_NOT_WRITABLE ?
false :
true);
500 }
else if (section_type & SgAsmNESectionTableEntry::SF_DATA) {
503 section->
set_mapped_wperm(entry->get_flags() & (SgAsmNESectionTableEntry::SF_PRELOAD |
504 SgAsmNESectionTableEntry::SF_NOT_WRITABLE) ?
false :
true);
508 if (entry->get_flags() & SgAsmNESectionTableEntry::SF_RELOCINFO) {
510 section->set_reloc_table(relocs);
520 ROSE_ASSERT(fhdr!=NULL);
523 for (
size_t i=0; i<sections.size(); i++) {
524 if (sections[i]->get_id()>=0) {
528 ROSE_ASSERT(section->
get_id()>0);
529 size_t slot = section->
get_id()-1;
533 write(f, slot*
sizeof(disk),
sizeof disk, &disk);
537 if (section->get_reloc_table())
538 section->get_reloc_table()->
unparse(f);
549 sprintf(p,
"%sNESectionTable[%zd].", prefix, idx);
551 sprintf(p,
"%sNESectionTable.", prefix);
562 SgAsmNENameTable::ctor(rose_addr_t offset)
568 set_synthesized(
true);
570 set_purpose(SP_HEADER);
573 ROSE_ASSERT(fhdr!=NULL);
581 read_content_local(at++, &byte, 1);
582 size_t length = byte;
583 if (0==length)
break;
586 char *buf =
new char[length];
587 read_content_local(at, buf, length);
588 p_names.push_back(std::string(buf, length));
594 read_content_local(at, &u16_disk, 2);
595 p_ordinals.push_back(ByteOrder::le_to_host(u16_disk));
605 ROSE_ASSERT(p_names.size() == p_ordinals.size());
607 for (
size_t i = 0; i < p_names.size(); i++) {
609 ROSE_ASSERT(p_names[i].size() <= 0xff);
610 unsigned char len = p_names[i].size();
611 spos = write(f, spos, len);
614 spos = write(f, spos, p_names[i]);
617 ROSE_ASSERT(p_ordinals[i]<=0xffff);
619 ByteOrder::host_to_le(p_ordinals[i], &ordinal_le);
620 spos = write(f, spos,
sizeof ordinal_le, &ordinal_le);
624 write(f, spos,
'\0');
633 sprintf(p,
"%sNENameTable[%zd].", prefix, idx);
635 sprintf(p,
"%sNENameTable.", prefix);
638 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
641 ROSE_ASSERT(p_names.size() == p_ordinals.size());
642 for (
size_t i = 0; i < p_names.size(); i++) {
643 fprintf(f,
"%s%-*s = [%zd] \"%s\"\n", p, w,
"names", i, escapeString(p_names[i]).c_str());
644 fprintf(f,
"%s%-*s = [%zd] %u\n", p, w,
"ordinals", i, p_ordinals[i]);
649 std::vector<std::string>
650 SgAsmNENameTable::get_names_by_ordinal(
unsigned ordinal)
652 std::vector<std::string> retval;
653 for (
size_t i = 0; i < p_ordinals.size(); i++) {
654 if (p_ordinals[i] == ordinal) {
655 retval.push_back(p_names[i]);
667 SgAsmNEModuleTable::ctor(rose_addr_t offset, rose_addr_t size)
673 set_synthesized(
true);
675 set_purpose(SP_HEADER);
678 ROSE_ASSERT(fhdr!=NULL);
680 ROSE_ASSERT(NULL != p_strtab);
682 for (rose_addr_t at = 0; at < get_size(); at += 2) {
684 read_content_local(at, &u16_disk, 2);
685 rose_addr_t name_offset = ByteOrder::le_to_host(u16_disk);
686 p_name_offsets.push_back(name_offset);
687 p_names.push_back(p_strtab->get_string(name_offset));
691 for (
size_t i = 0; i < p_names.size(); i++) {
700 rose_addr_t spos = 0;
701 p_strtab->unparse(f);
703 for (
size_t i = 0; i < p_name_offsets.size(); i++) {
704 uint16_t name_offset_le;
705 ByteOrder::host_to_le(p_name_offsets[i], &name_offset_le);
706 spos = write(f, spos,
sizeof name_offset_le, &name_offset_le);
716 sprintf(p,
"%sNEModuleTable[%zd].", prefix, idx);
718 sprintf(p,
"%sNEModuleTable.", prefix);
721 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
726 fprintf(f,
"%s%-*s = [%d] \"%s\"\n", p, w,
"strtab",
727 p_strtab->get_id(), p_strtab->get_name()->get_string(
true).c_str());
729 fprintf(f,
"%s%-*s = none\n", p, w,
"strtab");
732 for (
size_t i = 0; i < p_names.size(); i++) {
733 fprintf(f,
"%s%-*s = [%" PRIuPTR
"] (offset %" PRIu64
", %" PRIuPTR
" bytes) \"%s\"\n",
734 p, w,
"name", i, p_name_offsets[i], p_names[i].size(), escapeString(p_names[i]).c_str());
745 SgAsmNEStringTable::ctor(rose_addr_t offset, rose_addr_t size)
751 set_synthesized(
true);
753 set_purpose(SP_HEADER);
760 SgAsmNEStringTable::get_string(rose_addr_t offset)
763 read_content_local(offset, &byte, 1);
764 size_t length = byte;
766 char *buf =
new char[length];
767 read_content_local(offset+1, buf, length);
768 std::string retval(buf, length);
779 sprintf(p,
"%sNEStringTable[%zd].", prefix, idx);
781 sprintf(p,
"%sNEStringTable.", prefix);
787 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
788 bool was_congealed = get_congealed();
791 for (
size_t i=0; at<get_size(); i++) {
792 std::string s = get_string(at);
794 sprintf(label,
"string-at-%" PRIu64, at);
795 fprintf(f,
"%s%-*s = [%" PRIuPTR
"] (offset %" PRIu64
", %" PRIuPTR
" bytes) \"%s\"\n",
796 p, w,
"string", i, at, s.size(), s.c_str());
810 SgAsmNEEntryPoint::dump(FILE *f,
const char *prefix, ssize_t idx)
const
814 sprintf(p,
"%sNEEntryPoint[%zd].", prefix, idx);
816 sprintf(p,
"%sNEEntryPoint.", prefix);
819 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
821 if (0 == p_section_idx) {
822 fprintf(f,
"%s%-*s = %s\n", p, w,
"type",
"unused");
823 ROSE_ASSERT(SgAsmNEEntryPoint::EF_ZERO == p_flags);
824 ROSE_ASSERT(0 == p_int3f);
825 ROSE_ASSERT(0 == p_section_offset);
827 fprintf(f,
"%s%-*s = %s\n", p, w,
"type", 0 == p_int3f ?
"fixed" :
"movable");
828 fprintf(f,
"%s%-*s = 0x%02x", p, w,
"flags", p_flags);
829 if (p_flags & EF_EXPORTED) fputs(
" exported", f);
830 if (p_flags & EF_GLOBAL) fputs(
" global", f);
831 if (p_flags & EF_RESERVED) fputs(
" *", f);
834 fprintf(f,
"%s%-*s = 0x%04x\n", p, w,
"int3f", p_int3f);
835 fprintf(f,
"%s%-*s = %d\n", p, w,
"section_idx", p_section_idx);
836 fprintf(f,
"%s%-*s = 0x%04x\n", p, w,
"section_offset", p_section_offset);
842 SgAsmNEEntryTable::ctor(rose_addr_t offset, rose_addr_t size)
848 set_synthesized(
true);
850 set_purpose(SP_HEADER);
856 read_content_local(at++, &byte, 1);
857 size_t bundle_nentries = byte;
858 while (bundle_nentries > 0) {
859 p_bundle_sizes.push_back(bundle_nentries);
860 read_content_local(at++, &byte, 1);
861 unsigned segment_indicator = byte;
862 if (0 == segment_indicator) {
864 for (
size_t i = 0; i < bundle_nentries; i++) {
867 }
else if (0xff == segment_indicator) {
869 for (
size_t i = 0; i < bundle_nentries; i++, at+=6) {
870 read_content_local(at, &byte, 1);
871 SgAsmNEEntryPoint::NEEntryFlags flags = (SgAsmNEEntryPoint::NEEntryFlags)byte;
872 read_content_local(at+1, &u16_disk, 2);
873 unsigned int3f = ByteOrder::le_to_host(u16_disk);
874 ROSE_ASSERT(int3f!=0);
875 read_content_local(at+3, &byte, 1);
876 unsigned segno = byte;
877 read_content_local(at+4, &u16_disk, 2);
878 unsigned segoffset = ByteOrder::le_to_host(u16_disk);
883 for (
size_t i = 0; i < bundle_nentries; i++, at+=3) {
884 read_content_local(at, &byte, 1);
885 SgAsmNEEntryPoint::NEEntryFlags flags = (SgAsmNEEntryPoint::NEEntryFlags)byte;
886 read_content_local(at+1, &u16_disk, 2);
887 unsigned segoffset = ByteOrder::le_to_host(u16_disk);
888 p_entries.push_back(
new SgAsmNEEntryPoint(flags, 0, segment_indicator, segoffset));
892 read_content_local(at++, &byte, 1);
893 bundle_nentries = byte;
900 SgAsmNEEntryTable::populate_entries()
903 for (
size_t i=0; i < p_entries.size(); i++) {
906 if (0 == entry.get_section_idx()) {
908 }
else if (NULL == (section = get_file()->get_section_by_id(entry.get_section_idx()))) {
909 mlog[
WARN] <<
"ignoring bad entry section_idx\n";
910 entry.dump(stderr,
" ", i);
919 std::vector<std::string> names = nametab->get_names_by_ordinal(i+1);
920 fprintf(stderr,
"ROBB: entry[%" PRIuPTR
"] (ordinal %" PRIuPTR
")\n", i, i+1);
921 for (
size_t j = 0; j < p_names.size(); j++) {
922 fprintf(stderr,
"ROBB: name=\"%s\"\n", p_names[j].c_str());
935 for (
size_t bi=0, ei=0; bi < p_bundle_sizes.size(); ei += p_bundle_sizes[bi++]) {
936 ROSE_ASSERT(p_bundle_sizes[bi] > 0 && p_bundle_sizes[bi] <= 0xff);
937 unsigned char n = p_bundle_sizes[bi];
938 spos = write(f, spos, n);
940 ROSE_ASSERT(ei + p_bundle_sizes[bi] <= p_entries.size());
941 if (0 == p_entries[ei]->get_section_idx()) {
943 spos = write(f, spos,
'\0');
944 }
else if (0 == p_entries[ei]->get_int3f()) {
946 ROSE_ASSERT(p_entries[ei]->get_section_idx() <= 0xff);
947 unsigned char n = p_entries[ei]->get_section_idx();
948 spos = write(f, spos, n);
949 for (
size_t i = 0; i < p_bundle_sizes[bi]; i++) {
950 ROSE_ASSERT(p_entries[ei]->get_section_idx() == p_entries[ei+i]->get_section_idx());
951 ROSE_ASSERT(p_entries[ei+i]->get_int3f() == 0);
952 ROSE_ASSERT(p_entries[ei+i]->get_flags() <= 0xff);
953 n = p_entries[ei+i]->get_flags();
954 spos = write(f, spos, n);
956 ByteOrder::host_to_le(p_entries[ei+i]->get_section_offset(), &eoff_le);
957 spos = write(f, spos,
sizeof eoff_le, &eoff_le);
961 spos = write(f, spos,
'\377');
962 for (
size_t i = 0; i < p_bundle_sizes[bi]; i++) {
963 ROSE_ASSERT(p_entries[ei+i]->get_section_idx() > 0);
964 ROSE_ASSERT(p_entries[ei+i]->get_int3f() != 0);
965 ROSE_ASSERT(p_entries[ei+i]->get_flags() <= 0xff);
966 n = p_entries[ei+i]->get_flags();
967 spos = write(f, spos, n);
969 ByteOrder::host_to_le(p_entries[ei+i]->get_int3f(), &word);
970 spos = write(f, spos,
sizeof word, &word);
971 ROSE_ASSERT(p_entries[ei+i]->get_section_idx() <= 0xff);
972 n = p_entries[ei+i]->get_section_idx();
973 spos = write(f, spos, n);
974 ByteOrder::host_to_le(p_entries[ei+i]->get_section_offset(), &word);
975 spos = write(f, spos,
sizeof word, &word);
979 write(f, spos,
'\0');
988 sprintf(p,
"%sNEEntryTable[%zd].", prefix, idx);
990 sprintf(p,
"%sNEEntryTable.", prefix);
993 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
996 fprintf(f,
"%s%-*s = %" PRIuPTR
" bundles\n", p, w,
"nbundles", p_bundle_sizes.size());
997 for (
size_t i = 0; i < p_bundle_sizes.size(); i++) {
998 fprintf(f,
"%s%-*s = [%" PRIuPTR
"] %" PRIuPTR
" entries\n", p, w,
"bundle_size", i, p_bundle_sizes[i]);
1000 for (
size_t i = 0; i < p_entries.size(); i++) {
1001 p_entries[i]->dump(f, p, i);
1011 SgAsmNERelocEntry::ctor(
SgAsmGenericSection *relocs, rose_addr_t at, rose_addr_t *rec_size)
1017 rose_addr_t orig_at = at;
1018 ROSE_ASSERT(at == relocs->
get_size());
1024 p_src_type = (SgAsmNERelocEntry::NERelocSrcType)(n & 0x0f);
1025 p_modifier = (SgAsmNERelocEntry::NERelocModifiers)(n>>8);
1031 p_tgt_type = (SgAsmNERelocEntry::NERelocTgtType)(n & 0x03);
1032 p_flags = (SgAsmNERelocEntry::NERelocFlags)(n>>2);
1039 p_src_offset = ByteOrder::le_to_host(u16_disk);
1042 switch (p_tgt_type) {
1043 case RF_TGTTYPE_IREF:
1047 p_iref.sect_idx = byte;
1051 p_iref.tgt_offset = ByteOrder::le_to_host(u16_disk);
1054 case RF_TGTTYPE_IORD:
1058 p_iord.modref = ByteOrder::le_to_host(u16_disk);
1060 p_iord.ordinal = ByteOrder::le_to_host(u16_disk);
1062 if (p_flags & RF_2EXTRA) {
1063 if (p_flags & RF_32ADD) {
1066 p_iord.addend = ByteOrder::le_to_host(u32_disk);
1071 p_iord.addend = ByteOrder::le_to_host(u16_disk);
1078 case RF_TGTTYPE_INAME:
1082 p_iname.modref = ByteOrder::le_to_host(u16_disk);
1084 p_iname.nm_off = ByteOrder::le_to_host(u16_disk);
1086 if (p_flags & RF_2EXTRA) {
1087 if (p_flags & RF_32ADD) {
1090 p_iname.addend = ByteOrder::le_to_host(u32_disk);
1095 p_iname.addend = ByteOrder::le_to_host(u16_disk);
1102 case RF_TGTTYPE_OSFIXUP:
1106 p_osfixup.type = ByteOrder::le_to_host(u16_disk);
1108 p_osfixup.res3 = ByteOrder::le_to_host(u16_disk);
1114 *rec_size = at - orig_at;
1119 SgAsmNERelocEntry::unparse(std::ostream &f,
const SgAsmGenericSection *section, rose_addr_t spos)
const
1122 byte = (p_modifier << 8) | (p_src_type & 0x0f);
1123 spos = section->
write(f, spos, byte);
1124 byte = (p_flags << 2) | (p_tgt_type & 0x03);
1125 spos = section->
write(f, spos, byte);
1129 ByteOrder::host_to_le(p_src_offset, &word);
1130 spos = section->
write(f, spos,
sizeof word, &word);
1132 switch (p_tgt_type) {
1133 case RF_TGTTYPE_IREF:
1134 ByteOrder::host_to_le(p_iref.sect_idx, &byte);
1135 spos = section->
write(f, spos, byte);
1136 ByteOrder::host_to_le(p_iref.res1, &byte);
1137 spos = section->
write(f, spos, byte);
1138 ByteOrder::host_to_le(p_iref.tgt_offset, &word);
1139 spos = section->
write(f, spos,
sizeof word, &word);
1141 case RF_TGTTYPE_IORD:
1142 ByteOrder::host_to_le(p_iord.modref, &word);
1143 spos = section->
write(f, spos,
sizeof word, &word);
1144 ByteOrder::host_to_le(p_iord.ordinal, &word);
1145 spos = section->
write(f, spos,
sizeof word, &word);
1146 if (p_flags & RF_2EXTRA) {
1147 if (p_flags & RF_32ADD) {
1148 ByteOrder::host_to_le(p_iord.addend, &dword);
1149 spos = section->
write(f, spos,
sizeof dword, &dword);
1151 ByteOrder::host_to_le(p_iord.addend, &word);
1152 spos = section->
write(f, spos,
sizeof word, &word);
1155 ROSE_ASSERT(p_iord.addend==0);
1158 case RF_TGTTYPE_INAME:
1159 ByteOrder::host_to_le(p_iname.modref, &word);
1160 spos = section->
write(f, spos,
sizeof word, &word);
1161 ByteOrder::host_to_le(p_iname.nm_off, &word);
1162 spos = section->
write(f, spos,
sizeof word, &word);
1163 if (p_flags & RF_2EXTRA) {
1164 if (p_flags & RF_32ADD) {
1165 ByteOrder::host_to_le(p_iname.addend, &dword);
1166 spos = section->
write(f, spos,
sizeof dword, &dword);
1168 ByteOrder::host_to_le(p_iname.addend, &word);
1169 spos = section->
write(f, spos,
sizeof word, &word);
1172 ROSE_ASSERT(p_iname.addend==0);
1175 case RF_TGTTYPE_OSFIXUP:
1176 ByteOrder::host_to_le(p_osfixup.type, &word);
1177 spos = section->
write(f, spos,
sizeof word, &word);
1178 ByteOrder::host_to_le(p_osfixup.res3, &word);
1179 spos = section->
write(f, spos,
sizeof word, &word);
1182 ROSE_ASSERT(!
"unknown relocation target type");
1189 SgAsmNERelocEntry::dump(FILE *f,
const char *prefix, ssize_t idx)
const
1193 sprintf(p,
"%sRelocEntry[%zd].", prefix, idx);
1195 sprintf(p,
"%sRelocEntry.", prefix);
1198 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
1201 switch (p_src_type) {
1202 case RF_SRCTYPE_8OFF: s =
"byte offset";
break;
1203 case RF_SRCTYPE_WORDSEG: s =
"16-bit selector";
break;
1204 case RF_SRCTYPE_16PTR: s =
"16-bit pointer";
break;
1205 case RF_SRCTYPE_16OFF: s =
"16-bit offset";
break;
1206 case RF_SRCTYPE_32PTR: s =
"32-bit pointer";
break;
1207 case RF_SRCTYPE_32OFF: s =
"32-bit offset";
break;
1208 case RF_SRCTYPE_NEARCALL: s =
"near call/jump";
break;
1209 case RF_SRCTYPE_48PTR: s =
"48-bit pointer";
break;
1210 case RF_SRCTYPE_32OFF_b: s =
"32-bit offset";
break;
1211 default: s =
"unknown";
break;
1213 fprintf(f,
"%s%-*s = %u (%s)\n", p, w,
"src_type", p_src_type, s);
1215 switch (p_modifier) {
1216 case RF_MODIFIER_SINGLE: s =
"single";
break;
1217 case RF_MODIFIER_MULTI: s =
"multiple";
break;
1218 default: s =
"unknown";
break;
1220 fprintf(f,
"%s%-*s = 0x%04u (%s)\n", p, w,
"modifier", p_modifier, s);
1222 switch (p_tgt_type) {
1223 case RF_TGTTYPE_IREF: s =
"internal reference";
break;
1224 case RF_TGTTYPE_IORD: s =
"imported ordinal";
break;
1225 case RF_TGTTYPE_INAME: s =
"imported name";
break;
1226 case RF_TGTTYPE_OSFIXUP: s =
"OS fixup";
break;
1227 default: s =
"unknown";
break;
1229 fprintf(f,
"%s%-*s = %u (%s)\n", p, w,
"tgt_type", p_tgt_type, s);
1231 fprintf(f,
"%s%-*s = 0x%04x", p, w,
"flags", p_flags);
1232 if (p_flags & RF_ADDITIVE) fputs(
" additive", f);
1233 if (p_flags & RF_2EXTRA) fputs(
" 2-extra", f);
1234 if (p_flags & RF_32ADD) fputs(
" 32-add", f);
1235 if (p_flags & RF_16SECTION) fputs(
" 16-sect", f);
1236 if (p_flags & RF_8ORDINAL) fputs(
" 8-ordinal", f);
1239 fprintf(f,
"%s%-*s = 0x%08" PRIx64
"\n", p, w,
"src_offset", p_src_offset);
1241 switch (p_tgt_type) {
1242 case RF_TGTTYPE_IREF:
1243 fprintf(f,
"%s%-*s = %u\n", p, w,
"sect_idx", p_iref.sect_idx);
1244 fprintf(f,
"%s%-*s = 0x%02x\n", p, w,
"res3", p_iref.res1);
1245 fprintf(f,
"%s%-*s = 0x%08" PRIx64
"\n", p, w,
"tgt_offset", p_iref.tgt_offset);
1247 case RF_TGTTYPE_IORD:
1248 fprintf(f,
"%s%-*s = %u\n", p, w,
"modref", p_iord.modref);
1249 fprintf(f,
"%s%-*s = %u\n", p, w,
"ordinal", p_iord.ordinal);
1250 fprintf(f,
"%s%-*s = %" PRIu64
"\n", p, w,
"addend", p_iord.addend);
1252 case RF_TGTTYPE_INAME:
1253 fprintf(f,
"%s%-*s = %u\n", p, w,
"modref", p_iname.modref);
1254 fprintf(f,
"%s%-*s = %u\n", p, w,
"nm_off", p_iname.nm_off);
1255 fprintf(f,
"%s%-*s = %" PRIu64
"\n", p, w,
"addend", p_iname.addend);
1257 case RF_TGTTYPE_OSFIXUP:
1258 fprintf(f,
"%s%-*s = %u\n", p, w,
"type", p_osfixup.type);
1259 fprintf(f,
"%s%-*s = 0x%04x\n", p, w,
"res3", p_osfixup.res3);
1262 ROSE_ASSERT(!
"unknown relocation target type");
1272 ROSE_ASSERT(section!=NULL);
1278 sprintf(name,
"NE Relocation Table %" PRIu64, p_offset);
1279 set_synthesized(
true);
1281 set_purpose(SP_HEADER);
1283 ROSE_ASSERT(0 == get_size());
1285 rose_addr_t at = 0, reloc_size = 0;
1289 read_content_local(at, &u16_disk, 2);
1290 size_t nrelocs = ByteOrder::le_to_host(u16_disk);
1293 for (
size_t i = 0; i < nrelocs; i++, at += reloc_size) {
1304 ByteOrder::host_to_le(p_entries.size(), &size_le);
1305 spos = write(f, spos,
sizeof size_le, &size_le);
1307 for (
size_t i = 0; i < p_entries.size(); i++) {
1308 spos = p_entries[i]->unparse(f,
this, spos);
1318 sprintf(p,
"%sNERelocTable[%zd].", prefix, idx);
1320 sprintf(p,
"%sNERelocTable.", prefix);
1323 const int w = std::max(1, DUMP_FIELD_WIDTH-(
int)strlen(p));
1326 fprintf(f,
"%s%-*s = %" PRIuPTR
" entries\n", p, w,
"size", p_entries.size());
1327 for (
size_t i = 0; i < p_entries.size(); i++) {
1328 p_entries[i]->dump(f, p, i);
1338 ROSE_ASSERT(dos_header);
1345 dos2_header->parse();
1349 ne_header->set_dos2_header(dos2_header);
1352 if (ne_header->get_e_resnametab_rfo() > 0) {
1353 rose_addr_t resnames_offset = ne_header->
get_offset() + ne_header->get_e_resnametab_rfo();
1356 ne_header->set_resname_table(resnames);
1358 if (ne_header->get_e_modreftab_rfo() > 0 && ne_header->get_e_importnametab_rfo() > ne_header->get_e_modreftab_rfo()) {
1361 ROSE_ASSERT(ne_header->get_e_importnametab_rfo() > 0);
1362 ROSE_ASSERT(ne_header->get_e_entrytab_rfo() > ne_header->get_e_importnametab_rfo());
1363 rose_addr_t strtab_offset = ne_header->
get_offset() + ne_header->get_e_importnametab_rfo();
1364 rose_addr_t strtab_size = ne_header->get_e_entrytab_rfo() - ne_header->get_e_importnametab_rfo();
1368 rose_addr_t modref_offset = ne_header->
get_offset() + ne_header->get_e_modreftab_rfo();
1369 rose_addr_t modref_size = ne_header->get_e_importnametab_rfo() - ne_header->get_e_modreftab_rfo();
1371 ne_header->set_module_table(modtab);
1373 if (ne_header->get_e_entrytab_rfo() > 0 && ne_header->get_e_entrytab_size() > 0) {
1374 rose_addr_t enttab_offset = ne_header->
get_offset() + ne_header->get_e_entrytab_rfo();
1375 rose_addr_t enttab_size = ne_header->get_e_entrytab_size();
1377 ne_header->set_entry_table(enttab);
1379 if (ne_header->get_e_nonresnametab_offset() > 0) {
1382 ne_header->set_nonresname_table(nonres);
1391 enttab->populate_entries();
SgAsmGenericFile * get_file() const
Property: File to which this section belongs.
String associated with a binary file.
size_t read_content(rose_addr_t offset, void *dst_buf, rose_addr_t size, bool strict=true)
Reads data from a file.
Contiguous region of a file.
void set_mapped_xperm(bool)
Property: Whether mapped with execute permission.
virtual void unparse(std::ostream &) const
Write a section back to the file.
ROSE_DLL_API Sawyer::Message::Facility mlog
Diagnostic facility for the ROSE library as a whole.
size_t read_content_local(rose_addr_t rel_offset, void *dst_buf, rose_addr_t size, bool strict=true)
Reads data from a file.
void set_parent(SgNode *parent)
All nodes in the AST contain a reference to a parent node.
const SgAsmGenericSectionPtrList & get_sections() const
Property: List of section pointers.
void set_mapped_actual_va(rose_addr_t)
Property: Virtual address where ROSE maps this section.
rose_addr_t get_offset() const
Property: Offset to start of section in file.
virtual void set_mapped_preferred_rva(rose_addr_t)
Property: Relative virtual address where section prefers to be mapped.
ROSE_DLL_API int set_name(SgInitializedName *initializedNameNode, SgName new_name)
set_name of symbol in symbol table.
rose_addr_t write(std::ostream &f, rose_addr_t offset, size_t bufsize, const void *buf) const
Write data to a file section.
void set_mapped_rperm(bool)
Property: Whether mapped with read permission.
bool is_mapped() const
Whether section desires to be mapped to memory.
virtual void dump(FILE *, const char *prefix, ssize_t idx) const ROSE_OVERRIDE
Print some debugging info.
virtual void unparse(std::ostream &) const ROSE_OVERRIDE
Write a section back to the file.
virtual void set_offset(rose_addr_t)
Property: Offset to start of section in file.
virtual void dump(FILE *, const char *prefix, ssize_t idx) const
Print some debugging info.
virtual void unparse(std::ostream &) const ROSE_OVERRIDE
Write a section back to the file.
void set_synthesized(bool)
Property: Whether section really exists.
rose_addr_t get_size() const
Property: Size of section in file in bytes.
Base class for dynamically linked library information.
void grab_content()
Saves a reference to the original file data for a section based on the section's current offset and s...
virtual void unparse(std::ostream &) const ROSE_OVERRIDE
Write a section back to the file.
void set_mapped_wperm(bool)
Property: Whether mapped with write permission.
virtual void dump(FILE *, const char *prefix, ssize_t idx) const ROSE_OVERRIDE
Print some debugging info.
virtual void set_size(rose_addr_t)
Property: Size of section in file in bytes.
virtual void dump(FILE *, const char *prefix, ssize_t idx) const ROSE_OVERRIDE
Print some debugging info.
virtual void unparse(std::ostream &) const ROSE_OVERRIDE
Write a section back to the file.
virtual void dump(FILE *, const char *prefix, ssize_t idx) const ROSE_OVERRIDE
Print some debugging info.
void set_purpose(SectionPurpose)
Property: General contents of the section.
void set_id(int)
Property: Non-unique section ID or negative.
rose_addr_t get_end_offset() const
File offset for end of section.
virtual void dump(FILE *, const char *prefix, ssize_t idx) const ROSE_OVERRIDE
Print some debugging info.
virtual void set_mapped_size(rose_addr_t)
Property: Mapped size.
Warning messages that indicate an unusual situation from which the program was able to fully recover...
rose_addr_t get_mapped_preferred_rva() const
Property: Relative virtual address where section prefers to be mapped.
void extend(rose_addr_t nbytes)
Extend a section by some number of bytes during the construction and/or parsing phase.
Controls diagnostic messages from ROSE.
int get_id() const
Property: Non-unique section ID or negative.
virtual void unparse(std::ostream &) const ROSE_OVERRIDE
Write a section back to the file.
virtual void dump(FILE *, const char *prefix, ssize_t idx) const ROSE_OVERRIDE
Print some debugging info.
void set_name(SgAsmGenericString *s)
Property: Non-unique name of section.
Base class for binary files.