From 48063184948bd03fcd528ca47fbda301d75a1143 Mon Sep 17 00:00:00 2001 From: Tom Prince Date: Wed, 23 Feb 2011 15:55:07 -0500 Subject: [PATCH] Factor out microsoft string handling functions. --- library/CMakeLists.txt | 3 +- library/DFProcess-linux-wine.cpp | 58 ++----------------- library/DFProcess-windows.cpp | 58 ++----------------- library/MicrosoftSTL.cpp | 96 ++++++++++++++++++++++++++++++++ library/private/MicrosoftSTL.h | 46 +++++++++++++++ 5 files changed, 156 insertions(+), 105 deletions(-) create mode 100644 library/MicrosoftSTL.cpp create mode 100644 library/private/MicrosoftSTL.h diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index d54fc79d5..fdf49f8d3 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -31,8 +31,8 @@ SET(PROJECT_HDRS_INTERNAL private/Internal.h private/SHMProcess.h private/LinuxProcess.h - private/WindowsProcess.h private/ProcessFactory.h + private/MicrosoftSTL.h ) SET(PROJECT_HDRS @@ -94,6 +94,7 @@ DFTileTypes.cpp DFProcessEnumerator.cpp ContextShared.cpp DFProcess-SHM.cpp +MicrosoftSTL.cpp depends/md5/md5.cpp depends/md5/md5wrapper.cpp diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp index a75b8077d..7f28f8d9e 100644 --- a/library/DFProcess-linux-wine.cpp +++ b/library/DFProcess-linux-wine.cpp @@ -24,6 +24,7 @@ distribution. #include "Internal.h" #include "LinuxProcess.h" #include "ProcessFactory.h" +#include "MicrosoftSTL.h" #include "dfhack/VersionInfo.h" #include "dfhack/DFError.h" #include @@ -35,9 +36,7 @@ namespace { class WineProcess : public LinuxProcessBase { private: - uint32_t STLSTR_buf_off; - uint32_t STLSTR_size_off; - uint32_t STLSTR_cap_off; + MicrosoftSTL stl; public: WineProcess(uint32_t pid, std::vector & known_versions); @@ -133,10 +132,7 @@ bool WineProcess::validate(char * exe_file,uint32_t pid, char * memFile, vector memFile = memFile; identified = true; - OffsetGroup * strGrp = my_descriptor->getGroup("string")->getGroup("MSVC"); - STLSTR_buf_off = strGrp->getOffset("buffer"); - STLSTR_size_off = strGrp->getOffset("size"); - STLSTR_cap_off = strGrp->getOffset("capacity"); + stl.init(this); 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) { - uint32_t start_offset = offset + STLSTR_buf_off; - 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; + return stl.readSTLString(offset, buffer, bufcapacity); } const string WineProcess::readSTLString (uint32_t offset) { - uint32_t start_offset = offset + STLSTR_buf_off; - 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; + return stl.readSTLString(offset); } string WineProcess::readClassName (uint32_t vptr) { - int rtti = Process::readDWord(vptr - 0x4); - int typeinfo = Process::readDWord(rtti + 0xC); - string raw = readCString(typeinfo + 0xC); // skips the .?AV - raw.resize(raw.length() - 2);// trim @@ from end - return raw; + stl.readClassName(vptr); } diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp index a094e1e0f..da0055709 100644 --- a/library/DFProcess-windows.cpp +++ b/library/DFProcess-windows.cpp @@ -24,6 +24,7 @@ distribution. #include "Internal.h" #include "WindowsProcess.h" #include "ProcessFactory.h" +#include "MicrosoftSTL.h" #include "dfhack/VersionInfo.h" #include "dfhack/DFError.h" #include @@ -42,12 +43,10 @@ namespace bool attached; bool suspended; bool identified; - uint32_t STLSTR_buf_off; - uint32_t STLSTR_size_off; - uint32_t STLSTR_cap_off; IMAGE_NT_HEADERS pe_header; IMAGE_SECTION_HEADER * sections; uint32_t base; + MicrosoftSTL stl; public: NormalProcess(uint32_t pid, std::vector & known_versions); ~NormalProcess(); @@ -194,10 +193,7 @@ NormalProcess::NormalProcess(uint32_t pid, vector & known_versio vector threads; getThreadIDs( threads ); my_main_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads[0]); - OffsetGroup * strGrp = my_descriptor->getGroup("string")->getGroup("MSVC"); - STLSTR_buf_off = strGrp->getOffset("buffer"); - STLSTR_size_off = strGrp->getOffset("size"); - STLSTR_cap_off = strGrp->getOffset("capacity"); + stl.init(this); found = true; 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) { - uint32_t start_offset = offset + STLSTR_buf_off; - 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; + return stl.readSTLString(offset, buffer, bufcapacity); } const string NormalProcess::readSTLString (uint32_t offset) { - uint32_t start_offset = offset + STLSTR_buf_off; - 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; + return stl.readSTLString(offset); } string NormalProcess::readClassName (uint32_t vptr) { - int rtti = Process::readDWord(vptr - 0x4); - int typeinfo = Process::readDWord(rtti + 0xC); - string raw = readCString(typeinfo + 0xC); // skips the .?AV - raw.resize(raw.length() - 2);// trim @@ from end - return raw; + stl.readClassName(vptr); } string NormalProcess::getPath() diff --git a/library/MicrosoftSTL.cpp b/library/MicrosoftSTL.cpp new file mode 100644 index 000000000..9d619600e --- /dev/null +++ b/library/MicrosoftSTL.cpp @@ -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 +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; +} diff --git a/library/private/MicrosoftSTL.h b/library/private/MicrosoftSTL.h new file mode 100644 index 000000000..a25ee1797 --- /dev/null +++ b/library/private/MicrosoftSTL.h @@ -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 + +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); + }; +}