diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp index cd96b3e54..ce1916e54 100644 --- a/library/DFProcess-linux-wine.cpp +++ b/library/DFProcess-linux-wine.cpp @@ -147,7 +147,7 @@ bool WineProcess::Private::validate(char* exe_file, uint32_t pid, char* mem_file continue; } // are the md5 hashes the same? - if(VersionInfo::OS_WINDOWS == (*it)->getOS() && hash == thishash) + if(OS_WINDOWS == (*it)->getOS() && hash == thishash) { // keep track of created memory_info object so we can destroy it later diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp index 431dee508..7d82aa851 100644 --- a/library/DFProcess-linux.cpp +++ b/library/DFProcess-linux.cpp @@ -124,7 +124,7 @@ bool NormalProcess::Private::validate(char * exe_file,uint32_t pid, char * memFi if(hash == (*it)->getMD5()) // are the md5 hashes the same? { VersionInfo * m = *it; - if (VersionInfo::OS_LINUX == m->getOS()) + if (OS_LINUX == m->getOS()) { VersionInfo *m2 = new VersionInfo(*m); my_descriptor = m2; diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp index b9f3fd86e..6625669d5 100644 --- a/library/DFProcess-windows.cpp +++ b/library/DFProcess-windows.cpp @@ -103,7 +103,7 @@ NormalProcess::NormalProcess(uint32_t pid, vector & known_versio for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { // filter by OS - if(VersionInfo::OS_WINDOWS != (*it)->getOS()) + if(OS_WINDOWS != (*it)->getOS()) continue; uint32_t pe_timestamp; // filter by timestamp, skip entries without a timestamp diff --git a/library/VersionInfo.cpp b/library/VersionInfo.cpp index 7773b7470..0569b90f8 100644 --- a/library/VersionInfo.cpp +++ b/library/VersionInfo.cpp @@ -545,7 +545,7 @@ namespace DFHack Process * p; // the process this belongs to string version; - VersionInfo::OSType OS; + OSType OS; std::string md5; uint32_t PE_timestamp; }; @@ -707,7 +707,7 @@ void VersionInfo::setOS(OSType os) } -VersionInfo::OSType VersionInfo::getOS() const +OSType VersionInfo::getOS() const { return d->OS; } diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index d25af91c1..3aa3d924c 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -365,7 +365,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) throw Error::MemoryXmlBadAttribute("name"); mem->setVersion(cstr_version); - mem->setOS(VersionInfo::OS_BAD); + mem->setOS(OS_BAD); // process additional entries pElement = entry->FirstChildElement()->ToElement(); diff --git a/library/include/dfhack/VersionInfo.h b/library/include/dfhack/VersionInfo.h index b5c7dac14..39e838234 100644 --- a/library/include/dfhack/VersionInfo.h +++ b/library/include/dfhack/VersionInfo.h @@ -93,18 +93,18 @@ namespace DFHack /* * Version Info */ + enum OSType + { + OS_WINDOWS, + OS_LINUX, + OS_APPLE, + OS_BAD + }; class DFHACK_EXPORT VersionInfo : public OffsetGroup { private: VersionInfoPrivate * d; public: - enum OSType - { - OS_WINDOWS, - OS_LINUX, - OS_APPLE, - OS_BAD - }; VersionInfo(); VersionInfo(const VersionInfo&); void copy(const DFHack::VersionInfo* old); diff --git a/tools/playground/CMakeLists.txt b/tools/playground/CMakeLists.txt index 291845660..ab1b70165 100644 --- a/tools/playground/CMakeLists.txt +++ b/tools/playground/CMakeLists.txt @@ -24,6 +24,8 @@ TARGET_LINK_LIBRARIES(dfdigger dfhack) ADD_EXECUTABLE(dfdigger2 digger2.cpp) TARGET_LINK_LIBRARIES(dfdigger2 dfhack) +ADD_EXECUTABLE(primitives primitives.cpp) + # itemdesignator - change some item designations (dump, forbid, on-fire) for all # items of a given type and material # Author: belal @@ -33,6 +35,8 @@ TARGET_LINK_LIBRARIES(dfdigger2 dfhack) # incrementalsearch - a bit like cheat engine, only DF-specific, very basic # and Linux-only IF(UNIX) + ADD_EXECUTABLE(dfautosearch autosearch.cpp) + TARGET_LINK_LIBRARIES(dfautosearch dfhack) ADD_EXECUTABLE(dfincremental incrementalsearch.cpp) TARGET_LINK_LIBRARIES(dfincremental dfhack) ENDIF(UNIX) @@ -115,6 +119,7 @@ RUNTIME DESTINATION bin ) IF(UNIX) install(TARGETS + dfautosearch dfincremental RUNTIME DESTINATION bin ) diff --git a/tools/playground/autosearch.cpp b/tools/playground/autosearch.cpp new file mode 100644 index 000000000..1edab9797 --- /dev/null +++ b/tools/playground/autosearch.cpp @@ -0,0 +1,780 @@ +// this is an incremental search tool. It only works on Linux. +// here be dragons... and ugly code :P +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#ifndef LINUX_BUILD + #define WINVER 0x0500 + // this one prevents windows from infecting the global namespace with filth + #define NOMINMAX + #define WIN32_LEAN_AND_MEAN + #include +#endif + +#include +#include "SegmentedFinder.h" +class Token +{ +public: + Token(uint64_t _offset) + { + offset = _offset; + offset_valid = 1; + value_valid = 0; + parent = 0; + } + Token(const std::string & offsetn) + { + full_offset_name = offsetn; + offset_valid = 0; + value_valid = 0; + parent = 0; + } + Token() + { + offset_valid = 0; + value_valid = 0; + parent = 0; + } + virtual ~Token(){}; + virtual bool LoadData(SegmentedFinder * s) = 0; + virtual void EmptyData() + { + value_valid = false; + }; + virtual bool Match(SegmentedFinder * s, uint64_t offset) = 0; + virtual void EmptyOffset() + { + offset_valid = false; + }; + virtual bool AcquireOffset(DFHack::VersionInfo * vinfo) + { + vinfo->getOffset(full_offset_name); + } + virtual uint32_t Length() = 0; + virtual uint64_t getAbsolute(){if(parent) return parent->getAbsolute() + offset; else return offset;}; + void setParent( Token *par ) + { + par = parent; + } +protected: + uint64_t offset;// offset from the start of the parent token + std::string full_offset_name; + Token * parent; + bool offset_valid :1; + bool value_valid :1; +}; + +class Byte: virtual public Token +{ +public: + Byte(uint64_t _offset):Token(_offset){}; + Byte():Token(){}; + ~Byte(); + virtual bool LoadData(SegmentedFinder * s) + { + if(offset_valid) + { + char * ptr = s->Translate(getAbsolute()); + if(ptr) + { + value = *ptr; + value_valid = true; + return true; + } + } + return false; + }; + // is the loaded data same as data at offset? yes -> set our offset to that. + virtual bool Match(SegmentedFinder * s, uint64_t offs) + { + if(value_valid && (*s->Translate(parent->getAbsolute() + offset)) == value ) + { + if(parent) + offset = offs - parent->getAbsolute(); + else + offset = offs; + return true; + } + return false; + }; + virtual uint32_t Length() + { + return 1; + }; +private: + char value; +}; + +class Short: virtual public Token +{ +public: + Short(uint64_t _offset):Token(_offset){}; + Short():Token(){}; + ~Short(); + virtual bool LoadData(SegmentedFinder * s) + { + if(offset_valid) + { + uint16_t * ptr = s->Translate(getAbsolute()); + if(ptr) + { + value = *ptr; + value_valid = true; + return true; + } + } + return false; + }; + // is the loaded data same as data at offset? yes -> set our offset to that. + virtual bool Match(SegmentedFinder * s, uint64_t offs) + { + if(value_valid && (*s->Translate(parent->getAbsolute() + offset)) == value ) + { + if(parent) + offset = offs - parent->getAbsolute(); + else + offset = offs; + return true; + } + return false; + }; + virtual uint32_t Length() + { + return 2; + }; +private: + uint16_t value; +}; + +class Long: virtual public Token +{ +public: + Long(uint64_t _offset):Token(_offset){}; + Long():Token(){}; + ~Long(); + virtual bool LoadData(SegmentedFinder * s) + { + if(offset_valid) + { + uint32_t * ptr = s->Translate(getAbsolute()); + if(ptr) + { + value = *ptr; + value_valid = true; + return true; + } + } + return false; + }; + // is the loaded data same as data at offset? yes -> set our offset to that. + virtual bool Match(SegmentedFinder * s, uint64_t offs) + { + if(value_valid && (*s->Translate(offs)) == value ) + { + if(parent) + offset = offs - parent->getAbsolute(); + else + offset = offs; + return true; + } + return false; + + }; + virtual uint32_t Length(){return 4;}; +private: + uint32_t value; +}; + +class PtrVector : virtual public Token +{ +public: + PtrVector(uint64_t _offset):Token(_offset){}; + PtrVector():Token(){}; + ~PtrVector(); + virtual uint32_t Length(){return 12;}; +private: + vector value; +}; + +class Pointer: virtual public Token +{ +public: + Pointer(uint64_t _offset):Token(_offset){}; + Pointer():Token(){}; + ~Pointer(); + virtual uint32_t Length(){return 4;}; +private: + uint64_t value; +}; + +class String: virtual public Token +{ +protected: + string value; +}; + +class Struct: virtual public Token +{ +public: + Struct(uint64_t _offset):Token(_offset){}; + Struct():Token(){}; + ~Struct(){}; + void Add( Token * t ){members.push_back(t);}; + virtual uint32_t Length(){return 0;}; // FIXME: temporary solution, should be the minimal length of all the contents combined + virtual bool LoadData(SegmentedFinder* s) + { + bool OK = true; + for(int i = 0; i < members.size() && OK; i++) + OK &= members[i]->LoadData(s); + return OK; + }; + // TODO: IMPLEMENT! + virtual bool Match(SegmentedFinder* s, uint64_t offset) + { + return false; + } +private: + vector members; +}; + +class LinuxString: virtual public String +{ +public: + LinuxString(uint64_t _offset):Token(_offset){}; + LinuxString():Token(){}; + ~LinuxString(){}; + virtual uint32_t Length(){return 4;}; + virtual bool LoadData(SegmentedFinder* s) + { + return false; + } + virtual bool Match(SegmentedFinder* s, uint64_t offset) + { + return false; + } + /* + // read string pointer, translate to local scheme + char *str = sf->Translate(*offset); + // verify + if(!str) + return false; + uint32_t length = *(uint32_t *)(offset - 12); + uint32_t capacity = *(uint32_t *)(offset - 8); + if(length > capacity) + return false; + //char * temp = new char[length+1]; + // read data from inside the string structure + //memcpy(temp, str,length + 1); + output = str; + return true; + */ +}; + +class WindowsString: virtual public String +{ +public: + WindowsString(uint64_t _offset):Token(_offset){}; + WindowsString():Token(){}; + ~WindowsString(){}; + virtual uint32_t Length(){return 0x1C;}; // FIXME: pouzivat Memory.xml? + virtual bool LoadData(SegmentedFinder* s) + { + return false; + } + virtual bool Match(SegmentedFinder* s, uint64_t offset) + { + return false; + } + string rdWinString( char * offset, SegmentedFinder & sf ) + { + char * start_offset = offset + 4; // FIXME: pouzivat Memory.xml? + uint32_t length = *(uint32_t *)(offset + 20); // FIXME: pouzivat Memory.xml? + uint32_t capacity = *(uint32_t *)(offset + 24); // FIXME: pouzivat Memory.xml? + char * temp = new char[capacity+1]; + + // read data from inside the string structure + if(capacity < 16) + { + memcpy(temp, start_offset,capacity); + //read(start_offset, capacity, (uint8_t *)temp); + } + else // read data from what the offset + 4 dword points to + { + start_offset = sf.Translate(*(uint32_t*)start_offset); + memcpy(temp, start_offset,capacity); + } + + temp[length] = 0; + string ret = temp; + delete temp; + return ret; + } +}; + +inline void printRange(DFHack::t_memrange * tpr) +{ + std::cout << std::hex << tpr->start << " - " << tpr->end << "|" << (tpr->read ? "r" : "-") << (tpr->write ? "w" : "-") << (tpr->execute ? "x" : "-") << "|" << tpr->name << std::endl; +} + +bool getRanges(DFHack::Process * p, vector & selected_ranges) +{ + vector ranges; + selected_ranges.clear(); + p->getMemRanges(ranges); + cout << "Which range to search? (default is 1-4)" << endl; + for(int i = 0; i< ranges.size();i++) + { + cout << dec << "(" << i << ") "; + printRange(&(ranges[i])); + } + int start, end; + while(1) + { + string select; + cout << ">>"; + std::getline(cin, select); + if(select.empty()) + { + // empty input, assume default. observe the length of the memory range vector + // these are hardcoded values, intended for my convenience only + if(p->getDescriptor()->getOS() == DFHack::OS_WINDOWS) + { + start = min(11, (int)ranges.size()); + end = min(14, (int)ranges.size()); + } + else if(p->getDescriptor()->getOS() == DFHack::OS_LINUX) + { + start = min(2, (int)ranges.size()); + end = min(4, (int)ranges.size()); + } + else + { + start = 1; + end = 1; + } + break; + } + // I like the C variants here. much less object clutter + else if(sscanf(select.c_str(), "%d-%d", &start, &end) == 2) + { + start = min(start, (int)ranges.size()); + end = min(end, (int)ranges.size()); + break; + } + else + { + continue; + } + break; + } + end++; + cout << "selected ranges:" <::iterator it; + it = ranges.begin() + start; + while (it != ranges.begin() + end) + { + // check if readable + if((*it).read) + { + selected_ranges.push_back(*it); + printRange(&*it); + } + it++; + } +} + +bool getNumber (string prompt, int & output, int def, bool pdef = true) +{ + cout << prompt; + if(pdef) + cout << " default=" << def << endl; + while (1) + { + string select; + cout << ">>"; + std::getline(cin, select); + if(select.empty()) + { + output = def; + break; + } + else if( sscanf(select.c_str(), "%d", &output) == 1 ) + { + break; + } + else + { + continue; + } + } + return true; +} + +bool getString (string prompt, string & output) +{ + cout << prompt; + cout << ">>"; + string select; + std::getline(cin, select); + if(select.empty()) + { + return false; + } + else + { + output = select; + return true; + } +} + +// meh +#pragma pack(1) +struct tilecolors +{ + uint16_t fore; + uint16_t back; + uint16_t bright; +}; +#pragma pack() + +void printFound(vector &found, const char * what) +{ + cout << what << ":" << endl; + for(int i = 0; i < found.size();i++) + { + cout << hex << "0x" << found[i] << endl; + } +} + +void printFoundStrVec(vector &found, const char * what, SegmentedFinder & s) +{ + cout << what << ":" << endl; + for(int i = 0; i < found.size();i++) + { + cout << hex << "0x" << found[i] << endl; + cout << "--------------------------" << endl; + vecTriplet * vt = s.Translate(found[i]); + if(vt) + { + int j = 0; + for(uint32_t idx = vt->start; idx < vt->finish; idx += sizeof(uint32_t)) + { + uint32_t object_ptr; + // deref ptr idx, get ptr to object + if(!s.Read(idx,object_ptr)) + { + cout << "BAD!" << endl; + break; + } + // deref ptr to first object, get ptr to string + uint32_t string_ptr; + if(!s.Read(object_ptr,string_ptr)) + { + cout << "BAD!" << endl; + break; + } + // get string location in our local cache + char * str = s.Translate(string_ptr); + if(!str) + { + cout << "BAD!" << endl; + break; + } + cout << dec << j << ":" << hex << "0x" << object_ptr << " : " << str << endl; + j++; + } + } + else + { + cout << "BAD!" << endl; + break; + } + cout << "--------------------------" << endl; + } +} + +class TokenFactory +{ + DFHack::OSType platform; +public: + TokenFactory(DFHack::OSType platform_in) + { + platform = platform_in; + } + template + T * Build() + { + return new T; + } + template + T * Build(uint64_t offset) + { + return new T(offset); + } +}; +template <> +String * TokenFactory::Build() +{ + switch(platform) + { + case DFHack::OS_WINDOWS: + return new WindowsString(); + case DFHack::OS_LINUX: + case DFHack::OS_APPLE: + return new LinuxString(); + } + return 0; +}; +template <> +String * TokenFactory::Build(uint64_t offset) +{ + switch(platform) + { + case DFHack::OS_WINDOWS: + return new WindowsString(offset); + case DFHack::OS_LINUX: + case DFHack::OS_APPLE: + return new LinuxString(offset); + } + return 0; +}; + +void autoSearch(DFHack::Context * DF, vector & ranges, DFHack::OSType platform) +{ + cout << "stealing memory..." << endl; + SegmentedFinder sf(ranges, DF); + TokenFactory tf(platform); + cout << "done!" << endl; + Struct maps; + maps.Add(tf.Build()); + maps.Add(tf.Build()); + /* + vector allVectors; + vector filtVectors; + vector to_filter; + + cout << "stealing memory..." << endl; + SegmentedFinder sf(ranges, DF); + cout << "looking for vectors..." << endl; + sf.Find(0,4,allVectors, vectorAll); + + filtVectors = allVectors; + cout << "-------------------" << endl; + cout << "!!LANGUAGE TABLES!!" << endl; + cout << "-------------------" << endl; + + uint64_t kulet_vector; + uint64_t word_table_offset; + uint64_t DWARF_vector; + uint64_t DWARF_object; + + // find lang vector (neutral word table) + to_filter = filtVectors; + sf.Filter("ABBEY",to_filter, vectorStringFirst); + uint64_t lang_addr = to_filter[0]; + + // find dwarven language word table + to_filter = filtVectors; + sf.Filter("kulet",to_filter, vectorStringFirst); + kulet_vector = to_filter[0]; + + // find vector of languages + to_filter = filtVectors; + sf.Filter("DWARF",to_filter, vectorStringFirst); + + // verify + for(int i = 0; i < to_filter.size(); i++) + { + vecTriplet * vec = sf.Translate(to_filter[i]); + if(((vec->finish - vec->start) / 4) == 4) // verified + { + DWARF_vector = to_filter[i]; + DWARF_object = sf.Read(vec->start); + // compute word table offset from dwarf word table and dwarf language object addresses + word_table_offset = kulet_vector - DWARF_object; + break; + } + } + cout << "translation vector: " << hex << "0x" << DWARF_vector << endl; + cout << "lang vector: " << hex << "0x" << lang_addr << endl; + cout << "word table offset: " << hex << "0x" << word_table_offset << endl; + + cout << "-------------" << endl; + cout << "!!MATERIALS!!" << endl; + cout << "-------------" << endl; + // inorganics vector + to_filter = filtVectors; + //sf.Find(257 * 4,4,to_filter,vectorLength); + sf.Filter("IRON",to_filter, vectorString); + sf.Filter("ONYX",to_filter, vectorString); + sf.Filter("RAW_ADAMANTINE",to_filter, vectorString); + sf.Filter("BLOODSTONE",to_filter, vectorString); + printFound(to_filter,"inorganics"); + + // organics vector + to_filter = filtVectors; + sf.Filter(52 * 4,to_filter,vectorLength); + sf.Filter("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst); + printFound(to_filter,"organics"); + + // tree vector + to_filter = filtVectors; + sf.Filter(31 * 4,to_filter,vectorLength); + sf.Filter("MANGROVE",to_filter, vectorStringFirst); + printFound(to_filter,"trees"); + + // plant vector + to_filter = filtVectors; + sf.Filter(21 * 4,to_filter,vectorLength); + sf.Filter("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst); + printFound(to_filter,"plants"); + + // color descriptors + //AMBER, 112 + to_filter = filtVectors; + sf.Filter(112 * 4,to_filter,vectorLength); + sf.Filter("AMBER",to_filter, vectorStringFirst); + printFound(to_filter,"color descriptors"); + if(!to_filter.empty()) + { + uint64_t vec = to_filter[0]; + vecTriplet *vtColors = sf.Translate(vec); + uint32_t colorObj = sf.Read(vtColors->start); + cout << "Amber color:" << hex << "0x" << colorObj << endl; + // TODO: find string 'amber', the floats + } + + // all descriptors + //AMBER, 338 + to_filter = filtVectors; + sf.Filter(338 * 4,to_filter,vectorLength); + sf.Filter("AMBER",to_filter, vectorStringFirst); + printFound(to_filter,"all descriptors"); + + // creature type + //ELEPHANT, ?? (demons abound) + to_filter = filtVectors; + //sf.Find(338 * 4,4,to_filter,vectorLength); + sf.Filter("ELEPHANT",to_filter, vectorString); + sf.Filter("CAT",to_filter, vectorString); + sf.Filter("DWARF",to_filter, vectorString); + sf.Filter("WAMBLER_FLUFFY",to_filter, vectorString); + sf.Filter("TOAD",to_filter, vectorString); + sf.Filter("DEMON_1",to_filter, vectorString); + + vector toad_first = to_filter; + vector elephant_first = to_filter; + sf.Filter("TOAD",toad_first, vectorStringFirst); + sf.Filter("ELEPHANT",elephant_first, vectorStringFirst); + printFoundStrVec(toad_first,"toad-first creature types",sf); + printFound(elephant_first,"elephant-first creature types"); + printFound(to_filter,"all creature types"); + + uint64_t to_use = 0; + if(!elephant_first.empty()) + { + to_use = elephant_first[0]; + vecTriplet *vtCretypes = sf.Translate(to_use); + uint32_t elephant = sf.Read(vtCretypes->start); + uint64_t Eoffset; + cout << "Elephant: 0x" << hex << elephant << endl; + cout << "Elephant: rawname = 0x0" << endl; + uint8_t letter_E = 'E'; + Eoffset = sf.FindInRange (letter_E,equalityP, elephant, 0x300 ); + if(Eoffset) + { + cout << "Elephant: big E = 0x" << hex << Eoffset - elephant << endl; + } + Eoffset = sf.FindInRange ("FEMALE",vectorStringFirst, elephant, 0x300 ); + if(Eoffset) + { + cout << "Elephant: caste vector = 0x" << hex << Eoffset - elephant << endl; + } + Eoffset = sf.FindInRange ("SKIN",vectorStringFirst, elephant, 0x2000 ); + if(Eoffset) + { + cout << "Elephant: extract? vector = 0x" << hex << Eoffset - elephant << endl; + } + tilecolors eletc = {7,0,0}; + Bytestream bs_eletc(&eletc, sizeof(tilecolors)); + cout << bs_eletc; + Eoffset = sf.FindInRange (bs_eletc, findBytestream, elephant, 0x300 ); + if(Eoffset) + { + cout << "Elephant: colors = 0x" << hex << Eoffset - elephant << endl; + } + //cout << "Amber color:" << hex << "0x" << colorObj << endl; + // TODO: find string 'amber', the floats + } + if(!toad_first.empty()) + { + to_use = toad_first[0]; + vecTriplet *vtCretypes = sf.Translate(to_use); + uint32_t toad = sf.Read(vtCretypes->start); + uint64_t Eoffset; + cout << "Toad: 0x" << hex << toad << endl; + cout << "Toad: rawname = 0x0" << endl; + Eoffset = sf.FindInRange (0xF9,equalityP, toad, 0x300 ); + if(Eoffset) + { + cout << "Toad: character (not reliable) = 0x" << hex << Eoffset - toad << endl; + } + Eoffset = sf.FindInRange ("FEMALE",vectorStringFirst, toad, 0x300 ); + if(Eoffset) + { + cout << "Toad: caste vector = 0x" << hex << Eoffset - toad << endl; + } + Eoffset = sf.FindInRange ("SKIN",vectorStringFirst, toad, 0x2000 ); + if(Eoffset) + { + cout << "Toad: extract? vector = 0x" << hex << Eoffset - toad << endl; + } + tilecolors toadtc = {2,0,0}; + Bytestream bs_toadc(&toadtc, sizeof(tilecolors)); + Eoffset = sf.FindInRange (bs_toadc, findBytestream, toad, 0x300 ); + if(Eoffset) + { + cout << "Toad: colors = 0x" << hex << Eoffset - toad << endl; + } + }*/ +} + +int main (void) +{ + string select; + DFHack::ContextManager DFMgr("Memory.xml"); + DFHack::Context * DF = DFMgr.getSingleContext(); + try + { + DF->Attach(); + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + DFHack::Process * p = DF->getProcess(); + vector selected_ranges; + getRanges(p,selected_ranges); + + DFHack::VersionInfo *minfo = DF->getMemoryInfo(); + autoSearch(DF,selected_ranges, minfo->getOS()); + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +} diff --git a/tools/playground/incrementalsearch.cpp b/tools/playground/incrementalsearch.cpp index 8c347d0c7..676fbc522 100644 --- a/tools/playground/incrementalsearch.cpp +++ b/tools/playground/incrementalsearch.cpp @@ -21,146 +21,12 @@ using namespace std; #include #include "SegmentedFinder.h" -template -class holder -{ - public: - vector values; - SegmentedFinder & sf; - holder(SegmentedFinder& sff):sf(sff){}; - bool isValid(size_t idx) - { - - }; -}; - -class address -{ - public: - uint64_t addr_; - unsigned int valid : 1; - virtual void print(SegmentedFinder& sff) - { - cout << hex << "0x" << addr_ << endl; - }; - address(const uint64_t addr) - { - addr_ = addr; - valid = false; - } - virtual address & operator=(const uint64_t in) - { - addr_ = in; - valid = false; - return *this; - } - virtual bool isValid(SegmentedFinder& sff) - { - if(valid) return true; - if(sff.getSegmentForAddress(addr_)) - { - valid = 1; - } - } - virtual bool equals (SegmentedFinder & sf, address & rhs) - { - return rhs.addr_ == addr_; - } -}; - -// pointer to a null-terminated byte string -class Cstr: public address -{ - void print(SegmentedFinder & sf) - { - cout << hex << "0x" << addr_ << ": \"" << sf.Translate(addr_) << "\"" << endl; - } - bool equals(SegmentedFinder & sf,const char * rhs) - { - uint32_t addr2 = *(sf.Translate(addr_)); - return strcmp(sf.Translate(addr2), rhs) == 0; - } - template - bool equalsP(SegmentedFinder & sf,inType rhs) - { - return Predicate(addr_, sf, rhs); - } - bool isValid(SegmentedFinder& sf) - { - if (address::isValid(sf)) - { - // read the pointer - uint32_t addr2 = *(sf.Translate(addr_)); - // is it a real pointer? a pretty weak test, but whatever. - if(sf.getSegmentForAddress(addr2)) - return true; - } - return false; - } -}; - -// STL STRING -#ifdef LINUX_BUILD -class STLstr: public address -{ - -}; -#endif -#ifndef LINUX_BUILD -class STLstr: public address -{ - -}; -#endif - -// STL VECTOR -#ifdef LINUX_BUILD -class Vector: public address -{ - -}; -#endif -#ifndef LINUX_BUILD -class Vector: public address -{ - -}; -#endif -class Int64: public address{}; -class Int32: public address{}; -class Int16: public address{}; -class Int8: public address{}; inline void printRange(DFHack::t_memrange * tpr) { std::cout << std::hex << tpr->start << " - " << tpr->end << "|" << (tpr->read ? "r" : "-") << (tpr->write ? "w" : "-") << (tpr->execute ? "x" : "-") << "|" << tpr->name << std::endl; } -string rdWinString( char * offset, SegmentedFinder & sf ) -{ - char * start_offset = offset + 4; - uint32_t length = *(uint32_t *)(offset + 20); - uint32_t capacity = *(uint32_t *)(offset + 24); - char * temp = new char[capacity+1]; - - // read data from inside the string structure - if(capacity < 16) - { - memcpy(temp, start_offset,capacity); - //read(start_offset, capacity, (uint8_t *)temp); - } - else // read data from what the offset + 4 dword points to - { - start_offset = sf.Translate(*(uint32_t*)start_offset); - memcpy(temp, start_offset,capacity); - } - - temp[length] = 0; - string ret = temp; - delete temp; - return ret; -} - bool getRanges(DFHack::Process * p, vector & selected_ranges) { vector ranges; @@ -182,12 +48,12 @@ bool getRanges(DFHack::Process * p, vector & selected_ranges { // empty input, assume default. observe the length of the memory range vector // these are hardcoded values, intended for my convenience only - if(p->getDescriptor()->getOS() == DFHack::VersionInfo::OS_WINDOWS) + if(p->getDescriptor()->getOS() == DFHack::OS_WINDOWS) { start = min(11, (int)ranges.size()); end = min(14, (int)ranges.size()); } - else if(p->getDescriptor()->getOS() == DFHack::VersionInfo::OS_LINUX) + else if(p->getDescriptor()->getOS() == DFHack::OS_LINUX) { start = min(2, (int)ranges.size()); end = min(4, (int)ranges.size()); @@ -736,7 +602,7 @@ struct tilecolors }; #pragma pack() -void automatedLangtables(DFHack::Context * DF, vector & ranges) +void autoSearch(DFHack::Context * DF, vector & ranges) { vector allVectors; vector filtVectors; @@ -968,7 +834,7 @@ int main (void) getRanges(p,selected_ranges); DFHack::VersionInfo *minfo = DF->getMemoryInfo(); - DFHack::VersionInfo::OSType os = minfo->getOS(); + DFHack::OSType os = minfo->getOS(); string prompt = "Select search type: 1=number(default), 2=vector by length, 3=vector>object>string,\n" @@ -999,7 +865,7 @@ int main (void) FindStrings(DFMgr, selected_ranges); break; case 5: - automatedLangtables(DF,selected_ranges); + autoSearch(DF,selected_ranges); break; case 6: DF->Detach(); diff --git a/tools/playground/primitives.cpp b/tools/playground/primitives.cpp new file mode 100644 index 000000000..bdf837d62 --- /dev/null +++ b/tools/playground/primitives.cpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include +#include +using namespace std; +std::string teststr1; + std::string * teststr2; + std::string teststr3("test"); +int main (int numargs, const char ** args) +{ + printf("std::string E : 0x%x\n", &teststr1); + teststr1 = "This is a fairly long string, much longer than the one made by default constructor."; + cin.ignore(); + printf("std::string L : 0x%x\n", &teststr1); + teststr1 = "This one is shorter"; + cin.ignore(); + printf("std::string S : 0x%x\n", &teststr1); + cin.ignore(); + teststr2 = new string(); + printf("std::string * : 0x%x\n", &teststr2); + printf("std::string(\"test\") : 0x%x\n", &teststr3); + cin.ignore(); + return 0; +}