Gui::Gui(DFContextShared * _d) { d = new Private; d->d = _d; d->owner = _d->p; VersionInfo * mem = d->d->offset_descriptor; OffsetGroup * OG_Gui = mem->getGroup("GUI"); try { d->current_menu_state_offset = OG_Gui->getAddress("current_menu_state"); d->MenuStateInited = true; } catch(exception &){}; try { d->view_screen_offset = OG_Gui->getAddress ("view_screen"); d->ViewScreeInited = true; } catch(exception &){}; OffsetGroup * OG_Position; try { OG_Position = mem->getGroup("Position"); d->window_x_offset = OG_Position->getAddress ("window_x"); d->window_y_offset = OG_Position->getAddress ("window_y"); d->window_z_offset = OG_Position->getAddress ("window_z"); d->cursor_xyz_offset = OG_Position->getAddress ("cursor_xyz"); d->window_dims_offset = OG_Position->getAddress ("window_dims"); d->Started = true; } catch(Error::All &){}; try { OffsetGroup * OG_Hotkeys = mem->getGroup("Hotkeys"); d->hotkey_start = OG_Hotkeys->getAddress("start"); d->hotkey_mode_offset = OG_Hotkeys->getOffset ("mode"); d->hotkey_xyz_offset = OG_Hotkeys->getOffset("coords"); d->hotkey_size = OG_Hotkeys->getHexValue("size"); d->StartedHotkeys = true; } catch(Error::All &){}; try { d->screen_tiles_ptr_offset = OG_Position->getAddress ("screen_tiles_pointer"); d->StartedScreen = true; } catch(Error::All &){}; }
Constructions::Constructions(DFContextShared * d_) { d = new Private; d->d = d_; d->owner = d_->p; d->p_cons = 0; d->Inited = d->Started = false; VersionInfo * mem = d->d->offset_descriptor; d->construction_vector = mem->getGroup("Constructions")->getAddress ("vector"); d->Inited = true; }
Engravings::Engravings(DFContextShared * d_) { d = new Private; d->d = d_; d->owner = d_->p; d->p_engr = 0; d->Inited = d->Started = false; VersionInfo * mem = d->d->offset_descriptor; d->engraving_vector = mem->getGroup("Engravings")->getAddress ("vector"); d->Inited = true; }
Units::Units() { Core & c = Core::getInstance(); d = new Private; d->owner = c.p; VersionInfo * minfo = c.vinfo; d->Inited = false; d->Started = false; d->IdMapReady = false; d->trans = c.getTranslation(); d->trans->InitReadNames(); // FIXME: throws on error OffsetGroup *OG_Creatures = minfo->getGroup("Creatures"); creatures = 0; try { creatures = (vector <df_unit *> *) OG_Creatures->getAddress ("vector"); d->dwarf_race_index_addr = (void *) OG_Creatures->getAddress("current_race"); d->dwarf_civ_id_addr = (void *) OG_Creatures->getAddress("current_civ"); } catch(Error::All&){}; d->Inited = true; }
bool Materials::ReadCreatureTypesEx (void) { Process *p = d->owner; VersionInfo *mem = p->getDescriptor(); OffsetGroup * OG_string = mem->getGroup("string"); uint32_t sizeof_string = OG_string->getHexValue ("sizeof"); OffsetGroup * OG_Mats = mem->getGroup("Materials"); DfVector <uint32_t> p_races (OG_Mats->getAddress ("creature_type_vector")); OffsetGroup * OG_Creature = OG_Mats->getGroup("creature"); uint32_t castes_vector_offset = OG_Creature->getOffset ("caste_vector"); uint32_t extract_vector_offset = OG_Creature->getOffset ("extract_vector"); uint32_t tile_offset = OG_Creature->getOffset ("tile"); uint32_t tile_color_offset = OG_Creature->getOffset ("tile_color"); bool have_advanced = false; uint32_t caste_colormod_offset; uint32_t caste_attributes_offset; uint32_t caste_bodypart_offset; uint32_t bodypart_id_offset; uint32_t bodypart_category_offset; uint32_t color_modifier_part_offset; uint32_t color_modifier_startdate_offset; uint32_t color_modifier_enddate_offset; try { OffsetGroup * OG_Caste = OG_Creature->getGroup("caste"); caste_colormod_offset = OG_Caste->getOffset ("color_modifiers"); caste_attributes_offset = OG_Caste->getOffset ("attributes"); caste_bodypart_offset = OG_Caste->getOffset ("bodypart_vector"); OffsetGroup * OG_CasteBodyparts = OG_Creature->getGroup("caste_bodyparts"); bodypart_id_offset = OG_CasteBodyparts->getOffset ("id"); bodypart_category_offset = OG_CasteBodyparts->getOffset ("category"); OffsetGroup * OG_CasteColorMods = OG_Creature->getGroup("caste_color_mods"); color_modifier_part_offset = OG_CasteColorMods->getOffset ("part"); color_modifier_startdate_offset = OG_CasteColorMods->getOffset ("startdate"); color_modifier_enddate_offset = OG_CasteColorMods->getOffset ("enddate"); have_advanced = true; } catch (Error::All &){}; uint32_t size = p_races.size(); uint32_t sizecas = 0; uint32_t sizecolormod; uint32_t sizecolorlist; uint32_t sizebp; raceEx.clear(); raceEx.reserve (size); for (uint32_t i = 0; i < size;i++) { t_creaturetype mat; mat.id = p->readSTLString (p_races[i]); mat.tile_character = p->readByte( p_races[i] + tile_offset ); mat.tilecolor.fore = p->readWord( p_races[i] + tile_color_offset ); mat.tilecolor.back = p->readWord( p_races[i] + tile_color_offset + 2 ); mat.tilecolor.bright = p->readWord( p_races[i] + tile_color_offset + 4 ); DfVector <uint32_t> p_castes(p_races[i] + castes_vector_offset); sizecas = p_castes.size(); for (uint32_t j = 0; j < sizecas;j++) { /* caste name */ t_creaturecaste caste; uint32_t caste_start = p_castes[j]; caste.id = p->readSTLString (caste_start); caste.singular = p->readSTLString (caste_start + sizeof_string); caste.plural = p->readSTLString (caste_start + 2 * sizeof_string); caste.adjective = p->readSTLString (caste_start + 3 * sizeof_string); //cout << "Caste " << caste.rawname << " " << caste.singular << ": 0x" << hex << caste_start << endl; if(have_advanced) { /* color mod reading */ // Caste + offset > color mod vector DfVector <uint32_t> p_colormod(caste_start + caste_colormod_offset); sizecolormod = p_colormod.size(); caste.ColorModifier.resize(sizecolormod); for(uint32_t k = 0; k < sizecolormod;k++) { // color mod [0] -> color list DfVector <uint32_t> p_colorlist(p_colormod[k]); sizecolorlist = p_colorlist.size(); caste.ColorModifier[k].colorlist.resize(sizecolorlist); for(uint32_t l = 0; l < sizecolorlist; l++) caste.ColorModifier[k].colorlist[l] = p_colorlist[l]; // color mod [color_modifier_part_offset] = string part caste.ColorModifier[k].part = p->readSTLString( p_colormod[k] + color_modifier_part_offset); caste.ColorModifier[k].startdate = p->readDWord( p_colormod[k] + color_modifier_startdate_offset ); caste.ColorModifier[k].enddate = p->readDWord( p_colormod[k] + color_modifier_enddate_offset ); } /* body parts */ DfVector <uint32_t> p_bodypart(caste_start + caste_bodypart_offset); caste.bodypart.empty(); sizebp = p_bodypart.size(); for(uint32_t k = 0; k < sizebp; k++) { t_bodypart part; part.id = p->readSTLString (p_bodypart[k] + bodypart_id_offset); part.category = p->readSTLString (p_bodypart[k] + bodypart_category_offset); caste.bodypart.push_back(part); } p->read(caste_start + caste_attributes_offset, sizeof(t_attrib) * NUM_CREAT_ATTRIBS, (uint8_t *)&caste.strength); } else { memset(&caste.strength, 0, sizeof(t_attrib) * NUM_CREAT_ATTRIBS); } mat.castes.push_back(caste); } DfVector <uint32_t> p_extract(p_races[i] + extract_vector_offset); for(uint32_t j = 0; j < p_extract.size(); j++) { t_creatureextract extract; extract.id = p->readSTLString( p_extract[j] ); mat.extract.push_back(extract); } raceEx.push_back(mat); } return true; }
Creatures::Creatures(DFContextShared* _d) { d = new Private; d->d = _d; d->owner = _d->p; d->Inited = false; d->Started = false; d->d->InitReadNames(); // throws on error VersionInfo * minfo = d->d->offset_descriptor; OffsetGroup *OG_Creatures = minfo->getGroup("Creatures"); OffsetGroup *OG_creature = OG_Creatures->getGroup("creature"); OffsetGroup *OG_creature_ex = OG_creature->getGroup("advanced"); OffsetGroup *OG_soul = OG_Creatures->getGroup("soul"); OffsetGroup * OG_name = minfo->getGroup("name"); d->OG_jobs = OG_Creatures->getGroup("job"); d->OG_job_mats = d->OG_jobs->getGroup("material"); d->Ft_basic = d->Ft_advanced = d->Ft_jobs = d->Ft_soul = false; Creatures2010::creature_offsets &creatures = d->creatures; try { // Creatures creatures.vector = OG_Creatures->getAddress ("vector"); d->dwarf_race_index_addr = OG_Creatures->getAddress("current_race"); d->dwarf_civ_id_addr = OG_Creatures->getAddress("current_civ"); // Creatures/creature creatures.name_offset = OG_creature->getOffset ("name"); creatures.custom_profession_offset = OG_creature->getOffset ("custom_profession"); creatures.profession_offset = OG_creature->getOffset ("profession"); creatures.race_offset = OG_creature->getOffset ("race"); creatures.pos_offset = OG_creature->getOffset ("position"); creatures.flags1_offset = OG_creature->getOffset ("flags1"); creatures.flags2_offset = OG_creature->getOffset ("flags2"); creatures.sex_offset = OG_creature->getOffset ("sex"); creatures.caste_offset = OG_creature->getOffset ("caste"); creatures.id_offset = OG_creature->getOffset ("id"); creatures.civ_offset = OG_creature->getOffset ("civ"); // name struct creatures.name_firstname_offset = OG_name->getOffset("first"); creatures.name_nickname_offset = OG_name->getOffset("nick"); creatures.name_words_offset = OG_name->getOffset("second_words"); d->Ft_basic = true; try { creatures.inventory_offset = OG_creature_ex->getOffset("inventory_vector"); creatures.pickup_equipment_bit = OG_creature_ex->getOffset("pickup_equipment_bit"); creatures.mood_offset = OG_creature_ex->getOffset("mood"); // pregnancy // pregnancy_ptr creatures.birth_year_offset = OG_creature_ex->getOffset("birth_year"); creatures.birth_time_offset = OG_creature_ex->getOffset("birth_time"); creatures.current_job_offset = OG_creature_ex->getOffset("current_job"); creatures.mood_skill_offset = OG_creature_ex->getOffset("current_job_skill"); creatures.physical_offset = OG_creature_ex->getOffset("physical"); creatures.appearance_vector_offset = OG_creature_ex->getOffset("appearance_vector"); creatures.artifact_name_offset = OG_creature_ex->getOffset("artifact_name"); creatures.labors_offset = OG_creature_ex->getOffset ("labors"); creatures.happiness_offset = OG_creature_ex->getOffset ("happiness"); d->Ft_advanced = true; } catch(Error::All&) {}; try { creatures.soul_vector_offset = OG_creature_ex->getOffset("soul_vector"); creatures.default_soul_offset = OG_creature_ex->getOffset("current_soul"); creatures.soul_mental_offset = OG_soul->getOffset("mental"); creatures.soul_skills_vector_offset = OG_soul->getOffset("skills_vector"); creatures.soul_traits_offset = OG_soul->getOffset("traits"); d->Ft_soul = true; } catch(Error::All&) {}; } catch(Error::All&) {}; d->Inited = true; }
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); } }