cursor/window offsets for all versions, finished incremental search tool

develop
Petr Mrázek 2009-11-15 20:41:10 +00:00
parent 7e3af38941
commit b8c9a36897
3 changed files with 216 additions and 16 deletions

@ -114,6 +114,7 @@ void Process::getMemRanges( vector<t_memrange> & ranges )
while (fgets(buffer, 1024, mapFile)) while (fgets(buffer, 1024, mapFile))
{ {
t_memrange temp; t_memrange temp;
temp.name[0] = 0;
sscanf(buffer, "%llx-%llx %s %llx %2llu:%2llu %llu %s", sscanf(buffer, "%llx-%llx %s %llx %2llu:%2llu %llu %s",
&temp.start, &temp.start,
&temp.end, &temp.end,

@ -734,6 +734,11 @@
<class vtable="0x0097c84c" name="archery_target"/> <class vtable="0x0097c84c" name="archery_target"/>
<class vtable="0x0097cdcc" name="restraint"/> <class vtable="0x0097cdcc" name="restraint"/>
</VTable> </VTable>
<Address name="cursor_xyz">0x9fc294</Address>
<Address name="window_x">0xd457f4</Address>
<Address name="window_y">0xd73868</Address>
<Address name="window_z">0xd73844</Address>
</Entry> </Entry>
<!-- Windows 40d## sub-versions, should inherit only vtable from 40d --> <!-- Windows 40d## sub-versions, should inherit only vtable from 40d -->
<Entry version="v0.28.181.40d9" os="windows" id="40d9win" base="40dwin"> <Entry version="v0.28.181.40d9" os="windows" id="40d9win" base="40dwin">
@ -819,6 +824,10 @@
<multiclass name="furnace" typeoffset="0x11A" /> <multiclass name="furnace" typeoffset="0x11A" />
<multiclass name="mechanism" typeoffset="0x100" /> <multiclass name="mechanism" typeoffset="0x100" />
</VTable> </VTable>
<Address name="cursor_xyz">0x9662a4</Address>
<Address name="window_x">0xcae368</Address>
<Address name="window_y">0xcdc3dc</Address>
<Address name="window_z">0xcdc3b8</Address>
</Entry> </Entry>
<Entry version="v0.28.181.40d11" os="windows" rebase="0x2d388" id="40d11win" base="40d9win"> <Entry version="v0.28.181.40d11" os="windows" rebase="0x2d388" id="40d11win" base="40d9win">
<!-- identification --> <!-- identification -->
@ -826,6 +835,10 @@
<String name="md5">6f81231b845e9c9dc29aaf57705ccc7c</String> <String name="md5">6f81231b845e9c9dc29aaf57705ccc7c</String>
<!-- door: 0x8e91e4 --> <!-- door: 0x8e91e4 -->
<VTable rebase="-0x1000" /> <VTable rebase="-0x1000" />
<Address name="cursor_xyz">0x9652a4</Address>
<Address name="window_x">0xcdf5a0</Address>
<Address name="window_y">0xd0d64c</Address>
<Address name="window_z">0xd0d628</Address>
</Entry> </Entry>
<Entry version="v0.28.181.40d12" os="windows" id="40d12win" base="40d11win"> <Entry version="v0.28.181.40d12" os="windows" id="40d12win" base="40d11win">
<!-- identification --> <!-- identification -->
@ -859,7 +872,11 @@
<Address name="matgloss">0x015FCE3C</Address> <Address name="matgloss">0x015FCE3C</Address>
<!-- door: 0x8db5e4 --> <!-- door: 0x8db5e4 -->
<VTable rebase="-0xDC00" /> <VTable rebase="-0xDC00" />
<Address name="cursor_xyz">0x95f2b4</Address>
<Address name="window_x">0xd995a0</Address>
<Address name="window_y">0xdc764c</Address>
<Address name="window_z">0xdc7628</Address>
</Entry> </Entry>
<Entry version="v0.28.181.40d13" os="windows" id="40d13win" base="40d12win" rebase="0x5090"> <Entry version="v0.28.181.40d13" os="windows" id="40d13win" base="40d12win" rebase="0x5090">
<!-- identification --> <!-- identification -->
@ -868,6 +885,10 @@
<!-- map_data = 0x015FFD5C --> <!-- map_data = 0x015FFD5C -->
<!-- door: 0x8df5ec --> <!-- door: 0x8df5ec -->
<VTable rebase="0x4008" /> <VTable rebase="0x4008" />
<Address name="cursor_xyz">0x009642b4</Address>
<Address name="window_x">0x00d9e600</Address>
<Address name="window_y">0x00dcc6ac</Address>
<Address name="window_z">0x00dcc688</Address>
</Entry> </Entry>
<Entry version="v0.28.181.40d14" os="windows" id="40d14win" base="40d13win" rebase="0x2010"> <Entry version="v0.28.181.40d14" os="windows" id="40d14win" base="40d13win" rebase="0x2010">
<!-- identification --> <!-- identification -->
@ -876,6 +897,10 @@
<!-- map_data = 0x01601D6C --> <!-- map_data = 0x01601D6C -->
<!-- door: 0x8e15dc --> <!-- door: 0x8e15dc -->
<VTable rebase="0x1FF0" /> <VTable rebase="0x1FF0" />
<Address name="cursor_xyz">0x009662B4</Address>
<Address name="window_x">0x00DA060C</Address>
<Address name="window_y">0x00DCE6B8</Address>
<Address name="window_z">0x00DCE694</Address>
</Entry> </Entry>
<Entry version="v0.28.181.40d15" os="windows" id="40d15win" base="40d14win" rebase="0x18"> <Entry version="v0.28.181.40d15" os="windows" id="40d15win" base="40d14win" rebase="0x18">
<!-- identification --> <!-- identification -->
@ -884,6 +909,10 @@
<!-- map_data = 0x01601D84 --> <!-- map_data = 0x01601D84 -->
<!-- door: 0x8e15d4 --> <!-- door: 0x8e15d4 -->
<VTable rebase="-0x8" /> <VTable rebase="-0x8" />
<Address name="cursor_xyz">0x009662B4</Address>
<Address name="window_x">0x00DA061C</Address>
<Address name="window_y">0x00DCE6C8</Address>
<Address name="window_z">0x00DCE6A4</Address>
</Entry> </Entry>
<Entry version="v0.28.181.40d16" os="windows" base="40d15win"> <Entry version="v0.28.181.40d16" os="windows" base="40d15win">
<!-- identification --> <!-- identification -->
@ -891,19 +920,6 @@
<String name="md5">59ab29021aca9f3c66b1ab102fb3ceea</String> <String name="md5">59ab29021aca9f3c66b1ab102fb3ceea</String>
<!-- map_data = 0x01601D84 --> <!-- map_data = 0x01601D84 -->
<!-- door: 0x8e15d4, no VTable rebase needed --> <!-- door: 0x8e15d4, no VTable rebase needed -->
<Address name="cursor_xyz">0x009662B4</Address>
<Address name="window_x">0x00DA061C</Address>
<Address name="window_y">0x00DCE6C8</Address>
<Address name="window_z">0x00DCE6A4</Address>
<!--
<belal> for windows d16
<belal> designation x 0x009662B4
<belal> designation y 0x009662B8
<belal> designation z 0x009662BC
<belal> window x 0x00DA061C
<belal> window y 0x00DCE6C8
<belal> window z 0x00DCE6A4
-->
</Entry> </Entry>
.-"""-. .-"""-.
@ -941,6 +957,11 @@
<!--<Address name="buildings">0x09332EF0</Address>--> <!--<Address name="buildings">0x09332EF0</Address>-->
<Address name="vegetation">0x09335CB0</Address> <Address name="vegetation">0x09335CB0</Address>
<Address name="creatures">0x093326AC</Address> <Address name="creatures">0x093326AC</Address>
<Address name="cursor_xyz">0x8877634</Address>
<Address name="window_x">0x8d17ff4</Address>
<Address name="window_y">0x8d17ff8</Address>
<Address name="window_z">0x8d17ffC</Address>
<!-- translation tables --> <!-- translation tables -->
<Address name="translation_vector">0x09374FA8</Address> <Address name="translation_vector">0x09374FA8</Address>
@ -1107,6 +1128,7 @@
<String name="md5">fb8ecac8a12af5d0d7b1707078985d0d</String> <String name="md5">fb8ecac8a12af5d0d7b1707078985d0d</String>
<!--TODO: <Address name="notes">0x092ab244</Address>--> <!--TODO: <Address name="notes">0x092ab244</Address>-->
<VTable rebase="-0x5e360" /> <VTable rebase="-0x5e360" />
<Address name="cursor_xyz">0x88073d4</Address>
</Entry> </Entry>
<!-- re-specified addresses here, offsets and hexvals remain same --> <!-- re-specified addresses here, offsets and hexvals remain same -->
<Entry version="v0.28.181.40d12" os="linux" base="40d9lin" id="40d12lin"> <Entry version="v0.28.181.40d12" os="linux" base="40d9lin" id="40d12lin">
@ -1119,7 +1141,12 @@
<Address name="buildings">0x08F55740</Address> <Address name="buildings">0x08F55740</Address>
<Address name="vegetation">0x08F58890</Address> <Address name="vegetation">0x08F58890</Address>
<Address name="creatures">0x08F55250</Address> <Address name="creatures">0x08F55250</Address>
<Address name="cursor_xyz">0x0877B33C</Address>
<Address name="window_x">0x893ABD4</Address>
<Address name="window_y">0x893ABD8</Address>
<Address name="window_z">0x893ABDC</Address>
<!-- translation tables --> <!-- translation tables -->
<!-- these should be right --> <!-- these should be right -->
<Address name="translation_vector">0x08F97BA4</Address> <Address name="translation_vector">0x08F97BA4</Address>
@ -1148,6 +1175,7 @@
<String name="md5">2f3cb9d720e9fe8844c02c72a2b20bbd</String> <String name="md5">2f3cb9d720e9fe8844c02c72a2b20bbd</String>
<!-- map_data = 0x8F9ABDC --> <!-- map_data = 0x8F9ABDC -->
<VTable rebase="0x3A00" /> <VTable rebase="0x3A00" />
<Address name="cursor_xyz">0x8780354</Address>
<!--<class vtable="0x086C7368" name="door"/>--> <!--<class vtable="0x086C7368" name="door"/>-->
</Entry> </Entry>
<Entry version="v0.28.181.40d14" os="linux" id="40d14lin" base="40d13lin"> <Entry version="v0.28.181.40d14" os="linux" id="40d14lin" base="40d13lin">
@ -1170,7 +1198,6 @@
<!-- map_data = 0x8F9ABDC --> <!-- map_data = 0x8F9ABDC -->
<!--<class vtable="0x086c78c8" name="door"/>--> <!--<class vtable="0x086c78c8" name="door"/>-->
</Entry> </Entry>
</MemoryDescriptors> </MemoryDescriptors>
<!-- Windows logo by M$, spiderweb by jgs --> <!-- Windows logo by M$, spiderweb by jgs -->
</DFExtractor> </DFExtractor>

@ -6,10 +6,15 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <ctime> #include <ctime>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std; using namespace std;
#ifndef LINUX_BUILD #ifndef LINUX_BUILD
#define WINVER 0x0500 #define WINVER 0x0500
// this one prevents windows from infecting the global namespace with filth
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#endif #endif
@ -17,9 +22,82 @@ using namespace std;
#include <DFTypes.h> #include <DFTypes.h>
#include <DFHackAPI.h> #include <DFHackAPI.h>
#include <DFProcessManager.h> #include <DFProcessManager.h>
#include <DFMemInfo.h>
//TODO: lots of optimization
void searchLoop(DFHack::API & DF, vector <DFHack::t_memrange>& ranges, int size, int alignment)
{
int32_t test1;
int32_t test2;
vector <int64_t> found;
vector <int64_t> newfound;
found.reserve(100000);
newfound.reserve(100000);
//bool initial = 1;
cout << "search ready - insert integers, 'p' for results" << endl;
string select;
while (1)
{
cout << ">>";
DF.Detach();
std::getline(cin, select);
DF.Attach();
if(select == "p")
{
cout << "Found addresses:" << endl;
for(int i = 0; i < found.size();i++)
{
cout << hex << "0x" << found[i] << endl;
}
}
else if(sscanf(select.c_str(),"%d", &test1) == 1)
{
newfound.clear();
bool initial = found.empty();
if(initial)
{
// for each range
for (int i = 0; i < ranges.size();i++)
{
// can't read? range is invalid to us
if(!ranges[i].read)
continue;
//loop
for(uint64_t offset = ranges[i].start;offset <= ranges[i].end - size; offset+=alignment)
{
DF.ReadRaw(offset, size, (uint8_t *) &test2);
if(test1 == test2 )
found.push_back(offset);
}
}
cout << "found " << found.size() << " addresses" << endl;
}
else
{
for(int j = 0; j < found.size();j++)
{
DF.ReadRaw(found[j], size, (uint8_t *) &test2);
if(test1 == test2)
{
newfound.push_back(found[j]);
}
}
cout << "matched " << newfound.size() << " addresses out of " << found.size() << endl;
found = newfound;
}
}
else break;
}
}
int main (void) int main (void)
{ {
string select;
DFHack::API DF("Memory.xml"); DFHack::API DF("Memory.xml");
if(!DF.Attach()) if(!DF.Attach())
{ {
@ -28,11 +106,105 @@ int main (void)
} }
DFHack::Process * p = DF.getProcess(); DFHack::Process * p = DF.getProcess();
vector <DFHack::t_memrange> ranges; vector <DFHack::t_memrange> ranges;
vector <DFHack::t_memrange> selected_ranges;
p->getMemRanges(ranges); p->getMemRanges(ranges);
cout << "Which range to search? (default is 1-4)" << endl;
for(int i = 0; i< ranges.size();i++) for(int i = 0; i< ranges.size();i++)
{ {
cout << dec << "(" << i << ") ";
ranges[i].print(); ranges[i].print();
} }
try_again_ranges:
cout << ">>";
std::getline(cin, select);
int start, end;
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++)
{
selected_ranges[i].print();
}
// input / validation of variable size
try_again_size:
cout << "Select searched variable size (1,2,4 bytes, default is 4)" << endl;
cout << ">>";
std::getline(cin, select);
int size;
if(select.empty())
{
size = 4;
}
else if( sscanf(select.c_str(), "%d", &size) == 1 )
{
if(/*size != 8 &&*/ size != 4 && size != 2 && size != 1)
{
goto try_again_size;
}
}
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;
}
searchLoop(DF,selected_ranges, size, alignment);
// initial value
// cycle until you get only a few offsets (~10?)
if(!DF.Detach()) if(!DF.Detach())
{ {