Factor out microsoft string handling functions.

develop
Tom Prince 2011-02-23 15:55:07 -05:00
parent aac3056b12
commit 4806318494
5 changed files with 156 additions and 105 deletions

@ -31,8 +31,8 @@ SET(PROJECT_HDRS_INTERNAL
private/Internal.h private/Internal.h
private/SHMProcess.h private/SHMProcess.h
private/LinuxProcess.h private/LinuxProcess.h
private/WindowsProcess.h
private/ProcessFactory.h private/ProcessFactory.h
private/MicrosoftSTL.h
) )
SET(PROJECT_HDRS SET(PROJECT_HDRS
@ -94,6 +94,7 @@ DFTileTypes.cpp
DFProcessEnumerator.cpp DFProcessEnumerator.cpp
ContextShared.cpp ContextShared.cpp
DFProcess-SHM.cpp DFProcess-SHM.cpp
MicrosoftSTL.cpp
depends/md5/md5.cpp depends/md5/md5.cpp
depends/md5/md5wrapper.cpp depends/md5/md5wrapper.cpp

@ -24,6 +24,7 @@ distribution.
#include "Internal.h" #include "Internal.h"
#include "LinuxProcess.h" #include "LinuxProcess.h"
#include "ProcessFactory.h" #include "ProcessFactory.h"
#include "MicrosoftSTL.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/DFError.h" #include "dfhack/DFError.h"
#include <errno.h> #include <errno.h>
@ -35,9 +36,7 @@ namespace {
class WineProcess : public LinuxProcessBase class WineProcess : public LinuxProcessBase
{ {
private: private:
uint32_t STLSTR_buf_off; MicrosoftSTL stl;
uint32_t STLSTR_size_off;
uint32_t STLSTR_cap_off;
public: public:
WineProcess(uint32_t pid, std::vector <VersionInfo *> & known_versions); WineProcess(uint32_t pid, std::vector <VersionInfo *> & known_versions);
@ -133,10 +132,7 @@ bool WineProcess::validate(char * exe_file,uint32_t pid, char * memFile, vector
memFile = memFile; memFile = memFile;
identified = true; identified = true;
OffsetGroup * strGrp = my_descriptor->getGroup("string")->getGroup("MSVC"); stl.init(this);
STLSTR_buf_off = strGrp->getOffset("buffer");
STLSTR_size_off = strGrp->getOffset("size");
STLSTR_cap_off = strGrp->getOffset("capacity");
return true; return true;
} }
} }
@ -152,57 +148,15 @@ bool WineProcess::validate(char * exe_file,uint32_t pid, char * memFile, vector
size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{ {
uint32_t start_offset = offset + STLSTR_buf_off; return stl.readSTLString(offset, buffer, bufcapacity);
size_t length = Process::readDWord(offset + STLSTR_size_off);
size_t capacity = Process::readDWord(offset + STLSTR_cap_off);
size_t read_real = min(length, bufcapacity-1);// keep space for null termination
// read data from inside the string structure
if(capacity < 16)
{
read(start_offset, read_real , (uint8_t *)buffer);
}
else // read data from what the offset + 4 dword points to
{
start_offset = Process::readDWord(start_offset);// dereference the start offset
read(start_offset, read_real, (uint8_t *)buffer);
}
buffer[read_real] = 0;
return read_real;
} }
const string WineProcess::readSTLString (uint32_t offset) const string WineProcess::readSTLString (uint32_t offset)
{ {
uint32_t start_offset = offset + STLSTR_buf_off; return stl.readSTLString(offset);
size_t length = Process::readDWord(offset + STLSTR_size_off);
size_t capacity = Process::readDWord(offset + STLSTR_cap_off);
char * temp = new char[capacity+1];
// read data from inside the string structure
if(capacity < 16)
{
read(start_offset, capacity, (uint8_t *)temp);
}
else // read data from what the offset + 4 dword points to
{
start_offset = Process::readDWord(start_offset);// dereference the start offset
read(start_offset, capacity, (uint8_t *)temp);
}
temp[length] = 0;
string ret = temp;
delete temp;
return ret;
} }
string WineProcess::readClassName (uint32_t vptr) string WineProcess::readClassName (uint32_t vptr)
{ {
int rtti = Process::readDWord(vptr - 0x4); stl.readClassName(vptr);
int typeinfo = Process::readDWord(rtti + 0xC);
string raw = readCString(typeinfo + 0xC); // skips the .?AV
raw.resize(raw.length() - 2);// trim @@ from end
return raw;
} }

@ -24,6 +24,7 @@ distribution.
#include "Internal.h" #include "Internal.h"
#include "WindowsProcess.h" #include "WindowsProcess.h"
#include "ProcessFactory.h" #include "ProcessFactory.h"
#include "MicrosoftSTL.h"
#include "dfhack/VersionInfo.h" #include "dfhack/VersionInfo.h"
#include "dfhack/DFError.h" #include "dfhack/DFError.h"
#include <string.h> #include <string.h>
@ -42,12 +43,10 @@ namespace
bool attached; bool attached;
bool suspended; bool suspended;
bool identified; bool identified;
uint32_t STLSTR_buf_off;
uint32_t STLSTR_size_off;
uint32_t STLSTR_cap_off;
IMAGE_NT_HEADERS pe_header; IMAGE_NT_HEADERS pe_header;
IMAGE_SECTION_HEADER * sections; IMAGE_SECTION_HEADER * sections;
uint32_t base; uint32_t base;
MicrosoftSTL stl;
public: public:
NormalProcess(uint32_t pid, std::vector <VersionInfo *> & known_versions); NormalProcess(uint32_t pid, std::vector <VersionInfo *> & known_versions);
~NormalProcess(); ~NormalProcess();
@ -194,10 +193,7 @@ NormalProcess::NormalProcess(uint32_t pid, vector <VersionInfo *> & known_versio
vector<uint32_t> threads; vector<uint32_t> threads;
getThreadIDs( threads ); getThreadIDs( threads );
my_main_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads[0]); my_main_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads[0]);
OffsetGroup * strGrp = my_descriptor->getGroup("string")->getGroup("MSVC"); stl.init(this);
STLSTR_buf_off = strGrp->getOffset("buffer");
STLSTR_size_off = strGrp->getOffset("size");
STLSTR_cap_off = strGrp->getOffset("capacity");
found = true; found = true;
break; // break the iterator loop break; // break the iterator loop
} }
@ -552,59 +548,17 @@ const string NormalProcess::readCString (const uint32_t offset)
size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{ {
uint32_t start_offset = offset + STLSTR_buf_off; return stl.readSTLString(offset, buffer, bufcapacity);
size_t length = Process::readDWord(offset + STLSTR_size_off);
size_t capacity = Process::readDWord(offset + STLSTR_cap_off);
size_t read_real = min(length, bufcapacity-1);// keep space for null termination
// read data from inside the string structure
if(capacity < 16)
{
read(start_offset, read_real , (uint8_t *)buffer);
}
else // read data from what the offset + 4 dword points to
{
start_offset = Process::readDWord(start_offset);// dereference the start offset
read(start_offset, read_real, (uint8_t *)buffer);
}
buffer[read_real] = 0;
return read_real;
} }
const string NormalProcess::readSTLString (uint32_t offset) const string NormalProcess::readSTLString (uint32_t offset)
{ {
uint32_t start_offset = offset + STLSTR_buf_off; return stl.readSTLString(offset);
size_t length = Process::readDWord(offset + STLSTR_size_off);
size_t capacity = Process::readDWord(offset + STLSTR_cap_off);
char * temp = new char[capacity+1];
// read data from inside the string structure
if(capacity < 16)
{
read(start_offset, capacity, (uint8_t *)temp);
}
else // read data from what the offset + 4 dword points to
{
start_offset = Process::readDWord(start_offset);// dereference the start offset
read(start_offset, capacity, (uint8_t *)temp);
}
temp[length] = 0;
string ret = temp;
delete temp;
return ret;
} }
string NormalProcess::readClassName (uint32_t vptr) string NormalProcess::readClassName (uint32_t vptr)
{ {
int rtti = Process::readDWord(vptr - 0x4); stl.readClassName(vptr);
int typeinfo = Process::readDWord(rtti + 0xC);
string raw = readCString(typeinfo + 0xC); // skips the .?AV
raw.resize(raw.length() - 2);// trim @@ from end
return raw;
} }
string NormalProcess::getPath() string NormalProcess::getPath()

@ -0,0 +1,96 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "Internal.h"
#include "MicrosoftSTL.h"
#include "dfhack/DFProcess.h"
#include "dfhack/VersionInfo.h"
#include <string>
using namespace DFHack;
void MicrosoftSTL::init(Process* self)
{
p = self;
OffsetGroup * strGrp = p->getDescriptor()->getGroup("string")->getGroup("MSVC");
STLSTR_buf_off = strGrp->getOffset("buffer");
STLSTR_size_off = strGrp->getOffset("size");
STLSTR_cap_off = strGrp->getOffset("capacity");
}
size_t MicrosoftSTL::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{
uint32_t start_offset = offset + STLSTR_buf_off;
size_t length = p->readDWord(offset + STLSTR_size_off);
size_t capacity = p->readDWord(offset + STLSTR_cap_off);
size_t read_real = min(length, bufcapacity-1);// keep space for null termination
// read data from inside the string structure
if(capacity < 16)
{
p->read(start_offset, read_real , (uint8_t *)buffer);
}
else // read data from what the offset + 4 dword points to
{
start_offset = p->readDWord(start_offset);// dereference the start offset
p->read(start_offset, read_real, (uint8_t *)buffer);
}
buffer[read_real] = 0;
return read_real;
}
const string MicrosoftSTL::readSTLString (uint32_t offset)
{
uint32_t start_offset = offset + STLSTR_buf_off;
size_t length = p->readDWord(offset + STLSTR_size_off);
size_t capacity = p->readDWord(offset + STLSTR_cap_off);
char * temp = new char[capacity+1];
// read data from inside the string structure
if(capacity < 16)
{
p->read(start_offset, capacity, (uint8_t *)temp);
}
else // read data from what the offset + 4 dword points to
{
start_offset = p->readDWord(start_offset);// dereference the start offset
p->read(start_offset, capacity, (uint8_t *)temp);
}
temp[length] = 0;
string ret = temp;
delete temp;
return ret;
}
string MicrosoftSTL::readClassName (uint32_t vptr)
{
int rtti = p->readDWord(vptr - 0x4);
int typeinfo = p->readDWord(rtti + 0xC);
string raw = p->readCString(typeinfo + 0xC); // skips the .?AV
raw.resize(raw.length() - 2);// trim @@ from end
return raw;
}

@ -0,0 +1,46 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <string>
namespace DFHack {
class Process;
class MicrosoftSTL
{
private:
uint32_t STLSTR_buf_off;
uint32_t STLSTR_size_off;
uint32_t STLSTR_cap_off;
Process* p;
public:
void init(Process* p);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){};
// get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr);
};
}