struct PE_get_imports_info* PE_get_imports_info_deep_copy(struct PE_get_imports_info *i) { struct PE_get_imports_info *rt; rt=DMEMDUP (i, sizeof(struct PE_get_imports_info), "struct PE_get_imports_info"); for (int d=0; d < rt->import_descriptors_t; d++) { struct PE_get_imports_DLL_info* DLL_d=rt->dlls + d; struct PE_get_imports_DLL_info* DLL_s=i->dlls + d; DLL_d->DLL_name=DSTRDUP (DLL_s->DLL_name, "char*"); DLL_d->symbols_t=DLL_s->symbols_t; DLL_d->symbols=DCALLOC(char*, DLL_s->symbols_t, "char*"); for (int s=0; s<DLL_d->symbols_t; s++) { DLL_d->symbols[s]=DSTRDUP(DLL_s->symbols[s], "char*"); DLL_d->hints[s]=DLL_s->hints[s]; // can be optimized; }; DLL_d->allocate_thunks=DLL_s->allocate_thunks; }; return rt; };
int main() { #if __WORDSIZE==64 oassert(strtol_or_strtoll("0xAB12345678", NULL, 16)==0xAB12345678); #else oassert(strtol_or_strtoll("0x12345678", NULL, 16)==0x12345678); #endif const char* strings[]={"string1", "hello", "world", "another string"}; size_t strings_t=sizeof(strings)/sizeof(char*); printf ("%d\n", find_string_in_array_of_strings("another string", strings, strings_t, false, false)); printf ("%d\n", find_string_in_array_of_strings("world", strings, strings_t, true, false)); printf ("%d\n", find_string_in_array_of_strings("Hello", strings, strings_t, true, false)); printf ("%d\n", find_string_in_array_of_strings("world2", strings, strings_t, true, false)); printf ("%d\n", find_string_in_array_of_strings("World", strings, strings_t, false, false)); oassert (string_is_ends_with ("hello", "lo")==true); oassert (string_is_ends_with ("hello", "lo1")==false); oassert (str_common_prefix_len("asd", "das")==0); oassert (str_common_prefix_len(" & Her Lover", " Cook, the Thief, His Wife & Her Lover")==1); oassert (str_common_prefix_len("asd", "as2")==2); oassert (str_common_prefix_len("asd", "as")==2); oassert (str_common_prefix_len("asd", "asd")==3); oassert (str_common_prefix_len("asd", "abb")==1); char *buf=DSTRDUP("hello world","buf"); string_remove_part (buf, 0, 4); // "hello" string_remove_part (buf, 0, 0); // " " oassert (strcmp (buf, "world")==0); DFREE(buf); buf=DSTRDUP(" ","buf"); string_remove_part (buf, 0, 0); // " " oassert (strcmp (buf, "")==0); DFREE(buf); buf=DSTRDUP("asdfg","buf"); string_remove_part (buf, 4, 4); string_remove_part (buf, 0, 0); oassert (strcmp (buf, "sdf")==0); DFREE(buf); oassert(is_string_consists_only_of_Latin_letters("abcdef")==true); oassert(is_string_consists_only_of_Latin_letters("abcd1ef")==false); oassert(is_string_has_only_one_character_repeating("111111111", NULL)==true); oassert(is_string_has_only_one_character_repeating("1111111112", NULL)==false); char* tmp=dmalloc_and_snprintf ("%d %d", 123, 456); oassert(streq(tmp, "123 456")); DFREE(tmp); tmp=dmalloc_and_snprintf ("%" PRIx64 " %d", 0x1234567890ABCDEF, 456); oassert(streq(tmp, "1234567890abcdef 456")); DFREE(tmp); dump_unfreed_blocks(); };
struct PE_get_imports_info* PE_get_imports (LOADED_IMAGE *im) { struct PE_get_imports_info* rt=DMALLOC(struct PE_get_imports_info, 1, "struct PE_get_imports_info"); bool PE32_plus=PE_is_PE32(im); rt->start_RVA=PE_get_import_descriptor_RVA(im, PE32_plus); IMAGE_IMPORT_DESCRIPTOR* import_dir=PE_get_import_descriptor(im, PE32_plus); if (import_dir==NULL) { free(rt); return NULL; // No imports }; rt->import_descriptors_t=PE_count_import_descriptors (im); rt->dlls=DMALLOC(struct PE_get_imports_DLL_info, rt->import_descriptors_t, "struct PE_get_imports_DLL_info"); int j; IMAGE_IMPORT_DESCRIPTOR *i; for (i=import_dir, j=0; i->OriginalFirstThunk; i++, j++) { address* OriginalFirstThunk_a=(address*)ImageRvaToVa (im->FileHeader, im->MappedAddress, i->OriginalFirstThunk, NULL); char* name=(char*)ImageRvaToVa (im->FileHeader, im->MappedAddress, i->Name, NULL); struct PE_get_imports_DLL_info* DLL=rt->dlls+j; DLL->DLL_name=DSTRDUP(name,"char*"); DLL->FirstThunk=i->FirstThunk; DLL->allocate_thunks=false; DLL->symbols_t=NULL_terminated_array_of_pointers_size((void**)OriginalFirstThunk_a); DLL->symbols=DMALLOC(char*, DLL->symbols_t, "char*"); DLL->hints=DMALLOC(wyde, DLL->symbols_t, "wyde"); for (address *s=OriginalFirstThunk_a, si=0; *s; s++, si++) { if (IS_SET(*s, REG_MSB)) { DLL->hints[si]=(*s)&0xFFFF; DLL->symbols[si]=NULL; } else { byte *tmp=(byte*)ImageRvaToVa(im->FileHeader, im->MappedAddress, *s, NULL); DLL->hints[si]=*(wyde*)tmp; DLL->symbols[si]=DSTRDUP ((char*)(tmp+2), "symbol name"); }; }; }; return rt; };
static symbol *create_symbol (symbol_type t, char *n) { symbol *rt=DCALLOC (symbol, 1, "symbol"); rt->t=t; rt->skip_on_tracing=Fuzzy_Undefined; rt->name=DSTRDUP(n, "name"); return rt; };
void add_DLL_and_symbol_to_imports (struct PE_get_imports_info *i, char *dll, char *symname, wyde hint) { int DLL_idx=find_dll_in_imports(i, dll); if (DLL_idx==-1) { // add new DLL to the table DLL_idx=i->import_descriptors_t; i->import_descriptors_t++; i->dlls=DREALLOC (i->dlls, struct PE_get_imports_DLL_info, i->import_descriptors_t, "struct PE_get_imports_DLL_info"); struct PE_get_imports_DLL_info *DLL=i->dlls + DLL_idx; bzero(DLL, sizeof(struct PE_get_imports_DLL_info)); DLL->DLL_name=DSTRDUP(dll, "DLL name"); DLL->allocate_thunks=true; // FirstThunk is NULL here };
// replace %substring% to environment variable, if possible void env_vars_expansion(strbuf *sb, char** env) { oassert(env!=NULL); for (int i=0; env[i]; i++) { char *s=DSTRDUP (env[i], "env"); char *s1=strtok (s, "="); char *s2=strtok (NULL, "="); strbuf percented_env_var=STRBUF_INIT; strbuf_addc (&percented_env_var, '%'); strbuf_addstr (&percented_env_var, s1); strbuf_addc (&percented_env_var, '%'); strbuf_replace_if_possible (sb, percented_env_var.buf, s2); strbuf_deinit(&percented_env_var); DFREE(s); }; };
if (DLL_idx==-1) { // add new DLL to the table DLL_idx=i->import_descriptors_t; i->import_descriptors_t++; i->dlls=DREALLOC (i->dlls, struct PE_get_imports_DLL_info, i->import_descriptors_t, "struct PE_get_imports_DLL_info"); struct PE_get_imports_DLL_info *DLL=i->dlls + DLL_idx; bzero(DLL, sizeof(struct PE_get_imports_DLL_info)); DLL->DLL_name=DSTRDUP(dll, "DLL name"); DLL->allocate_thunks=true; // FirstThunk is NULL here }; struct PE_get_imports_DLL_info *DLL=i->dlls + DLL_idx; DLL->symbols=DREALLOC (DLL->symbols, char*, DLL->symbols_t+1, "char*"); DLL->hints=DREALLOC (DLL->hints, wyde, DLL->symbols_t+1, "wyde"); DLL->symbols[DLL->symbols_t]=DSTRDUP(symname, "char*"); DLL->hints[DLL->symbols_t]=hint; DLL->symbols_t++; }; address PE_find_thunk_by_import (struct PE_get_imports_info *i, char* dll_name, char* sym_name) { int DLL_no=find_dll_in_imports (i, dll_name); oassert(DLL_no!=-1); oassert(DLL_no < i->import_descriptors_t); struct PE_get_imports_DLL_info* DLL=i->dlls + DLL_no; for (unsigned s=0; s<DLL->symbols_t; s++) if (stricmp(DLL->symbols[s], sym_name)==0) return i->dlls[DLL_no].FirstThunk + s*sizeof(address);