/* check if a given forward does exist in one of the imported dlls */ static void check_undefined_forwards( DLLSPEC *spec ) { char *link_name, *api_name, *dll_name, *p; int i, j; for (i = 0; i < spec->nb_entry_points; i++) { ORDDEF *odp = &spec->entry_points[i]; if (!(odp->flags & FLAG_FORWARD)) continue; link_name = xstrdup( odp->link_name ); p = strrchr( link_name, '.' ); *p = 0; api_name = p + 1; dll_name = get_dll_name( link_name, NULL ); for (j = 0; j < nb_imports; j++) { struct import *imp = dll_imports[j]; if (strcasecmp( imp->spec->file_name, dll_name )) continue; if (!find_export( api_name, imp->exports, imp->nb_exports )) warning( "%s:%d: forward '%s' not found in %s\n", spec->src_name, odp->lineno, odp->link_name, imp->spec->file_name ); break; } if (j == nb_imports) warning( "%s:%d: forward '%s' not found in the imported dll list\n", spec->src_name, odp->lineno, odp->link_name ); free( link_name ); free( dll_name ); } }
/* add a dll to the list of imports */ void add_import_dll( const char *name, const char *filename ) { struct import *imp = xmalloc( sizeof(*imp) ); imp->spec = alloc_dll_spec(); imp->spec->file_name = get_dll_name( name, filename ); imp->delay = 0; imp->imports = NULL; imp->nb_imports = 0; imp->exports = NULL; imp->nb_exports = 0; if (filename) imp->full_name = xstrdup( filename ); else imp->full_name = find_library( name ); if (read_import_lib( imp )) { dll_imports = xrealloc( dll_imports, (nb_imports+1) * sizeof(*dll_imports) ); dll_imports[nb_imports++] = imp; } else { free_imports( imp ); if (nb_errors) exit(1); } }
cb_dlhandle_t cb_dlopen(const char *library, char **errmsg) { cb_dlhandle_t handle; char *buffer = NULL; if (library == NULL) { handle = dlopen(NULL, RTLD_NOW | RTLD_LOCAL); } else { handle = dlopen(library, RTLD_NOW | RTLD_LOCAL); if (handle == NULL) { buffer = malloc(strlen(library) + 20); if (buffer == NULL) { if (*errmsg) { *errmsg = strdup("Failed to allocate memory"); } return NULL; } handle = dlopen(get_dll_name(library, buffer), RTLD_NOW | RTLD_LOCAL); free(buffer); } } if (handle == NULL && errmsg != NULL) { *errmsg = strdup(dlerror()); } return handle; }
/* add a library to the list of delayed imports */ void add_delayed_import( const char *name ) { struct import *imp; char *fullname = get_dll_name( name, NULL ); add_name( &delayed_imports, fullname ); if ((imp = is_already_imported( fullname )) && !imp->delay) { imp->delay = 1; nb_delayed++; } free( fullname ); }
/** Allocates space for this import directory's name, import lookup table, and import address table. The items are allocated * beginning at the specified relative virtual address. Items are reallocated if they are not allocated or if they are * allocated in the same section to which start_rva points (the import section). They are not reallocated if they already * exist in some other section. The return value is the number of bytes allocated in the import section. Upon return, this * directory's address data members are initialized with possibly new values. */ size_t SgAsmPEImportDirectory::reallocate(rose_rva_t start_rva) { rose_rva_t end_rva = start_rva; const SgAsmPEImportItemPtrList &imports = get_imports()->get_vector(); /* Allocate space for the name if it hasn't been allocated already; reallocate space if its allocated in the import * section. Allocate space even if the name is the empty string. */ if (0==p_dll_name_rva.get_rva() || p_dll_name_rva.get_section()==end_rva.get_section()) { p_dll_name_nalloc = get_dll_name()->get_string().size() + 1; p_dll_name_rva = end_rva; end_rva.increment(p_dll_name_nalloc); } /* Allocate space for the import lookup table if it hasn't been allocated yet. The table is terminated with a zero * entry (as is the IAT according to the spec even though the IAT size is implied by the ILT size). */ if (0==p_ilt_rva.get_rva() || p_ilt_rva.get_section()==end_rva.get_section()) { p_ilt_nalloc = iat_required_size(); // ILT and IAT are always the same size p_ilt_rva = end_rva; end_rva.increment(p_ilt_nalloc); } /* Allocate space for the import address table if it hasn't been allocated yet. Note, the import address table should * usually be allocated explicitly because it is referenced by the program's instructions. */ if (0==p_iat_rva.get_rva() || p_iat_rva.get_section()==end_rva.get_section()) { p_iat_nalloc = iat_required_size(); p_iat_rva = end_rva; end_rva.increment(p_iat_nalloc); } /* Allocate space for the Hint/Name pairs that haven't been allocated yet. The ILT and IAT will both point to the same * hint/name pair when the IAT is a copy of the ILT. When the IAT is unparsed as bound addresses, then space for the * hint/name pair is still needed because the ILT still points to it. We allocate space even for hint/name pairs that are * zero and the empty string. We don't reallocate hint/name pairs that are stored in a different file section (so be * careful that you don't increase the length of the name). */ for (size_t i=0; i<imports.size(); ++i) { if (!imports[i]->get_by_ordinal() && (0==imports[i]->get_hintname_rva() || imports[i]->get_hintname_rva().get_section()==end_rva.get_section())) { size_t sz = imports[i]->hintname_required_size(); imports[i]->set_hintname_nalloc(sz); imports[i]->set_hintname_rva(end_rva); end_rva.increment(sz); } } return end_rva.get_rva() - start_rva.get_rva(); }
void TraceLog::logCall(const ADDRINT prevAddr, const string module, const string func) { createFile(); m_traceFile << std::hex << prevAddr << DELIMITER; if (!m_shortLog) { m_traceFile << "called: " << module; } else { m_traceFile << get_dll_name(module); } if (func.length() > 0) { m_traceFile << "." << func; } m_traceFile << std::endl; m_traceFile.flush(); }