Sync, autosearch skeleton.
							parent
							
								
									30d806d988
								
							
						
					
					
						commit
						5bed6c5949
					
				@ -0,0 +1,780 @@
 | 
			
		||||
// 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 <list>
 | 
			
		||||
#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"
 | 
			
		||||
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<char>(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<char>(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<uint16_t>(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<uint16_t>(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<uint32_t>(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<uint32_t>(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 <uint64_t> 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<Token*> 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<char>(*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<char>(*(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 <DFHack::t_memrange>& selected_ranges)
 | 
			
		||||
{
 | 
			
		||||
    vector <DFHack::t_memrange> 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:" <<endl;
 | 
			
		||||
    vector <DFHack::t_memrange>::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 <uint64_t> &found, const char * what)
 | 
			
		||||
{
 | 
			
		||||
    cout << what << ":" << endl;
 | 
			
		||||
    for(int 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(int 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class TokenFactory
 | 
			
		||||
{
 | 
			
		||||
    DFHack::OSType platform;
 | 
			
		||||
public:
 | 
			
		||||
    TokenFactory(DFHack::OSType platform_in)
 | 
			
		||||
    {
 | 
			
		||||
        platform = platform_in;
 | 
			
		||||
    }
 | 
			
		||||
    template <class T>
 | 
			
		||||
    T * Build()
 | 
			
		||||
    {
 | 
			
		||||
        return new T;
 | 
			
		||||
    }
 | 
			
		||||
    template <class T>
 | 
			
		||||
    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 <DFHack::t_memrange>& ranges, DFHack::OSType platform)
 | 
			
		||||
{
 | 
			
		||||
    cout << "stealing memory..." << endl;
 | 
			
		||||
    SegmentedFinder sf(ranges, DF);
 | 
			
		||||
    TokenFactory tf(platform);
 | 
			
		||||
    cout << "done!" << endl;
 | 
			
		||||
    Struct maps;
 | 
			
		||||
    maps.Add(tf.Build<String>());
 | 
			
		||||
    maps.Add(tf.Build<String>());
 | 
			
		||||
    /*
 | 
			
		||||
    vector <uint64_t> allVectors;
 | 
			
		||||
    vector <uint64_t> filtVectors;
 | 
			
		||||
    vector <uint64_t> to_filter;
 | 
			
		||||
 | 
			
		||||
    cout << "stealing memory..." << endl;
 | 
			
		||||
    SegmentedFinder sf(ranges, DF);
 | 
			
		||||
    cout << "looking for vectors..." << endl;
 | 
			
		||||
    sf.Find<int ,vecTriplet>(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<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(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;
 | 
			
		||||
 | 
			
		||||
    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");
 | 
			
		||||
 | 
			
		||||
    // 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;
 | 
			
		||||
        }
 | 
			
		||||
    }*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 <DFHack::t_memrange> 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;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,27 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
#include <climits>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue