/** Convert to a string representation. If this RVA is unbound, then the string representation is the numeric RVA value (in * hexadecimal and decimal). Otherwise the string representation contains information about the bound section. */ std::string rose_rva_t::to_string() const { char s[1024]; sprintf(s, "0x%08"PRIx64" (%"PRIu64")", get_rva(), get_rva()); std::string ss = s; if (get_section()) { sprintf(s, " + 0x%08"PRIx64" (%"PRIu64")", get_rel(), get_rel()); ss += " <" + get_section()->get_name()->get_string(true) + s + ">"; } return ss; }
/** Binds this RVA to the best available section from the specified file header. The numeric value of the RVA is not changed * by this operation. The section is selected to be the mapped section that most specifically includes this RVA. */ rose_rva_t& rose_rva_t::bind(SgAsmGenericHeader *fhdr) { rose_addr_t va = get_rva() + fhdr->get_base_va(); SgAsmGenericSection *secbind = fhdr->get_best_section_by_va(va, true); return set_section(secbind); }
int main(int argc, char *argv[]) { char *dll_filename; char *def_filename; char *dll; int fd; unsigned int size, i; struct stat st; struct dos_header *doshdr; struct image_header *imghdr; struct image_export_directory *expdir; unsigned long *names; unsigned short *ordinals; char *module_name; FILE *output; // Parse command line if (argc == 2) { dll_filename = argv[1]; def_filename = NULL; } else if (argc == 3) { dll_filename = argv[1]; def_filename = argv[2]; } else { fprintf(stderr, "usage: impdef <dll> [<def>]\n"); return 1; } // Load DLL image into memory fd = open(dll_filename, O_RDONLY | O_BINARY); if (fd < 0 || fstat(fd, &st) < 0) { perror(dll_filename); return 1; } size = st.st_size; dll = (char *) malloc(size); if (read(fd, dll, size) != size) { perror(dll_filename); free(dll); return 1; } close(fd); // Check PE file signature doshdr = (struct dos_header *) dll; imghdr = (struct image_header *) (dll + doshdr->e_lfanew); if (doshdr->e_lfanew > size || imghdr->signature != IMAGE_PE_SIGNATURE) { fprintf(stderr, "%s: Not a PE file\n", dll_filename); free(dll); return 1; } // Open output file. if (def_filename) { output = fopen(def_filename, "wb"); if (output == NULL) { perror(def_filename); free(dll); return 1; } } else { output = stdout; } // Output exported functions. expdir = get_image_directory(dll, imghdr, IMAGE_DIRECTORY_ENTRY_EXPORT); module_name = get_rva(dll, imghdr, expdir->name); fprintf(output, "LIBRARY %s\r\n\r\nEXPORTS\r\n", module_name); names = get_rva(dll, imghdr, expdir->address_of_names); ordinals = get_rva(dll, imghdr, expdir->address_of_name_ordinals); for (i = 0; i < expdir->number_of_names; i++) { char *name = get_rva(dll, imghdr, names[i]); fprintf(output, "%s@%d\r\n", name, ordinals[i]); } if (def_filename) fclose(output); free(dll); return 0; }
void *get_image_directory(char *dll, struct image_header *imghdr, int dir) { return get_rva(dll, imghdr, imghdr->optional.data_directory[dir].virtual_address); }
/** Returns an offset relative to the specified section. The specified section must be mapped to a VA. */ rose_addr_t rose_rva_t::get_rel(SgAsmGenericSection *s) { assert(s!=NULL && s->is_mapped()); return get_rva() - s->get_mapped_preferred_rva(); }