void *do_search(void *thread_id) { int tid; int cur_queue = count_dirlist(); int position = -1; tid = *((int *) thread_id); printf("Thread %d started with %d dirs in queue...\n", tid, cur_queue); while(cur_queue != 0) { // Catch a lock do { position = read_dirlist(); } while (position < 0 && count_dirlist() != 0); if(position < 0) break; char *path = dirlist[position]; if(path != NULL) { build_dirlist(path); printf("do_search: Thread %d found a new path: %s\n", tid, path); find_in_dir(path); del_dir(path); } if(position >= 0) pthread_mutex_unlock(&dirlist_acc[position]); cur_queue = count_dirlist(); } printf("do_search: Directory list is empty. Thread %d terminates.\n", tid); return NULL; }
// Fill the array of icons for uninstall with their offsets // Returns 0 if failed, anything else is icon_offset. int generate_unicons_offsets(unsigned char* exeHeader, unsigned char* uninstIconData) { int i; MY_ASSERT(PIMAGE_DOS_HEADER(exeHeader)->e_magic != IMAGE_DOS_SIGNATURE, "invalid dos header"); PIMAGE_NT_HEADERS ntHeaders = PIMAGE_NT_HEADERS(exeHeader + PIMAGE_DOS_HEADER(exeHeader)->e_lfanew); MY_ASSERT(ntHeaders->Signature != IMAGE_NT_SIGNATURE, "invalid nt headers"); DWORD dwResourceSectionVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(ntHeaders); for (i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) if (dwResourceSectionVA == sectionHeadersArray[i].VirtualAddress) break; MY_ASSERT(i == ntHeaders->FileHeader.NumberOfSections, "can't find resource section"); PRESOURCE_DIRECTORY rdRoot = PRESOURCE_DIRECTORY(exeHeader + sectionHeadersArray[i].PointerToRawData); int iNextSection; if (i == ntHeaders->FileHeader.NumberOfSections - 1) iNextSection = (int)ntHeaders->OptionalHeader.SizeOfImage; else iNextSection = (int)sectionHeadersArray[i+1].PointerToRawData; MY_ASSERT((int)rdRoot - (int)exeHeader > iNextSection, "corrupted EXE - invalid pointer"); int idx = find_in_dir(rdRoot, WORD(RT_ICON)); MY_ASSERT(idx == -1, "no icons?!"); MY_ASSERT(!rdRoot->Entries[idx].DataIsDirectory, "bad resource directory"); PRESOURCE_DIRECTORY rdIcons = PRESOURCE_DIRECTORY(rdRoot->Entries[idx].OffsetToDirectory + DWORD(rdRoot)); MY_ASSERT((int)rdIcons - (int)exeHeader > iNextSection, "corrupted EXE - invalid pointer"); unsigned char* seeker = uninstIconData; for (i = 0; i < rdIcons->Header.NumberOfIdEntries; i++) { // Icons dir can't have named entries MY_ASSERT(!rdIcons->Entries[i].DataIsDirectory, "bad resource directory"); PRESOURCE_DIRECTORY rd = PRESOURCE_DIRECTORY(rdIcons->Entries[i].OffsetToDirectory + DWORD(rdRoot)); MY_ASSERT((int)rd - (int)exeHeader > iNextSection, "corrupted EXE - invalid pointer"); MY_ASSERT(rd->Entries[0].DataIsDirectory, "bad resource directory"); PIMAGE_RESOURCE_DATA_ENTRY rde = PIMAGE_RESOURCE_DATA_ENTRY(rd->Entries[0].OffsetToData + DWORD(rdRoot)); MY_ASSERT((int)rde - (int)exeHeader > iNextSection, "corrupted EXE - invalid pointer"); DWORD dwSize = *(DWORD*)seeker; seeker += sizeof(DWORD); MY_ASSERT(dwSize != rde->Size, "installer, uninstaller icon size mismatch - see the Icon instruction's documentation for more information"); // Set offset *(DWORD*)seeker = rde->OffsetToData + DWORD(rdRoot) - dwResourceSectionVA - DWORD(exeHeader); MY_ASSERT(*(int*)seeker > iNextSection || *(int*)seeker < (int)rdRoot - (int)exeHeader, "invalid data offset - icon resource probably compressed"); seeker += sizeof(DWORD) + dwSize; } MY_ASSERT(i == 0, "no icons found"); MY_ASSERT(*(DWORD*)seeker != 0, "number of icons doesn't match"); return PIMAGE_RESOURCE_DATA_ENTRY(PRESOURCE_DIRECTORY(rdIcons->Entries[0].OffsetToDirectory + DWORD(rdRoot))->Entries[0].OffsetToData + DWORD(rdRoot))->OffsetToData + DWORD(rdRoot) - dwResourceSectionVA - DWORD(exeHeader); }