type_class_def ReturnClass( type_def *tipe, call_attributes attr ) /*****************************************************************/ { switch( tipe->refno ) { case TY_INT_1: case TY_UINT_1: case TY_INT_2: case TY_UINT_2: case TY_INT_4: case TY_UINT_4: case TY_INT_8: case TY_UINT_8: return( MapIntReturn( tipe->refno ) ); case TY_NEAR_POINTER: case TY_NEAR_CODE_PTR: case TY_HUGE_POINTER: case TY_LONG_CODE_PTR: case TY_LONG_POINTER: return( MapPointer( tipe->refno ) ); case TY_SINGLE: case TY_DOUBLE: case TY_LONG_DOUBLE: return( MapFloat( tipe->refno, attr ) ); default: return( MapStruct( tipe->length, attr ) ); } }
struct DepTreeElement *ProcessDep (BuildTreeConfig* cfg, soff_entry *soffs, int soffs_len, DWORD name, struct DepTreeElement *root, struct DepTreeElement *self, int deep) { struct DepTreeElement *child = NULL; int found; int64_t i; char *dllname = (char *) MapPointer (soffs, soffs_len, name, NULL); if (dllname == NULL) return NULL; if (strlen (dllname) > 10 && strnicmp ("api-ms-win", dllname, 10) == 0) { /* TODO: find a better way to identify api stubs. Versioninfo, maybe? */ return NULL; } for (i = (int64_t)*cfg->stack_len - 1; i >= 0; i--) { if ((*cfg->stack)[i] && stricmp ((*cfg->stack)[i], dllname) == 0) return NULL; if (i == 0) break; } found = FindDep (root, dllname, &child); if (found < 0) { child = (struct DepTreeElement *) malloc (sizeof (struct DepTreeElement)); memset (child, 0, sizeof (struct DepTreeElement)); if (deep == 0) { child->module = strdup (dllname); AddDep (self, child); } } if (deep == 1) { BuildDepTree (cfg, dllname, root, child); } return child; }
static void BuildDepTree32or64 (LOADED_IMAGE *img, BuildTreeConfig* cfg, struct DepTreeElement *root, struct DepTreeElement *self, soff_entry *soffs, int soffs_len) { IMAGE_DATA_DIRECTORY *idata; IMAGE_IMPORT_DESCRIPTOR *iid; IMAGE_EXPORT_DIRECTORY *ied; IMAGE_DELAYLOAD_DESCRIPTOR *idd; void *ith, *oith; void *opt_header = &img->FileHeader->OptionalHeader; DWORD i, j; idata = opt_header_get_dd_entry (opt_header, IMAGE_DIRECTORY_ENTRY_EXPORT, cfg); if (idata->Size > 0 && idata->VirtualAddress != 0) { int export_section = -2; ied = (IMAGE_EXPORT_DIRECTORY *) MapPointer (soffs, soffs_len, idata->VirtualAddress, &export_section); if (ied && ied->Name != 0) { char *export_module = MapPointer (soffs, soffs_len, ied->Name, NULL); if (export_module != NULL) { if (self->export_module == NULL) self->export_module = strdup (export_module); } } if (ied && ied->NumberOfFunctions > 0) { DWORD *addrs, *names; WORD *ords; int section = -1; self->exports_len = ied->NumberOfFunctions; self->exports = (struct ExportTableItem *) malloc (sizeof (struct ExportTableItem) * self->exports_len); memset (self->exports, 0, sizeof (struct ExportTableItem) * self->exports_len); addrs = (DWORD *) MapPointer (soffs, soffs_len, ied->AddressOfFunctions, NULL); ords = (WORD *) MapPointer (soffs, soffs_len, ied->AddressOfNameOrdinals, NULL); names = (DWORD *) MapPointer (soffs, soffs_len, ied->AddressOfNames, NULL); for (i = 0; i < ied->NumberOfNames; i++) { self->exports[ords[i]].ordinal = ords[i] + ied->Base; if (names[i] != 0) { char *s_name = (char *) MapPointer (soffs, soffs_len, names[i], NULL); if (s_name != NULL) self->exports[ords[i]].name = strdup (s_name); } } for (i = 0; i < ied->NumberOfFunctions; i++) { if (addrs[i] != 0) { int section_index = FindSectionByRawData (img, addrs[i]); if ((idata->VirtualAddress <= addrs[i]) && (idata->VirtualAddress + idata->Size > addrs[i])) { self->exports[i].address = NULL; self->exports[i].forward_str = strdup ((char *) MapPointer (soffs, soffs_len, addrs[i], NULL)); } else self->exports[i].address = MapPointer (soffs, soffs_len, addrs[i], §ion); self->exports[i].ordinal = i + ied->Base; self->exports[i].section_index = section_index; self->exports[i].address_offset = addrs[i]; } } } } idata = opt_header_get_dd_entry (opt_header, IMAGE_DIRECTORY_ENTRY_IMPORT, cfg); if (idata->Size > 0 && idata->VirtualAddress != 0) { iid = (IMAGE_IMPORT_DESCRIPTOR *) MapPointer (soffs, soffs_len, idata->VirtualAddress, NULL); if (iid) for (i = 0; iid[i].Characteristics || iid[i].TimeDateStamp || iid[i].ForwarderChain || iid[i].Name || iid[i].FirstThunk; i++) { struct DepTreeElement *dll; uint64_t impaddress; dll = ProcessDep (cfg, soffs, soffs_len, iid[i].Name, root, self, 0); if (dll == NULL) continue; ith = (void *) MapPointer (soffs, soffs_len, iid[i].FirstThunk, NULL); oith = (void *) MapPointer (soffs, soffs_len, iid[i].OriginalFirstThunk, NULL); for (j = 0; (impaddress = thunk_data_u1_function (ith, j, cfg)) != 0; j++) { struct ImportTableItem *imp = AddImport (self); imp->dll = dll; imp->ordinal = -1; if (oith); imp->orig_address = thunk_data_u1_function (oith, j, cfg); if (cfg->on_self) { imp->address = impaddress; } if (oith && imp->orig_address & (1 << (sizeof (DWORD) * 8 - 1))) { imp->ordinal = imp->orig_address & ~(1 << (sizeof (DWORD) * 8 - 1)); } else if (oith) { IMAGE_IMPORT_BY_NAME *byname = (IMAGE_IMPORT_BY_NAME *) MapPointer (soffs, soffs_len, imp->orig_address, NULL); if (byname != NULL) imp->name = strdup ((char *) byname->Name); } } } } idata = opt_header_get_dd_entry (opt_header, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, cfg); if (idata->Size > 0 && idata->VirtualAddress != 0) { idd = (IMAGE_DELAYLOAD_DESCRIPTOR *) MapPointer (soffs, soffs_len, idata->VirtualAddress, NULL); if (idd) for (i = 0; idd[i].Attributes.AllAttributes || idd[i].DllNameRVA || idd[i].ModuleHandleRVA || idd[i].ImportAddressTableRVA || idd[i].ImportNameTableRVA || idd[i].BoundImportAddressTableRVA || idd[i].UnloadInformationTableRVA || idd[i].TimeDateStamp; i++) { struct DepTreeElement *dll; uint64_t impaddress; dll = ProcessDep (cfg, soffs, soffs_len, idd[i].DllNameRVA, root, self, 0); if (dll == NULL) continue; if (idd[i].Attributes.AllAttributes & 0x00000001) { ith = (void *) MapPointer (soffs, soffs_len, idd[i].ImportAddressTableRVA, NULL); oith = (void *) MapPointer (soffs, soffs_len, idd[i].ImportNameTableRVA, NULL); } else { ith = (void *) idd[i].ImportAddressTableRVA; oith = (void *) idd[i].ImportNameTableRVA; } for (j = 0; (impaddress = thunk_data_u1_function (ith, j, cfg)) != 0; j++) { struct ImportTableItem *imp = AddImport (self); imp->dll = dll; imp->ordinal = -1; if (oith) imp->orig_address = thunk_data_u1_function (oith, j, cfg); if (cfg->on_self) { imp->address = impaddress; } if (oith && imp->orig_address & (1 << (sizeof (DWORD) * 8 - 1))) { imp->ordinal = imp->orig_address & ~(1 << (sizeof (DWORD) * 8 - 1)); } else if (oith) { IMAGE_IMPORT_BY_NAME *byname = (IMAGE_IMPORT_BY_NAME *) MapPointer (soffs, soffs_len, imp->orig_address, NULL); if (byname != NULL) imp->name = strdup ((char *) byname->Name); } } } } idata = opt_header_get_dd_entry (opt_header, IMAGE_DIRECTORY_ENTRY_IMPORT, cfg); if (idata->Size > 0 && idata->VirtualAddress != 0) { iid = (IMAGE_IMPORT_DESCRIPTOR *) MapPointer (soffs, soffs_len, idata->VirtualAddress, NULL); if (iid) for (i = 0; iid[i].Characteristics || iid[i].TimeDateStamp || iid[i].ForwarderChain || iid[i].Name || iid[i].FirstThunk; i++) ProcessDep (cfg, soffs, soffs_len, iid[i].Name, root, self, 1); } idata = opt_header_get_dd_entry (opt_header, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, cfg); if (idata->Size > 0 && idata->VirtualAddress != 0) { idd = (IMAGE_DELAYLOAD_DESCRIPTOR *) MapPointer (soffs, soffs_len, idata->VirtualAddress, NULL); if (idd) for (i = 0; idd[i].Attributes.AllAttributes || idd[i].DllNameRVA || idd[i].ModuleHandleRVA || idd[i].ImportAddressTableRVA || idd[i].ImportNameTableRVA || idd[i].BoundImportAddressTableRVA || idd[i].UnloadInformationTableRVA || idd[i].TimeDateStamp; i++) ProcessDep (cfg, soffs, soffs_len, idd[i].DllNameRVA, root, self, 1); } }