bool SHMProcess::Private::validate(vector <VersionInfo *> & known_versions) { // try to identify the DF version IMAGE_NT_HEADERS32 pe_header; IMAGE_SECTION_HEADER sections[16]; HMODULE hmod = NULL; DWORD junk; HANDLE hProcess; bool found = false; identified = false; // open process, we only need the process open hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, process_ID ); if (NULL == hProcess) return false; // try getting the first module of the process if(EnumProcessModules(hProcess, &hmod, 1 * sizeof(HMODULE), &junk) == 0) { CloseHandle(hProcess); // cout << "EnumProcessModules fail'd" << endl; return false; } // got base ;) uint32_t base = (uint32_t)hmod; // read from this process uint32_t pe_offset = self->readDWord(base+0x3C); self->read(base + pe_offset , sizeof(pe_header), (uint8_t *)&pe_header); self->read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)§ions ); // iterate over the list of memory locations vector<VersionInfo *>::iterator it; for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { uint32_t pe_timestamp; try { pe_timestamp = (*it)->getPE(); } catch(Error::MissingMemoryDefinition&) { continue; } if (pe_timestamp == pe_header.FileHeader.TimeDateStamp) { VersionInfo *m = new VersionInfo(**it); m->RebaseAll(base); memdescriptor = m; m->setParentProcess(self); identified = true; cerr << "identified " << m->getVersion() << endl; CloseHandle(hProcess); return true; } } return false; }
bool SHMProcess::Private::validate(vector <VersionInfo *> & known_versions) { char exe_link_name [256]; char target_name[1024]; int target_result; // find the binary sprintf(exe_link_name,"/proc/%d/exe", process_ID); target_result = readlink(exe_link_name, target_name, sizeof(target_name)-1); if (target_result == -1) { perror("readlink"); return false; } // make sure we have a null terminated string... // see http://www.opengroup.org/onlinepubs/000095399/functions/readlink.html target_name[target_result] = 0; md5wrapper md5; // get hash of the running DF process string hash = md5.getHashFromFile(target_name); vector<VersionInfo *>::iterator it; // cerr << exe_file << " " << hash << endl; // iterate over the list of memory locations for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { try { if(hash == (*it)->getMD5()) // are the md5 hashes the same? { VersionInfo *m = new VersionInfo(**it); memdescriptor = m; m->setParentProcess(dynamic_cast<Process *>( self )); identified = true; // cerr << "identified " << m->getVersion() << endl; return true; } } catch (Error::AllMemdef&) { continue; } } return false; }
NormalProcess::NormalProcess(uint32_t pid, vector <VersionInfo *> & known_versions) : d(new Private()) { HMODULE hmod = NULL; DWORD junk; HANDLE hProcess; bool found = false; IMAGE_NT_HEADERS32 pe_header; IMAGE_SECTION_HEADER sections[16]; d->identified = false; // open process hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid ); if (NULL == hProcess) return; // try getting the first module of the process if(EnumProcessModules(hProcess, &hmod, 1 * sizeof(HMODULE), &junk) == 0) { CloseHandle(hProcess); // cout << "EnumProcessModules fail'd" << endl; return; //if enumprocessModules fails, give up } // got base ;) uint32_t base = (uint32_t)hmod; // temporarily assign this to allow some checks d->my_handle = hProcess; d->my_main_thread = 0; // read from this process try { uint32_t pe_offset = readDWord(base+0x3C); read(base + pe_offset , sizeof(pe_header), (uint8_t *)&pe_header); read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)§ions ); d->my_handle = 0; } catch (exception &) { CloseHandle(hProcess); d->my_handle = 0; return; } // see if there's a version entry that matches this process vector<VersionInfo*>::iterator it; for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { // filter by OS if(VersionInfo::OS_WINDOWS != (*it)->getOS()) continue; uint32_t pe_timestamp; // filter by timestamp, skip entries without a timestamp try { pe_timestamp = (*it)->getPE(); } catch(Error::MissingMemoryDefinition&) { continue; } if (pe_timestamp != pe_header.FileHeader.TimeDateStamp) continue; // all went well { printf("Match found! Using version %s.\n", (*it)->getVersion().c_str()); d->identified = true; // give the process a data model and memory layout fixed for the base of first module VersionInfo *m = new VersionInfo(**it); m->RebaseAll(base); // keep track of created memory_info object so we can destroy it later d->my_descriptor = m; m->setParentProcess(this); // process is responsible for destroying its data model d->my_pid = pid; d->my_handle = hProcess; d->identified = true; // TODO: detect errors in thread enumeration vector<uint32_t> threads; getThreadIDs( threads ); d->my_main_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads[0]); OffsetGroup * strGrp = m->getGroup("string")->getGroup("MSVC"); d->STLSTR_buf_off = strGrp->getOffset("buffer"); d->STLSTR_size_off = strGrp->getOffset("size"); d->STLSTR_cap_off = strGrp->getOffset("capacity"); found = true; break; // break the iterator loop } } // close handle of processes that aren't DF if(!found) { CloseHandle(hProcess); } }