void MicrosoftSTL::init(Process* self) { p = self; OffsetGroup * strGrp = p->getDescriptor()->getGroup("string")->getGroup("MSVC"); STLSTR_buf_off = strGrp->getOffset("buffer"); STLSTR_size_off = strGrp->getOffset("size"); STLSTR_cap_off = strGrp->getOffset("capacity"); }
std::string OffsetGroup::getFullName() { string temp, accum; OffsetGroup * curr = this; while(curr) { temp = curr->getName() + string("/") + accum; accum = temp; curr = curr->getParent(); } return accum; }
void OffsetGroup::copy(const OffsetGroup * old) { OGd->addresses = old->OGd->addresses; OGd->offsets = old->OGd->offsets; OGd->hexvals = old->OGd->hexvals; OGd->strings = old->OGd->strings; for(groups_Iter it = old->OGd->groups.begin(); it != old->OGd->groups.end(); it++) { OffsetGroup * ogn = new OffsetGroup((*it).first, this); ogn->copy((*it).second); OGd->groups[(*it).first] = ogn; } }
bool Translation::InitReadNames() { Core & c = Core::getInstance(); try { OffsetGroup * OG = c.vinfo->getGroup("name"); d->name_firstname_offset = OG->getOffset("first"); d->name_nickname_offset = OG->getOffset("nick"); d->name_words_offset = OG->getOffset("second_words"); d->name_parts_offset = OG->getOffset("parts_of_speech"); d->name_language_offset = OG->getOffset("language"); d->name_set_offset = OG->getOffset("has_name"); } catch(exception &) { d->namesFailed = true; return false; } d->namesInited = true; return true; }
void VersionInfoFactory::ParseOffsets(TiXmlElement * parent, VersionInfo* target, bool initial) { // we parse the groups iteratively instead of recursively // breadcrubs acts like a makeshift stack // first pair entry stores the current element of that level // second pair entry the group object from OffsetGroup typedef triple< TiXmlElement *, OffsetGroup *, INVAL_TYPE> groupTriple; vector< groupTriple > breadcrumbs; { TiXmlElement* pEntry; // we get the <Offsets>, look at the children pEntry = parent->FirstChildElement(); if(!pEntry) return; const char *cstr_invalid = parent->Attribute("valid"); INVAL_TYPE parent_inval = NOT_SET; if(cstr_invalid) { if(strcmp(cstr_invalid,"false") == 0) parent_inval = IS_INVALID; else if(strcmp(cstr_invalid,"true") == 0) parent_inval = IS_VALID; } OffsetGroup * currentGroup = reinterpret_cast<OffsetGroup *> (target); currentGroup->setInvalid(parent_inval); breadcrumbs.push_back(groupTriple(pEntry,currentGroup, parent_inval)); } // work variables OffsetGroup * currentGroup = 0; TiXmlElement * currentElem = 0; INVAL_TYPE parent_inval = NOT_SET; //cerr << "<Offsets>"<< endl; while(1) { // get current work variables currentElem = breadcrumbs.back().first; currentGroup = breadcrumbs.back().second; parent_inval = breadcrumbs.back().third; // we reached the end of the current group? if(!currentElem) { // go one level up breadcrumbs.pop_back(); // exit if no more work if(breadcrumbs.empty()) { break; } else { //cerr << "</group>" << endl; continue; } } if(!currentGroup) { groupTriple & gp = breadcrumbs.back(); gp.first = gp.first->NextSiblingElement(); continue; } // skip non-elements if (currentElem->Type() != TiXmlNode::ELEMENT) { groupTriple & gp = breadcrumbs.back(); gp.first = gp.first->NextSiblingElement(); continue; } // we have a valid current element and current group // get properties string type = currentElem->Value(); std::transform(type.begin(), type.end(), type.begin(), ::tolower); const char *cstr_name = currentElem->Attribute("name"); if(!cstr_name) { // ERROR, missing attribute } // evaluate elements const char *cstr_value = currentElem->Attribute("value"); const char *cstr_invalid = currentElem->Attribute("valid"); INVAL_TYPE child_inval = parent_inval; if(cstr_invalid) { if(strcmp(cstr_invalid,"false") == 0) child_inval = IS_INVALID; else if(strcmp(cstr_invalid,"true") == 0) child_inval = IS_VALID; } if(type == "group") { // create or get group OffsetGroup * og; if(initial) og = currentGroup->createGroup(cstr_name); else og = currentGroup->getGroup(cstr_name); // advance this level to the next element groupTriple & gp = breadcrumbs.back(); gp.first = currentElem->NextSiblingElement(); if(!og) { string fullname = currentGroup->getFullName() + cstr_name; throw Error::MissingMemoryDefinition("group", fullname); } // add a new level that will be processed in the next step breadcrumbs.push_back(groupTriple(currentElem->FirstChildElement(), og, child_inval)); og->setInvalid(child_inval); continue; } else if(type == "address") { if(child_inval == NOT_SET) child_inval = IS_VALID; if(initial) { currentGroup->createAddress(cstr_name); } else if(cstr_value) { currentGroup->setAddress(cstr_name, cstr_value, child_inval); } else { currentGroup->setAddressValidity(cstr_name, child_inval); } } else if(type == "offset") { if(child_inval == NOT_SET) child_inval = IS_VALID; if(initial) { currentGroup->createOffset(cstr_name); } else if(cstr_value) { currentGroup->setOffset(cstr_name, cstr_value, child_inval); } else { currentGroup->setOffsetValidity(cstr_name, child_inval); } } else if(type == "string") { if(child_inval == NOT_SET) child_inval = IS_VALID; if(initial) { currentGroup->createString(cstr_name); } else if(cstr_value) { currentGroup->setString(cstr_name, cstr_value, child_inval); } else { currentGroup->setStringValidity(cstr_name, child_inval); } } else if(type == "hexvalue") { if(child_inval == NOT_SET) child_inval = IS_VALID; if(initial) { currentGroup->createHexValue(cstr_name); } else if(cstr_value) { currentGroup->setHexValue(cstr_name, cstr_value, child_inval); } else { currentGroup->setHexValueValidity(cstr_name, child_inval); } } // advance to next element groupTriple & gp = breadcrumbs.back(); gp.first = currentElem->NextSiblingElement(); continue; } //cerr << "</Offsets>"<< endl; }
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); } }