Simplified memory search tool

develop
Petr Mrázek 2010-06-02 05:39:55 +02:00
parent 1e00076df7
commit 8d15e22a59
2 changed files with 476 additions and 505 deletions

@ -0,0 +1,224 @@
#ifndef SEGMENTED_FINDER_H
#define SEGMENTED_FINDER_H
class SegmentedFinder;
class SegmentFinder
{
public:
SegmentFinder(DFHack::t_memrange & mr, DFHack::Context * DF, SegmentedFinder * SF)
{
_DF = DF;
mr_ = mr;
mr_.buffer = (uint8_t *)malloc (mr_.end - mr_.start);
DF->ReadRaw(mr_.start,(mr_.end - mr_.start),mr_.buffer);
_SF = SF;
}
~SegmentFinder()
{
delete mr_.buffer;
}
template <class needleType, class hayType, typename comparator >
bool Find (needleType needle, const uint8_t increment ,vector <uint64_t> &found, vector <uint64_t> &newfound, comparator oper)
{
if(found.empty())
{
//loop
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(hayType); offset += increment)
{
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) )
newfound.push_back(mr_.start + offset);
}
}
else
{
for( uint64_t i = 0; i < found.size(); i++)
{
if(mr_.isInRange(found[i]))
{
uint64_t corrected = found[i] - mr_.start;
if( oper(_SF,(hayType *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
}
}
return true;
}
private:
friend class SegmentedFinder;
SegmentedFinder * _SF;
DFHack::Context * _DF;
DFHack::t_memrange mr_;
};
class SegmentedFinder
{
public:
SegmentedFinder(vector <DFHack::t_memrange>& ranges, DFHack::Context * DF)
{
_DF = DF;
for(int i = 0; i < ranges.size(); i++)
{
segments.push_back(new SegmentFinder(ranges[i], DF, this));
}
}
~SegmentedFinder()
{
for(int i = 0; i < segments.size(); i++)
{
delete segments[i];
}
}
SegmentFinder * getSegmentForAddress (uint64_t addr)
{
for(int i = 0; i < segments.size(); i++)
{
if(segments[i]->mr_.isInRange(addr))
{
return segments[i];
}
}
return 0;
}
template <class needleType, class hayType, typename comparator >
bool Find (const needleType needle, const uint8_t increment, vector <uint64_t> &found, comparator oper)
{
vector <uint64_t> newfound;
for(int i = 0; i < segments.size(); i++)
{
segments[i]->Find<needleType,hayType,comparator>(needle, increment, found, newfound, oper);
}
found.clear();
found = newfound;
return !(found.empty());
}
template <typename T>
T * Translate(uint64_t address)
{
for(int i = 0; i < segments.size(); i++)
{
if(segments[i]->mr_.isInRange(address))
{
return (T *) (segments[i]->mr_.buffer + address - segments[i]->mr_.start);
}
}
return 0;
}
template <typename T>
T Read(uint64_t address)
{
return *Translate<T>(address);
}
template <typename T>
bool Read(uint64_t address, T& target)
{
T * test = Translate<T>(address);
if(test)
{
target = *test;
return true;
}
return false;
}
private:
DFHack::Context * _DF;
vector <SegmentFinder *> segments;
};
template <typename T>
bool equalityP (SegmentedFinder* s, T *x, T y)
{
return (*x) == y;
}
struct vecTriplet
{
uint32_t start;
uint32_t finish;
uint32_t alloc_finish;
};
template <typename Needle>
bool vectorLength (SegmentedFinder* s, vecTriplet *x, Needle &y)
{
if(x->start <= x->finish && x->finish <= x->alloc_finish)
if((x->finish - x->start) == y)
return true;
return false;
}
// find a vector of 32bit pointers, where an object pointed to has a string 'y' as the first member
bool vectorString (SegmentedFinder* s, vecTriplet *x, const char *y)
{
uint32_t object_ptr;
uint32_t idx = x->start;
// iterato over vector of pointers
for(uint32_t idx = x->start; idx < x->finish; idx += sizeof(uint32_t))
{
// deref ptr idx, get ptr to object
if(!s->Read(idx,object_ptr))
{
return false;
}
// deref ptr to first object, get ptr to string
uint32_t string_ptr;
if(!s->Read(object_ptr,string_ptr))
return false;
// get string location in our local cache
char * str = s->Translate<char>(string_ptr);
if(!str)
return false;
if(strcmp(y, str) == 0)
return true;
}
return false;
}
// test if the address is within a vector's array
bool vectorAddrWithin (SegmentedFinder* s, vecTriplet *x, uint32_t address)
{
if(address < x->finish && address >= x->start)
return true;
return false;
}
// test if an object address is within the vector of pointers
bool vectorOfPtrWithin (SegmentedFinder* s, vecTriplet *x, uint32_t address)
{
uint32_t object_ptr;
uint32_t idx = x->start;
for(uint32_t idx = x->start; idx < x->finish; idx += sizeof(uint32_t))
{
if(!s->Read(idx,object_ptr))
{
return false;
}
if(object_ptr == address)
return true;
}
return false;
}
bool vectorAll (SegmentedFinder* s, vecTriplet *x, int )
{
if(x->start <= x->finish && x->finish <= x->alloc_finish)
{
if(s->getSegmentForAddress(x->start) == s->getSegmentForAddress(x->finish)
&& s->getSegmentForAddress(x->finish) == s->getSegmentForAddress(x->alloc_finish))
return true;
}
return false;
}
bool findString (SegmentedFinder* s, uint32_t *addr, const char * compare )
{
// read string pointer, translate to local scheme
char *str = s->Translate<char>(*addr);
// verify
if(!str)
return false;
if(strcmp(str, compare) == 0)
return true;
return false;
}
#endif // SEGMENTED_FINDER_H

@ -19,395 +19,307 @@ using namespace std;
#endif #endif
#include <DFHack.h> #include <DFHack.h>
class SegmentedFinder; #include "SegmentedFinder.h"
class SegmentFinder
inline void printRange(DFHack::t_memrange * tpr)
{ {
public: std::cout << std::hex << tpr->start << " - " << tpr->end << "|" << (tpr->read ? "r" : "-") << (tpr->write ? "w" : "-") << (tpr->execute ? "x" : "-") << "|" << tpr->name << std::endl;
SegmentFinder(DFHack::t_memrange & mr, DFHack::Context * DF, SegmentedFinder * SF) }
{
_DF = DF; bool getRanges(DFHack::Process * p, vector <DFHack::t_memrange>& selected_ranges)
mr_ = mr; {
mr_.buffer = (uint8_t *)malloc (mr_.end - mr_.start); vector <DFHack::t_memrange> ranges;
DF->ReadRaw(mr_.start,(mr_.end - mr_.start),mr_.buffer); selected_ranges.clear();
_SF = SF; p->getMemRanges(ranges);
} cout << "Which range to search? (default is 1-4)" << endl;
~SegmentFinder() for(int i = 0; i< ranges.size();i++)
{ {
delete mr_.buffer; cout << dec << "(" << i << ") ";
printRange(&(ranges[i]));
} }
template <class needleType, class hayType, typename comparator > int start, end;
bool Find (needleType needle, const uint8_t increment ,vector <uint64_t> &found, vector <uint64_t> &newfound, comparator oper) while(1)
{ {
if(found.empty()) string select;
cout << ">>";
std::getline(cin, select);
if(select.empty())
{ {
//loop // empty input, assume default. observe the length of the memory range vector
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(hayType); offset += increment) // these are hardcoded values, intended for my convenience only
if(p->getDescriptor()->getOS() == DFHack::memory_info::OS_WINDOWS)
{ {
if( oper(_SF,(hayType *)(mr_.buffer + offset), needle) ) start = min(11, (int)ranges.size());
newfound.push_back(mr_.start + offset); end = min(14, (int)ranges.size());
} }
} else if(p->getDescriptor()->getOS() == DFHack::memory_info::OS_LINUX)
else {
{ start = min(11, (int)ranges.size());
for( uint64_t i = 0; i < found.size(); i++) end = min(14, (int)ranges.size());
}
else
{ {
if(mr_.isInRange(found[i])) start = 1;
{ end = 1;
uint64_t corrected = found[i] - mr_.start;
if( oper(_SF,(hayType *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
} }
break;
} }
return true; // I like the C variants here. much less object clutter
} else if(sscanf(select.c_str(), "%d-%d", &start, &end) == 2)
private:
friend class SegmentedFinder;
SegmentedFinder * _SF;
DFHack::Context * _DF;
DFHack::t_memrange mr_;
};
class SegmentedFinder
{
public:
SegmentedFinder(vector <DFHack::t_memrange>& ranges, DFHack::Context * DF)
{
_DF = DF;
for(int i = 0; i < ranges.size(); i++)
{ {
segments.push_back(new SegmentFinder(ranges[i], DF, this)); start = min(start, (int)ranges.size());
end = min(end, (int)ranges.size());
break;
} }
} else
~SegmentedFinder()
{
for(int i = 0; i < segments.size(); i++)
{ {
delete segments[i]; continue;
} }
break;
} }
SegmentFinder * getSegmentForAddress (uint64_t addr) end++;
cout << "selected ranges:" <<endl;
selected_ranges.insert(selected_ranges.begin(),ranges.begin() + start, ranges.begin() + end);
for(int i = 0; i< selected_ranges.size();i++)
{ {
for(int i = 0; i < segments.size(); i++) printRange(&(selected_ranges[i]));
{
if(segments[i]->mr_.isInRange(addr))
{
return segments[i];
}
}
return 0;
} }
template <class needleType, class hayType, typename comparator > }
bool Find (const needleType needle, const uint8_t increment, vector <uint64_t> &found, comparator oper)
bool getNumber (string prompt, int & output, int def, bool pdef = true)
{
cout << prompt;
if(pdef)
cout << " default=" << def << endl;
while (1)
{ {
vector <uint64_t> newfound; string select;
for(int i = 0; i < segments.size(); i++) cout << ">>";
std::getline(cin, select);
if(select.empty())
{ {
segments[i]->Find<needleType,hayType,comparator>(needle, increment, found, newfound, oper); output = def;
break;
} }
found.clear(); else if( sscanf(select.c_str(), "%d", &output) == 1 )
found = newfound;
return !(found.empty());
}
template <typename T>
T * Translate(uint64_t address)
{
for(int i = 0; i < segments.size(); i++)
{ {
if(segments[i]->mr_.isInRange(address)) break;
{
return (T *) (segments[i]->mr_.buffer + address - segments[i]->mr_.start);
}
} }
return 0; else
}
template <typename T>
T Read(uint64_t address)
{
return *Translate<T>(address);
}
template <typename T>
bool Read(uint64_t address, T& target)
{
T * test = Translate<T>(address);
if(test)
{ {
target = *test; continue;
return true;
} }
return false;
} }
private: return true;
DFHack::Context * _DF;
vector <SegmentFinder *> segments;
};
template <typename T>
bool equalityP (SegmentedFinder* s, T *x, T y)
{
return (*x) == y;
} }
struct vecTriplet bool getString (string prompt, string & output)
{
uint32_t start;
uint32_t finish;
uint32_t alloc_finish;
};
template <typename Needle>
bool vectorLength (SegmentedFinder* s, vecTriplet *x, Needle &y)
{ {
if(x->start <= x->finish && x->finish <= x->alloc_finish) cout << prompt;
if((x->finish - x->start) == y) cout << ">>";
return true; string select;
return false; std::getline(cin, select);
} if(select.empty())
bool vectorString (SegmentedFinder* s, vecTriplet *x, const char *y)
{
if(x->start <= x->finish && x->finish <= x->alloc_finish)
{ {
// deref ptr start, get ptr to firt object return false;
uint32_t object_ptr;
if(!s->Read(x->start,object_ptr))
return false;
// deref ptr to first object, get ptr to string
uint32_t string_ptr;
if(!s->Read(object_ptr,string_ptr))
return false;
// get string location in our local cache
char * str = s->Translate<char>(string_ptr);
if(!str)
return false;
if(strcmp(y, str) == 0)
return true;
} }
return false; else
}
bool vectorAll (SegmentedFinder* s, vecTriplet *x, int )
{
if(x->start <= x->finish && x->finish <= x->alloc_finish)
{ {
if(s->getSegmentForAddress(x->start) == s->getSegmentForAddress(x->finish) output = select;
&& s->getSegmentForAddress(x->finish) == s->getSegmentForAddress(x->alloc_finish)) return true;
return true;
} }
return false;
} }
bool findString (SegmentedFinder* s, uint32_t *addr, const char * compare ) template <class T>
bool Incremental ( vector <uint64_t> &found, const char * what, T& output,
const char *singular = "address", const char *plural = "addresses" )
{ {
// read string pointer, translate to local scheme string select;
char *str = s->Translate<char>(*addr); if(found.empty())
// verify {
if(!str) cout << "search ready - insert " << what << ", 'p' for results" << endl;
}
else if( found.size() == 1)
{
cout << "Found an "<< singular <<"!" << endl;
cout << hex << "0x" << found[0] << endl;
}
else
{
cout << "Found " << dec << found.size() << " " << plural <<"." << endl;
}
incremental_more:
cout << ">>";
std::getline(cin, select);
if(select == "p")
{
cout << "Found "<< plural <<":" << endl;
for(int i = 0; i < found.size();i++)
{
cout << hex << "0x" << found[i] << endl;
}
goto incremental_more;
}
else if(select.empty())
{
return false; return false;
if(strcmp(str, compare) == 0) }
else
{
stringstream ss (stringstream::in | stringstream::out);
ss << select;
ss >> output;
if(ss.fail())
{
cout << "not a valid value for type: " << what << endl;
goto incremental_more;
}
return true; return true;
return false; }
} }
//TODO: lots of optimization //TODO: lots of optimization
void searchLoop(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges, int size, int alignment) void searchLoop(DFHack::ContextManager & DFMgr, 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; uint32_t test1;
vector <uint64_t> found; vector <uint64_t> found;
found.reserve(100); found.reserve(100);
//bool initial = 1; while(Incremental(found, "integer",test1))
cout << "search ready - insert integers, 'p' for results" << endl;
string select;
while (1)
{ {
cout << ">>"; DFMgr.Refresh();
std::getline(cin, select); DFHack::Context * DF = DFMgr.getSingleContext();
if(select == "p") DF->Attach();
{ SegmentedFinder sf(ranges,DF);
cout << "Found addresses:" << endl; switch(size)
for(int i = 0; i < found.size();i++)
{
cout << hex << "0x" << found[i] << endl;
}
}
else if(sscanf(select.c_str(),"%d", &test1) == 1)
{ {
// refresh the list of processes, get first suitable, attach case 1:
DFMgr.Refresh(); sf.Find<uint8_t,uint8_t>(test1,alignment,found, equalityP<uint8_t>);
DFHack::Context * DF = DFMgr.getSingleContext(); break;
DF->Attach(); case 2:
SegmentedFinder sf(ranges,DF); sf.Find<uint16_t,uint16_t>(test1,alignment,found, equalityP<uint16_t>);
switch(size) break;
{ case 4:
case 1: sf.Find<uint32_t,uint32_t>(test1,alignment,found, equalityP<uint32_t>);
sf.Find<uint8_t,uint8_t>(test1,alignment,found, equalityP<uint8_t>); break;
break;
case 2:
sf.Find<uint16_t,uint16_t>(test1,alignment,found, equalityP<uint16_t>);
break;
case 4:
sf.Find<uint32_t,uint32_t>(test1,alignment,found, equalityP<uint32_t>);
break;
}
if( found.size() == 1)
{
cout << "Found an address!" << endl;
cout << hex << "0x" << found[0] << endl;
}
else
cout << "Found " << dec << found.size() << " addresses." << endl;
DF->Detach();
} }
else break; DF->Detach();
} }
} }
void searchLoopVector(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges, uint32_t element_size) void searchLoopVector(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges )
{ {
vecTriplet load; int element_size;
do
{
getNumber("Select searched vector item size in bytes",element_size, 4);
} while (element_size < 1);
uint32_t length; uint32_t length;
vector <uint64_t> found; vector <uint64_t> found;
found.reserve(100); found.reserve(100);
//bool initial = 1; while (Incremental(found, "vector length",length,"vector","vectors"))
cout << "search ready - insert vector length" << endl;
string select;
while (1)
{ {
cout << ">>"; DFMgr.Refresh();
std::getline(cin, select); DFHack::Context * DF = DFMgr.getSingleContext();
if(select == "p") DF->Attach();
{ SegmentedFinder sf(ranges,DF);
cout << "Found vectors:" << endl; sf.Find<int ,vecTriplet>(0,4,found,vectorAll);
for(int i = 0; i < found.size();i++) sf.Find<uint32_t,vecTriplet>(length * element_size,4,found,vectorLength<uint32_t>);
{ DF->Detach();
cout << hex << "0x" << found[i] << endl;
}
}
else if(sscanf(select.c_str(),"%d", &length) == 1)
{
// refresh the list of processes, get first suitable, attach
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
// clear the list of found addresses
found.clear();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found,vectorAll);
sf.Find<uint32_t,vecTriplet>(length*element_size,4,found,vectorLength<uint32_t>);
if( found.size() == 1)
{
cout << "Found an address!" << endl;
cout << hex << "0x" << found[0] << endl;
}
else
cout << "Found " << dec << found.size() << " addresses." << endl;
// detach again
DF->Detach();
}
else
{
break;
}
} }
} }
void searchLoopStrObjVector(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) void searchLoopStrObjVector(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges)
{ {
vector <uint64_t> found; vector <uint64_t> found;
cout << "search ready - insert string" << endl;
string select; string select;
while (1) while (Incremental(found, "raw name",select,"vector","vectors"))
{ {
cout << ">>"; // clear the list of found addresses -- this is a one-shot
std::getline(cin, select); found.clear();
if(select == "p") DFMgr.Refresh();
{ DFHack::Context * DF = DFMgr.getSingleContext();
cout << "Found vectors:" << endl; DF->Attach();
for(int i = 0; i < found.size();i++) SegmentedFinder sf(ranges,DF);
{ sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
cout << hex << "0x" << found[i] << endl; sf.Find<const char * ,vecTriplet>(select.c_str(),4,found, vectorString);
} DF->Detach();
}
else if(!select.empty())
{
// refresh the list of processes, get first suitable, attach
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
// clear the list of found addresses
found.clear();
SegmentedFinder sf(ranges,DF);
sf.Find<int ,vecTriplet>(0,4,found, vectorAll);
sf.Find<const char * ,vecTriplet>(select.c_str(),4,found, vectorString);
if( found.size() == 1)
{
cout << "Found an address!" << endl;
cout << hex << "0x" << found[0] << endl;
}
else
cout << "Found " << dec << found.size() << " addresses." << endl;
// detach again
DF->Detach();
}
else
{
break;
}
} }
} }
void searchLoopStr(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges) void searchLoopStr(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges)
{ {
vector <uint64_t> found; vector <uint64_t> found;
cout << "search ready - insert string" << endl;
string select; string select;
while (1) while (Incremental(found,"string",select,"string","strings"))
{ {
cout << ">>"; DFMgr.Refresh();
std::getline(cin, select); DFHack::Context * DF = DFMgr.getSingleContext();
if(select == "p") DF->Attach();
{ SegmentedFinder sf(ranges,DF);
cout << "Found strings:" << endl; sf.Find< const char * ,uint32_t>(select.c_str(),1,found, findString);
for(int i = 0; i < found.size();i++) DF->Detach();
{ }
cout << hex << "0x" << found[i] << endl; }
}
}
else if(!select.empty())
{
// refresh the list of processes, get first suitable, attach
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
// clear the list of found addresses void automatedLangtables(DFHack::Context * DF, vector <DFHack::t_memrange>& ranges)
found.clear(); {
SegmentedFinder sf(ranges,DF); vector <uint64_t> allVectors;
sf.Find< const char * ,uint32_t>(select.c_str(),1,found, findString); vector <uint64_t> to_filter;
if( found.size() == 1) uint64_t kulet_vector;
{ uint64_t word_table_offset;
cout << "Found a string!" << endl; uint64_t DWARF_vector;
cout << hex << "0x" << found[0] << endl; uint64_t DWARF_object;
} SegmentedFinder sf(ranges, DF);
else
cout << "Found " << dec << found.size() << " strings." << endl; // enumerate all vectors
// detach again sf.Find<int ,vecTriplet>(0,4,allVectors, vectorAll);
DF->Detach();
} // find lang vector (neutral word table)
else to_filter = allVectors;
sf.Find<const char * ,vecTriplet>("ABBEY",4,to_filter, vectorString);
uint64_t lang_addr = to_filter[0];
// find dwarven language word table
to_filter = allVectors;
sf.Find<const char * ,vecTriplet>("kulet",4,to_filter, vectorString);
kulet_vector = to_filter[0];
// find vector of languages
to_filter = allVectors;
sf.Find<const char * ,vecTriplet>("DWARF",4,to_filter, vectorString);
// verify
for(int 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; 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;
} }
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;
}
int main (void) int main (void)
{ {
string select; string select;
@ -426,205 +338,40 @@ int main (void)
return 1; return 1;
} }
DFHack::Process * p = DF->getProcess(); DFHack::Process * p = DF->getProcess();
vector <DFHack::t_memrange> ranges;
vector <DFHack::t_memrange> selected_ranges; vector <DFHack::t_memrange> selected_ranges;
p->getMemRanges(ranges); getRanges(p,selected_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]));
}
try_again_ranges: string prompt =
cout << ">>"; "Select search type: 1=number(default), 2=vector by length, 3=vector>object>string,\n"
std::getline(cin, select); " 4=string, 5=automated lang tables, 6=vector by address in its array,\n"
int start, end; " 7=pointer vector by address of an object, 8=vector>first object>string\n";
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::memory_info::OS_WINDOWS)
{
start = min(11, (int)ranges.size());
end = min(14, (int)ranges.size());
}
else if(p->getDescriptor()->getOS() == DFHack::memory_info::OS_LINUX)
{
start = min(11, (int)ranges.size());
end = min(14, (int)ranges.size());
}
else
{
start = 1;
end = 1;
}
}
// 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());
}
else
{
goto try_again_ranges; // yes, this is a goto. bite me.
}
end++;
cout << "selected ranges:" <<endl;
selected_ranges.insert(selected_ranges.begin(),ranges.begin() + start, ranges.begin() + end);
for(int i = 0; i< selected_ranges.size();i++)
{
printRange(&(selected_ranges[i]));
}
try_again_type:
cout << "Select search type: 1=number(default), 2=vector, 3=vector>object>string, 4=string, 5=automated lang tables" << endl;
cout << ">>";
std::getline(cin, select);
int mode; int mode;
if(select.empty()) do
{
mode = 1;
}
else if( sscanf(select.c_str(), "%d", &mode) == 1 )
{ {
if(mode != 1 && mode != 2 && mode != 3 && mode != 4 && mode != 5) getNumber(prompt,mode, 1, false);
{ } while (mode < 1 || mode > 8 );
goto try_again_type; switch (mode)
}
}
else
{ {
goto try_again_type; case 1:// integers
} searchLoop(DFMgr, selected_ranges);
break;
if(mode == 1) case 2:// vector by length and item size
{ searchLoopVector(DFMgr, selected_ranges);
// input / validation of variable size break;
try_again_size: case 3:// vector>object>string
cout << "Select searched variable size (1,2,4 bytes, default is 4)" << endl; searchLoopStrObjVector(DFMgr, selected_ranges);
cout << ">>"; break;
std::getline(cin, select); case 4:// string
int size; searchLoopStr(DFMgr, selected_ranges);
if(select.empty()) break;
{ case 5:
size = 4; automatedLangtables(DF,selected_ranges);
} break;
else if( sscanf(select.c_str(), "%d", &size) == 1 ) case 6:
{ case 7:
if(/*size != 8 &&*/ size != 4 && size != 2 && size != 1) case 8:
{ default:
goto try_again_size; cout << "not implemented :(" << endl;
}
}
else
{
goto try_again_size;
}
// input / validation of variable alignment (default is to use the same alignment as size)
try_again_align:
cout << "Variable alignment (1,2,4 bytes, default is " << size << ")" << endl;
cout << ">>";
std::getline(cin, select);
int alignment = size;
if(select.empty())
{
alignment = size;
}
else if( sscanf(select.c_str(), "%d", &alignment) == 1 )
{
if(/*alignment != 8 &&*/ alignment != 4 && alignment != 2 && alignment != 1)
{
goto try_again_align;
}
}
else
{
goto try_again_align;
}
// we detach, searchLoop looks for the process again.
DF->Detach();
searchLoop(DFMgr, selected_ranges, size, alignment);
}
else if(mode == 2)// vector
{
// input / validation of variable size
try_again_vsize:
cout << "Select searched vector item size (in bytes, default is 4)" << endl;
cout << ">>";
std::getline(cin, select);
uint32_t size;
if(select.empty())
{
size = 4;
}
else if( sscanf(select.c_str(), "%d", &size) == 1 )
{
if(size == 0)
{
goto try_again_vsize;
}
}
else
{
goto try_again_vsize;
}
// we detach, searchLoop looks for the process again.
DF->Detach();
searchLoopVector(DFMgr, selected_ranges,size);
}
else if(mode == 3)// vector>object>string
{
searchLoopStrObjVector(DFMgr, selected_ranges);
}
else if(mode == 4)// string
{
searchLoopStr(DFMgr, selected_ranges);
}
else if(mode == 5) // find lang tables and stuff
{
vector <uint64_t> allVectors;
vector <uint64_t> to_filter;
uint64_t kulet_vector;
uint64_t word_table_offset;
uint64_t DWARF_vector;
uint64_t DWARF_object;
SegmentedFinder sf(selected_ranges, DF);
// enumerate all vectors
sf.Find<int ,vecTriplet>(0,4,allVectors, vectorAll);
// find lang vector (neutral word table)
to_filter = allVectors;
sf.Find<const char * ,vecTriplet>("ABBEY",4,to_filter, vectorString);
uint64_t lang_addr = to_filter[0];
// find dwarven language word table
to_filter = allVectors;
sf.Find<const char * ,vecTriplet>("kulet",4,to_filter, vectorString);
kulet_vector = to_filter[0];
// find vector of languages
to_filter = allVectors;
sf.Find<const char * ,vecTriplet>("DWARF",4,to_filter, vectorString);
// verify
for(int 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;
} }
#ifndef LINUX_BUILD #ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl; cout << "Done. Press any key to continue" << endl;