summaryrefslogtreecommitdiff
path: root/needs_porting/incrementalsearch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'needs_porting/incrementalsearch.cpp')
-rw-r--r--needs_porting/incrementalsearch.cpp1064
1 files changed, 1064 insertions, 0 deletions
diff --git a/needs_porting/incrementalsearch.cpp b/needs_porting/incrementalsearch.cpp
new file mode 100644
index 00000000..e70e0952
--- /dev/null
+++ b/needs_porting/incrementalsearch.cpp
@@ -0,0 +1,1064 @@
+// this is an incremental search tool. It only works on Linux.
+// here be dragons... and ugly code :P
+#include <iostream>
+#include <climits>
+#include <vector>
+#include <map>
+#include <set>
+#include <ctime>
+#include <string.h>
+#include <stdio.h>
+#include <algorithm>
+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 <windows.h>
+#endif
+
+#include <DFHack.h>
+#include "SegmentedFinder.h"
+
+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;
+}
+
+/*
+ * Since the start and/or end of a memory range can change each time we
+ * detach and re-attach to the DF process, we save the indexes of the
+ * memory ranges we want to look at, and re-read the ranges each time
+ * we re-attach. Hopefully we won't encounter any circumstances where
+ * entire new ranges are added or removed...
+ */
+bool getRanges(DFHack::Process * p, vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ ranges.clear();
+ selected_ranges.clear();
+ p->getMemRanges(ranges);
+ cout << "Which range to search? (default is 1-4)" << endl;
+ for(size_t 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;
+ }
+ cout << "selected ranges:" <<endl;
+
+ for (int i = start; i <= end; i++)
+ {
+ // check if readable
+ if (ranges[i].read)
+ {
+ selected_ranges.push_back(i);
+ printRange(&(ranges[i]));
+ }
+ }
+
+ return true;
+}
+
+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;
+ }
+}
+
+bool readRanges(DFHack::Context * DF, vector <int>& selected_ranges,
+ vector <DFHack::t_memrange>& ranges)
+{
+ DFHack::Process * p = DF->getProcess();
+
+ vector <DFHack::t_memrange> new_ranges;
+ new_ranges.clear();
+ p->getMemRanges(new_ranges);
+
+ for (size_t i = 0; i < selected_ranges.size(); i++)
+ {
+ int idx = selected_ranges[i];
+
+ if (ranges.size() == i)
+ // First time ranges vector has been filled in.
+ ranges.push_back(new_ranges[idx]);
+ // If something was wrong with the range on one memory read,
+ // don't read it again.
+ else if(ranges[i].valid)
+ ranges[i] = new_ranges[idx];
+ }
+
+ return true;
+}
+
+
+template <class T>
+bool Incremental ( vector <uint64_t> &found, const char * what, T& output,
+ const char *singular = "address", const char *plural = "addresses", bool numberz = false )
+{
+ string select;
+ if(found.empty())
+ {
+ cout << "search ready - insert " << what << ", 'p' for results, 'p #' to limit number of results" << endl;
+ }
+ else if( found.size() == 1)
+ {
+ cout << "Found single "<< singular <<"!" << endl;
+ cout << hex << "0x" << found[0] << endl;
+ }
+ else
+ {
+ cout << "Found " << dec << found.size() << " " << plural <<"." << endl;
+ }
+ incremental_more:
+ cout << ">>";
+ std::getline(cin, select);
+ size_t num = 0;
+ if( sscanf(select.c_str(),"p %zd", &num) && num > 0)
+ {
+ cout << "Found "<< plural <<":" << endl;
+ for(size_t i = 0; i < min(found.size(), num);i++)
+ {
+ cout << hex << "0x" << found[i] << endl;
+ }
+ goto incremental_more;
+ }
+ else if(select == "p")
+ {
+ cout << "Found "<< plural <<":" << endl;
+ for(size_t i = 0; i < found.size();i++)
+ {
+ cout << hex << "0x" << found[i] << endl;
+ }
+ goto incremental_more;
+ }
+ else if(select == "q")
+ {
+ return false;
+ }
+ else if(select.empty())
+ {
+ goto incremental_more;
+ }
+ else
+ {
+ if(numberz)
+ {
+ if( sscanf(select.c_str(),"0x%x", &output) == 1 )
+ {
+ //cout << dec << output << endl;
+ return true;
+ }
+ if( sscanf(select.c_str(),"%d", &output) == 1 )
+ {
+ //cout << dec << output << endl;
+ return true;
+ }
+ }
+ stringstream ss (stringstream::in | stringstream::out);
+ ss << select;
+ ss >> output;
+ cout << output;
+ if(!ss.fail())
+ {
+ return true;
+ }
+ cout << "not a valid value for type: " << what << endl;
+ goto incremental_more;
+ }
+}
+
+void FindIntegers(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+
+ // input / validation of variable size
+ int size;
+ do
+ {
+ getNumber("Select variable size (1,2,4 bytes)",size, 4);
+ } while (size != 1 && size != 2 && size != 4);
+ // input / validation of variable alignment (default is to use the same alignment as size)
+ int alignment;
+ do
+ {
+ getNumber("Select variable alignment (1,2,4 bytes)",alignment, size);
+ } while (alignment != 1 && alignment != 2 && alignment != 4);
+
+ uint32_t test1;
+ vector <uint64_t> found;
+ found.reserve(100);
+ while(Incremental(found, "integer",test1,"address", "addresses",true))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ switch(size)
+ {
+ case 1:
+ sf.Incremental<uint8_t,uint8_t>(test1,alignment,found, equalityP<uint8_t>);
+ break;
+ case 2:
+ sf.Incremental<uint16_t,uint16_t>(test1,alignment,found, equalityP<uint16_t>);
+ break;
+ case 4:
+ sf.Incremental<uint32_t,uint32_t>(test1,alignment,found, equalityP<uint32_t>);
+ break;
+ }
+ DF->Detach();
+ }
+}
+
+void FindVectorByLength(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges )
+{
+ vector <DFHack::t_memrange> ranges;
+
+ int element_size;
+ do
+ {
+ getNumber("Select searched vector item size in bytes",element_size, 4);
+ } while (element_size < 1);
+
+ uint32_t length;
+ vector <uint64_t> found;
+ found.reserve(100);
+ while (Incremental(found, "vector length",length,"vector","vectors"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ //sf.Incremental<int ,vecTriplet>(0,4,found,vectorAll);
+ //sf.Filter<uint32_t,vecTriplet>(length * element_size,found,vectorLength<uint32_t>);
+ sf.Incremental<uint32_t,vecTriplet>(length * element_size, 4 , found, vectorLength<uint32_t>);
+ DF->Detach();
+ }
+}
+
+void FindVectorByObjectRawname(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ vector <uint64_t> found;
+ string select;
+
+ while (Incremental(found, "raw name",select,"vector","vectors"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
+ sf.Filter<const char * ,vecTriplet>(select.c_str(),found, vectorString);
+ DF->Detach();
+ }
+}
+
+void FindVectorByFirstObjectRawname(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ vector <uint64_t> found;
+ string select;
+ while (Incremental(found, "raw name",select,"vector","vectors"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
+ sf.Filter<const char * ,vecTriplet>(select.c_str(),found, vectorStringFirst);
+ DF->Detach();
+ }
+}
+
+struct VectorSizeFunctor : public binary_function<uint64_t, uint64_t, bool>
+{
+ VectorSizeFunctor(SegmentedFinder & sf):sf_(sf){}
+ bool operator()( uint64_t lhs, uint64_t rhs)
+ {
+ vecTriplet* left = sf_.Translate<vecTriplet>(lhs);
+ vecTriplet* right = sf_.Translate<vecTriplet>(rhs);
+ return ((left->finish - left->start) < (right->finish - right->start));
+ }
+ SegmentedFinder & sf_;
+};
+
+void FindVectorByBounds(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ vector <uint64_t> found;
+ uint32_t select;
+ while (Incremental(found, "address between vector.start and vector.end",select,"vector","vectors"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
+ sf.Filter<uint32_t ,vecTriplet>(select,found, vectorAddrWithin);
+ // sort by size of vector
+ std::sort(found.begin(), found.end(), VectorSizeFunctor(sf));
+ DF->Detach();
+ }
+}
+
+void FindPtrVectorsByObjectAddress(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ vector <uint64_t> found;
+ uint32_t select;
+ while (Incremental(found, "object address",select,"vector","vectors"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
+ sf.Filter<uint32_t ,vecTriplet>(select,found, vectorOfPtrWithin);
+ DF->Detach();
+ }
+}
+
+void FindStrBufs(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ vector <uint64_t> found;
+ string select;
+ while (Incremental(found,"buffer",select,"buffer","buffers"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ sf.Find< const char * ,uint32_t>(select.c_str(),1,found, findStrBuffer);
+ DF->Detach();
+ }
+}
+
+
+
+void FindStrings(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ vector <uint64_t> found;
+ string select;
+ while (Incremental(found,"string",select,"string","strings"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ sf.Incremental< const char * ,uint32_t>(select.c_str(),1,found, findString);
+ DF->Detach();
+ }
+}
+
+void FindData(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ vector <uint64_t> found;
+ Bytestream select;
+ while (Incremental(found,"byte stream",select,"byte stream","byte streams"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ sf.Incremental< Bytestream ,uint32_t>(select,1,found, findBytestream);
+ DF->Detach();
+ }
+}
+
+bool TriggerIncremental ( vector <uint64_t> &found )
+{
+ string select;
+ if(found.empty())
+ {
+ cout << "search ready - position the DF cursor and hit enter when ready" << endl;
+ }
+ else if( found.size() == 1 )
+ {
+ cout << "Found single coord!" << endl;
+ cout << hex << "0x" << found[0] << endl;
+ }
+ else
+ {
+ cout << "Found " << dec << found.size() << " coords." << endl;
+ }
+ incremental_more:
+ cout << ">>";
+ std::getline(cin, select);
+ size_t num = 0;
+ if( sscanf(select.c_str(),"p %zd", &num) && num > 0)
+ {
+ cout << "Found coords:" << endl;
+ for(size_t i = 0; i < min(found.size(), num);i++)
+ {
+ cout << hex << "0x" << found[i] << endl;
+ }
+ goto incremental_more;
+ }
+ else if(select == "p")
+ {
+ cout << "Found coords:" << endl;
+ for(size_t i = 0; i < found.size();i++)
+ {
+ cout << hex << "0x" << found[i] << endl;
+ }
+ goto incremental_more;
+ }
+ else if(select == "q")
+ {
+ return false;
+ }
+ else return true;
+}
+
+void FindCoords(DFHack::ContextManager & DFMgr, vector <int>& selected_ranges)
+{
+ vector <uint64_t> found;
+ vector <DFHack::t_memrange> ranges;
+
+ int size = 4;
+ do
+ {
+ getNumber("Select coord size (2,4 bytes)",size, 4);
+ } while (size != 2 && size != 4);
+ while (TriggerIncremental(found))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ DFHack::Gui * pos = DF->getGui();
+ pos->Start();
+ int32_t x, y, z;
+ pos->getCursorCoords(x,y,z);
+ cout << "Searching for: " << dec << x << ":" << y << ":" << z << endl;
+ Bytestream select;
+ if(size == 2)
+ {
+ select.insert<uint16_t>(x);
+ select.insert<uint16_t>(y);
+ select.insert<uint16_t>(z);
+ }
+ else
+ {
+ select.insert<uint32_t>(x);
+ select.insert<uint32_t>(y);
+ select.insert<uint32_t>(z);
+ }
+ cout << select << endl;
+ SegmentedFinder sf(ranges,DF);
+ sf.Incremental< Bytestream ,uint32_t>(select,1,found, findBytestream);
+ DF->Detach();
+ }
+}
+
+void PtrTrace(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+
+ int element_size;
+ do
+ {
+ getNumber("Set search granularity",element_size, 4);
+ } while (element_size < 1);
+
+ vector <uint64_t> found;
+ set <uint64_t> check; // to detect circles
+ uint32_t select;
+ while (Incremental(found,"address",select,"addresses","addresses",true))
+ {
+ DFMgr.Refresh();
+ found.clear();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ readRanges(DF, selected_ranges, ranges);
+ SegmentedFinder sf(ranges,DF);
+ cout <<"Starting: 0x" << hex << select << endl;
+ while(sf.getSegmentForAddress(select))
+ {
+ sf.Incremental<uint32_t,uint32_t>(select,element_size,found, equalityP<uint32_t>);
+ if(found.empty())
+ {
+ cout << ".";
+ cout.flush();
+ select -=element_size;
+ continue;
+ }
+ cout << endl;
+ cout <<"Object start: 0x" << hex << select << endl;
+ cout <<"Pointer: 0x" << hex << found[0] << endl;
+ // make sure we don't go in circles'
+ if(check.count(select))
+ {
+ break;
+ }
+ check.insert(select);
+ // ascend
+ select = found[0];
+ found.clear();
+ }
+ DF->Detach();
+ }
+}
+/*
+{
+ vector <uint64_t> found;
+ Bytestream select;
+ while (Incremental(found,"byte stream",select,"byte stream","byte streams"))
+ {
+ DFMgr.Refresh();
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ SegmentedFinder sf(ranges,DF);
+ sf.Incremental< Bytestream ,uint32_t>(select,1,found, findBytestream);
+ DF->Detach();
+ }
+}
+*/
+void DataPtrTrace(DFHack::ContextManager & DFMgr,
+ vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ int element_size;
+ do
+ {
+ getNumber("Set search granularity",element_size, 4);
+ } while (element_size < 1);
+
+ vector <uint64_t> found;
+ set <uint64_t> check; // to detect circles
+ uint32_t select;
+ Bytestream bs_select;
+ DFHack::Context * DF = DFMgr.getSingleContext();
+ DF->Attach();
+ DFMgr.Refresh();
+ readRanges(DF, selected_ranges, ranges);
+ found.clear();
+ SegmentedFinder sf(ranges,DF);
+ while(found.empty())
+ {
+ Incremental(found,"byte stream",bs_select,"byte stream","byte streams");
+
+ sf.Incremental< Bytestream ,uint32_t>(bs_select,1,found, findBytestream);
+ }
+ select = found[0];
+
+
+
+
+ cout <<"Starting: 0x" << hex << select << endl;
+ while(sf.getSegmentForAddress(select))
+ {
+ sf.Incremental<uint32_t,uint32_t>(select,element_size,found, equalityP<uint32_t>);
+ if(found.empty())
+ {
+ cout << ".";
+ cout.flush();
+ select -=element_size;
+ continue;
+ }
+ cout << endl;
+ cout <<"Object start: 0x" << hex << select << endl;
+ cout <<"Pointer: 0x" << hex << found[0] << endl;
+ // make sure we don't go in circles'
+ if(check.count(select))
+ {
+ break;
+ }
+ check.insert(select);
+ // ascend
+ select = found[0];
+ found.clear();
+ }
+ DF->Detach();
+}
+
+void printFound(vector <uint64_t> &found, const char * what)
+{
+ cout << what << ":" << endl;
+ for(size_t i = 0; i < found.size();i++)
+ {
+ cout << hex << "0x" << found[i] << endl;
+ }
+}
+
+void printFoundStrVec(vector <uint64_t> &found, const char * what, SegmentedFinder & s)
+{
+ cout << what << ":" << endl;
+ for(size_t i = 0; i < found.size();i++)
+ {
+ cout << hex << "0x" << found[i] << endl;
+ cout << "--------------------------" << endl;
+ vecTriplet * vt = s.Translate<vecTriplet>(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<char>(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;
+ }
+}
+
+// meh
+#pragma pack(1)
+struct tilecolors
+{
+ uint16_t fore;
+ uint16_t back;
+ uint16_t bright;
+};
+#pragma pack()
+
+void autoSearch(DFHack::Context * DF, vector <int>& selected_ranges)
+{
+ vector <DFHack::t_memrange> ranges;
+ vector <uint64_t> allVectors;
+ vector <uint64_t> filtVectors;
+ vector <uint64_t> to_filter;
+
+ readRanges(DF, selected_ranges, ranges);
+
+ cout << "stealing memory..." << endl;
+ SegmentedFinder sf(ranges, DF);
+ cout << "looking for vectors..." << endl;
+ sf.Find<int ,vecTriplet>(0,4,allVectors, vectorAll);
+/*
+ // trim vectors. anything with > 10000 entries is not interesting
+ for(uint64_t i = 0; i < allVectors.size();i++)
+ {
+ vecTriplet* vtrip = sf.Translate<vecTriplet>(allVectors[i]);
+ if(vtrip)
+ {
+ uint64_t length = (vtrip->finish - vtrip->start) / 4;
+ if(length < 10000 )
+ {
+ filtVectors.push_back(allVectors[i]);
+ }
+ }
+ }
+*/
+ 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<const char * ,vecTriplet>("ABBEY",to_filter, vectorStringFirst);
+ uint64_t lang_addr = to_filter[0];
+
+ // find dwarven language word table
+ to_filter = filtVectors;
+ sf.Filter<const char * ,vecTriplet>("kulet",to_filter, vectorStringFirst);
+ kulet_vector = to_filter[0];
+
+ // find vector of languages
+ to_filter = filtVectors;
+ sf.Filter<const char * ,vecTriplet>("DWARF",to_filter, vectorStringFirst);
+
+ // verify
+ for(size_t i = 0; i < to_filter.size(); i++)
+ {
+ vecTriplet * vec = sf.Translate<vecTriplet>(to_filter[i]);
+ if(((vec->finish - vec->start) / 4) == 4) // verified
+ {
+ DWARF_vector = to_filter[i];
+ DWARF_object = sf.Read<uint32_t>(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<uint32_t,vecTriplet>(257 * 4,4,to_filter,vectorLength<uint32_t>);
+ sf.Filter<const char * ,vecTriplet>("IRON",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("ONYX",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("RAW_ADAMANTINE",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("BLOODSTONE",to_filter, vectorString);
+ printFound(to_filter,"inorganics");
+
+ // organics vector
+ to_filter = filtVectors;
+ sf.Filter<uint32_t,vecTriplet>(52 * 4,to_filter,vectorLength<uint32_t>);
+ sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst);
+ printFound(to_filter,"organics");
+
+ // new organics vector
+ to_filter = filtVectors;
+ sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("MEADOW-GRASS",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("TUNNEL_TUBE",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("WEED_BLADE",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("EYEBALL",to_filter, vectorString);
+ printFound(to_filter,"organics 31.19");
+
+ // tree vector
+ to_filter = filtVectors;
+ sf.Filter<uint32_t,vecTriplet>(31 * 4,to_filter,vectorLength<uint32_t>);
+ sf.Filter<const char * ,vecTriplet>("MANGROVE",to_filter, vectorStringFirst);
+ printFound(to_filter,"trees");
+
+ // plant vector
+ to_filter = filtVectors;
+ sf.Filter<uint32_t,vecTriplet>(21 * 4,to_filter,vectorLength<uint32_t>);
+ sf.Filter<const char * ,vecTriplet>("MUSHROOM_HELMET_PLUMP",to_filter, vectorStringFirst);
+ printFound(to_filter,"plants");
+
+ // color descriptors
+ //AMBER, 112
+ to_filter = filtVectors;
+ sf.Filter<uint32_t,vecTriplet>(112 * 4,to_filter,vectorLength<uint32_t>);
+ sf.Filter<const char * ,vecTriplet>("AMBER",to_filter, vectorStringFirst);
+ printFound(to_filter,"color descriptors");
+ if(!to_filter.empty())
+ {
+ uint64_t vec = to_filter[0];
+ vecTriplet *vtColors = sf.Translate<vecTriplet>(vec);
+ uint32_t colorObj = sf.Read<uint32_t>(vtColors->start);
+ cout << "Amber color:" << hex << "0x" << colorObj << endl;
+ // TODO: find string 'amber', the floats
+ }
+
+ // all descriptors
+ //AMBER, 338
+ to_filter = filtVectors;
+ sf.Filter<uint32_t,vecTriplet>(338 * 4,to_filter,vectorLength<uint32_t>);
+ sf.Filter<const char * ,vecTriplet>("AMBER",to_filter, vectorStringFirst);
+ printFound(to_filter,"all descriptors");
+
+ // creature type
+ //ELEPHANT, ?? (demons abound)
+ to_filter = filtVectors;
+ //sf.Find<uint32_t,vecTriplet>(338 * 4,4,to_filter,vectorLength<uint32_t>);
+ sf.Filter<const char * ,vecTriplet>("ELEPHANT",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("CAT",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("DWARF",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("WAMBLER_FLUFFY",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("TOAD",to_filter, vectorString);
+ sf.Filter<const char * ,vecTriplet>("DEMON_1",to_filter, vectorString);
+
+ vector <uint64_t> toad_first = to_filter;
+ vector <uint64_t> elephant_first = to_filter;
+ sf.Filter<const char * ,vecTriplet>("TOAD",toad_first, vectorStringFirst);
+ sf.Filter<const char * ,vecTriplet>("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<vecTriplet>(to_use);
+ uint32_t elephant = sf.Read<uint32_t>(vtCretypes->start);
+ uint64_t Eoffset;
+ cout << "Elephant: 0x" << hex << elephant << endl;
+ cout << "Elephant: rawname = 0x0" << endl;
+ uint8_t letter_E = 'E';
+ Eoffset = sf.FindInRange<uint8_t,uint8_t> (letter_E,equalityP<uint8_t>, elephant, 0x300 );
+ if(Eoffset)
+ {
+ cout << "Elephant: big E = 0x" << hex << Eoffset - elephant << endl;
+ }
+ Eoffset = sf.FindInRange<const char *,vecTriplet> ("FEMALE",vectorStringFirst, elephant, 0x300 );
+ if(Eoffset)
+ {
+ cout << "Elephant: caste vector = 0x" << hex << Eoffset - elephant << endl;
+ }
+ Eoffset = sf.FindInRange<const char *,vecTriplet> ("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<Bytestream,tilecolors> (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<vecTriplet>(to_use);
+ uint32_t toad = sf.Read<uint32_t>(vtCretypes->start);
+ uint64_t Eoffset;
+ cout << "Toad: 0x" << hex << toad << endl;
+ cout << "Toad: rawname = 0x0" << endl;
+ Eoffset = sf.FindInRange<uint8_t,uint8_t> (0xF9,equalityP<uint8_t>, toad, 0x300 );
+ if(Eoffset)
+ {
+ cout << "Toad: character (not reliable) = 0x" << hex << Eoffset - toad << endl;
+ }
+ Eoffset = sf.FindInRange<const char *,vecTriplet> ("FEMALE",vectorStringFirst, toad, 0x300 );
+ if(Eoffset)
+ {
+ cout << "Toad: caste vector = 0x" << hex << Eoffset - toad << endl;
+ }
+ Eoffset = sf.FindInRange<const char *,vecTriplet> ("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<Bytestream,tilecolors> (bs_toadc, findBytestream, toad, 0x300 );
+ if(Eoffset)
+ {
+ cout << "Toad: colors = 0x" << hex << Eoffset - toad << endl;
+ }
+ }
+ if(to_use)
+ {
+
+ }
+}
+
+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 <int> selected_ranges;
+ getRanges(p, selected_ranges);
+
+ string prompt =
+ "Select search type: 1=number(default), 2=vector by length, 3=vector>object>string,\n"
+ " 4=string, 5=automated offset search, 6=vector by address in its array,\n"
+ " 7=pointer vector by address of an object, 8=vector>first object>string\n"
+ " 9=string buffers, 10=known data, 11=backpointers, 12=data+backpointers\n"
+ " 13=coord lookup\n"
+ " 0= exit\n";
+ int mode;
+ bool finish = 0;
+ do
+ {
+ getNumber(prompt,mode, 1, false);
+ switch (mode)
+ {
+ case 0:
+ finish = 1;
+ break;
+ case 1:
+ DF->Detach();
+ FindIntegers(DFMgr, selected_ranges);
+ break;
+ case 2:
+ DF->Detach();
+ FindVectorByLength(DFMgr, selected_ranges);
+ break;
+ case 3:
+ DF->Detach();
+ FindVectorByObjectRawname(DFMgr, selected_ranges);
+ break;
+ case 4:
+ DF->Detach();
+ FindStrings(DFMgr, selected_ranges);
+ break;
+ case 5:
+ autoSearch(DF,selected_ranges);
+ break;
+ case 6:
+ DF->Detach();
+ FindVectorByBounds(DFMgr,selected_ranges);
+ break;
+ case 7:
+ DF->Detach();
+ FindPtrVectorsByObjectAddress(DFMgr,selected_ranges);
+ break;
+ case 8:
+ DF->Detach();
+ FindVectorByFirstObjectRawname(DFMgr, selected_ranges);
+ break;
+ case 9:
+ DF->Detach();
+ FindStrBufs(DFMgr, selected_ranges);
+ break;
+ case 10:
+ DF->Detach();
+ FindData(DFMgr, selected_ranges);
+ break;
+ case 11:
+ DF->Detach();
+ PtrTrace(DFMgr, selected_ranges);
+ break;
+ case 12:
+ DF->Detach();
+ DataPtrTrace(DFMgr, selected_ranges);
+ break;
+ case 13:
+ DF->Detach();
+ FindCoords(DFMgr, selected_ranges);
+ break;
+ default:
+ cout << "Unknown function, try again." << endl;
+ }
+ } while ( !finish );
+ #ifndef LINUX_BUILD
+ cout << "Done. Press any key to continue" << endl;
+ cin.ignore();
+ #endif
+ return 0;
+}