20 ROSE_ASSERT(section!=NULL);
37 SgAsmPEFileHeader *fhdr = SageInterface::getEnclosingNode<SgAsmPEFileHeader>(
this);
48 if (hint>=0 && (
size_t)hint<imports.size() && imports[hint]==item)
50 for (
size_t i=0; i<imports.size(); ++i) {
71 for (SgAsmPEImportItemPtrList::const_iterator ii=imports.begin(); ii!=imports.end(); ++ii) {
73 if (!import->get_by_ordinal() &&
import->get_hintname_rva().get_rva()!=0 &&
import->get_hintname_nalloc()>0) {
74 size_t nbytes = std::min(import->get_hintname_nalloc(),
import->hintname_required_size());
75 extent.
insert(
Extent(import->get_hintname_rva().get_va(), nbytes));
88 SgAsmPEFileHeader *fhdr = SageInterface::getEnclosingNode<SgAsmPEFileHeader>(
this);
89 ROSE_ASSERT(fhdr!=NULL);
93 memset(&zero, 0,
sizeof zero);
95 if (nread!=
sizeof disk) {
97 "at va 0x%08"PRIx64
" (needed %zu bytes)\n",
98 nread, 1==nread?
"":
"s", idir_va,
sizeof disk);
99 memset(&disk, 0,
sizeof disk);
103 if (!memcmp(&disk, &zero,
sizeof zero))
120 std::string dll_name;
129 " import directory at va 0x%08"PRIx64
"\n",
132 fprintf(stderr,
" Memory map in effect at time of error is:\n");
168 bool processing_iat = !imports.empty();
175 uint64_t by_ordinal_bit = 1ull << (8*entry_size-1);
177 for (
size_t idx=0; 1; ++idx, entry_va+=entry_size) {
179 uint64_t entry_word = 0;
184 ": table entry is outside mapped memory\n", idx, entry_va) && e.
map) {
185 fprintf(stderr,
" Memory map in effect at time of error:\n");
197 if (idx<imports.size()) {
199 ": IAT zero termination occurs before end of corresponding ILT;"
200 " %scontinuing to read IAT entries.\n", idx, entry_va,
201 (assume_bound?
"":
"assuming this is a bound null address and "));
202 assert(idx<imports.size());
203 imports[idx]->set_bound_rva(
rose_rva_t(entry_word).bind(fhdr));
208 }
else if (processing_iat && idx>=imports.size()) {
210 ": IAT extends beyond end of corresponding ILT (it is not zero terminated)"
211 "; forcibly terminating here\n", idx, entry_va);
216 bool entry_existed =
true;
217 if (idx>=imports.size()) {
218 assert(idx==imports.size());
220 entry_existed =
false;
229 ": bound address 0x%08"PRIx64
" conflicts with bound address already"
230 " discovered 0x%08"PRIx64
" (using new value)\n", idx, entry_va, entry_word,
234 }
else if (0!=(entry_word & by_ordinal_bit)) {
236 if (entry_existed && import_item->
get_ordinal()!=0 && import_item->
get_ordinal()!=(entry_word & 0xffff)) {
238 ": ordinal %"PRIu64
" conflicts with ordinal already discovered %u"
239 " (assuming this is a bound address)\n", idx, entry_va, (entry_word&0xffff),
245 if (0!=(entry_word & ~(by_ordinal_bit | 0xffff))) {
247 ": contains extra bits in violation of PE specification"
248 " (extra bits removed)\n", idx, entry_va);
256 ": entry type \"hint/name\" conflicts with entry type already discovered"
257 " \"ordinal\" (assuming this is a bound address)\n", idx, entry_va);
262 ": hint/name rva 0x%08"PRIx64
" conflicts with hint/name rva already"
263 " discovered 0x%08"PRIx64
" (assuming this is a bound address)\n",
278 ": points to unmapped Hint/Name pair at va 0x%08"PRIx64
279 " (when reading hint)\n", idx, entry_va, entry_word_va) &&
281 fprintf(stderr,
" Memory map in effect at time of error:\n");
295 ": points to an unmapped Hint/Name pair at va 0x%08"PRIx64
296 " (when reading name)\n", idx, entry_va, entry_word_va) &&
298 fprintf(stderr,
" Memory map in effect at time of error:\n");
305 if ((s.size()+1) % 2) {
311 ": points to an unmapped Hint/Name pair at va 0x%08"PRIx64
312 " (when reading pad byte)\n", idx, entry_va, entry_word_va) &&
314 fprintf(stderr,
" Memory map in effect at time of error:\n");
321 ": has a non-zero padding byte: 0x%02x\n", idx, entry_va, byte);
343 size_t tablesize)
const
352 uint64_t by_ordinal_bit = 1ull << (8*entry_size-1);
354 if (0==table_start.
get_rva() || imports.empty())
363 size_t nelmts = std::min(tablesize/entry_size, imports.size()+1);
364 if (nelmts<imports.size()+1) {
366 " %zu entries (inc. zero terminator) due to allocation constraints.\n",
367 table_start.
to_string().c_str(), imports.size()+1, nelmts);
371 for (
size_t idx=0; idx<nelmts; ++idx, entry_rva.
increment(entry_size)) {
372 uint64_t entry_word = 0;
381 rose_rva_t hn_rva = imports[idx]->get_hintname_rva();
385 entry_word = imports[idx]->get_bound_rva().
get_rva();
386 }
else if (imports[idx]->get_by_ordinal()) {
387 if (0!=(imports[idx]->get_ordinal() & ~0xffff)) {
389 ": ordinal is out of bounds: %u (truncated to 16 bits)\n",
390 idx, entry_rva.
get_rva(), imports[idx]->get_ordinal());
392 entry_word |= by_ordinal_bit | (imports[idx]->get_ordinal() & 0xffff);
395 ": non-ordinal entry has invalid hint/name pair address %s or is"
396 " not associated with any section.\n",
400 size_t bufsz = std::min(imports[idx]->get_hintname_nalloc(), imports[idx]->hintname_required_size());
401 if (bufsz < imports[idx]->hintname_required_size()) {
403 ": insufficient space (%zu byte%s) allocated for hint/name pair at"
404 " rva %s (need %zu bytes)\n",
405 idx, entry_rva.
get_rva(), bufsz, 1==bufsz?
"":
"s",
406 hn_rva.
to_string().c_str(), imports[idx]->hintname_required_size());
409 uint8_t *buf =
new uint8_t[bufsz];
410 unsigned hint = imports[idx]->get_hint();
411 std::string
name = imports[idx]->get_name()->get_string();
412 if (0!=(hint & ~0xffff)) {
414 ": hint is out of bounds: %u (truncated to 16 bits)\n",
415 idx, entry_rva.
get_rva(), hint);
418 memcpy(buf, &hint, 2);
419 memcpy(buf+2, name.c_str(), std::min(name.size()+1, bufsz-2));
423 if (0!=(hn_rva.
get_rva() & by_ordinal_bit)) {
425 ": hint/name pair rva 0x%08"PRIx64
" has by_ordinal bit set\n",
430 entry_word = hn_rva.
get_rva() & ~by_ordinal_bit;
436 ": zero table entry will cause table to be truncated when read\n",
497 for (
size_t i=0; i<imports.size(); ++i) {
498 if (!imports[i]->get_by_ordinal() &&
499 (0==imports[i]->get_hintname_rva() || imports[i]->get_hintname_rva().get_section()==end_rva.
get_section())) {
500 size_t sz = imports[i]->hintname_required_size();
501 imports[i]->set_hintname_nalloc(sz);
502 imports[i]->set_hintname_rva(end_rva);
539 section->
write(f, idx*
sizeof disk,
sizeof disk, &disk);
549 sprintf(p,
"%sPEImportDirectory[%zd].", prefix, idx);
551 sprintf(p,
"%sPEImportDirectory.", prefix);
561 fprintf(f,
"%s%-*s = %lu %s", p, w,
"time", (
unsigned long)
p_time, ctime(&p_time));
569 import->dump(f, p, i);