From e85b4291271b63cf66605681ebaa74a76acc4fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 13 Apr 2010 03:11:26 +0200 Subject: [PATCH] Throw exceptions on memory read errors! Fix reading creatures that have no soul. --- dfhack/DFProcess-linux-SHM.cpp | 36 ++++++------- dfhack/DFProcess-linux-wine.cpp | 21 ++++---- dfhack/DFProcess-linux.cpp | 13 ++--- dfhack/DFProcess-windows-SHM.cpp | 36 ++++++------- dfhack/DFProcess-windows.cpp | 57 +++++++++++++-------- dfhack/include/DFError.h | 6 +-- dfhack/include/modules/Creatures.h | 2 +- dfhack/modules/Buildings.cpp | 4 ++ dfhack/modules/Creatures.cpp | 34 +++++++------ examples/creaturedump.cpp | 82 ++++++++++++++---------------- output/Memory.xml | 1 + 11 files changed, 155 insertions(+), 137 deletions(-) diff --git a/dfhack/DFProcess-linux-SHM.cpp b/dfhack/DFProcess-linux-SHM.cpp index bcc55fb08..8f7951d8d 100644 --- a/dfhack/DFProcess-linux-SHM.cpp +++ b/dfhack/DFProcess-linux-SHM.cpp @@ -608,7 +608,7 @@ bool SHMProcess::detach() void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); // normal read under 1MB if(size <= SHM_BODY) @@ -645,7 +645,7 @@ void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buff uint8_t SHMProcess::readByte (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -655,7 +655,7 @@ uint8_t SHMProcess::readByte (const uint32_t offset) void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -665,7 +665,7 @@ void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) uint16_t SHMProcess::readWord (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -675,7 +675,7 @@ uint16_t SHMProcess::readWord (const uint32_t offset) void SHMProcess::readWord (const uint32_t offset, uint16_t &val) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -685,7 +685,7 @@ void SHMProcess::readWord (const uint32_t offset, uint16_t &val) uint32_t SHMProcess::readDWord (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -694,7 +694,7 @@ uint32_t SHMProcess::readDWord (const uint32_t offset) } void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; gcc_barrier @@ -708,7 +708,7 @@ void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) void SHMProcess::writeDWord (uint32_t offset, uint32_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -719,7 +719,7 @@ void SHMProcess::writeDWord (uint32_t offset, uint32_t data) // using these is expensive. void SHMProcess::writeWord (uint32_t offset, uint16_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -729,7 +729,7 @@ void SHMProcess::writeWord (uint32_t offset, uint16_t data) void SHMProcess::writeByte (uint32_t offset, uint8_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -739,7 +739,7 @@ void SHMProcess::writeByte (uint32_t offset, uint8_t data) void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); // normal write under 1MB if(size <= SHM_BODY) @@ -777,7 +777,7 @@ void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buf // FIXME: butt-fugly const std::string SHMProcess::readCString (uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); std::string temp; char temp_c[256]; @@ -796,7 +796,7 @@ const std::string SHMProcess::readCString (uint32_t offset) const std::string SHMProcess::readSTLString(uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -806,7 +806,7 @@ const std::string SHMProcess::readSTLString(uint32_t offset) size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -820,7 +820,7 @@ size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapa void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = address; strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator @@ -830,7 +830,7 @@ void SHMProcess::writeSTLString(const uint32_t address, const std::string writeS string SHMProcess::readClassName (uint32_t vptr) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); int typeinfo = readDWord(vptr - 0x4); int typestring = readDWord(typeinfo + 0x4); @@ -843,7 +843,7 @@ string SHMProcess::readClassName (uint32_t vptr) // get module index by name and version. bool 0 = error bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); modulelookup * payload = D_SHMDATA(modulelookup); payload->version = version; @@ -873,7 +873,7 @@ char * SHMProcess::getSHMStart (void) bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, pid_t & PID) { - if(!locked) throw Error::SHMAccessDenied(); + if(!locked) throw Error::MemoryAccessDenied(); SHMDATA(coreattach)->cl_affinity = OS_getAffinity(); if(!SetAndWait(CORE_ATTACH)) return false; diff --git a/dfhack/DFProcess-linux-wine.cpp b/dfhack/DFProcess-linux-wine.cpp index da4a11fb2..6177502d3 100644 --- a/dfhack/DFProcess-linux-wine.cpp +++ b/dfhack/DFProcess-linux-wine.cpp @@ -377,6 +377,7 @@ void WineProcess::read (const uint32_t offset, const uint32_t size, uint8_t *tar cerr << "pread failed: can't read " << size << " bytes at addres " << offset << endl; cerr << "errno: " << errno << endl; errno = 0; + throw Error::MemoryAccessDenied(); } else { @@ -516,20 +517,20 @@ size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcap Uint32 capacity */ uint32_t start_offset = offset + 4; - size_t length = g_pProcess->readDWord(offset + 20); + size_t length = readDWord(offset + 20); - size_t capacity = g_pProcess->readDWord(offset + 24); + size_t capacity = readDWord(offset + 24); size_t read_real = min(length, bufcapacity-1);// keep space for null termination // read data from inside the string structure if(capacity < 16) { - g_pProcess->read(start_offset, read_real , (uint8_t *)buffer); + read(start_offset, read_real , (uint8_t *)buffer); } else // read data from what the offset + 4 dword points to { - start_offset = g_pProcess->readDWord(start_offset);// dereference the start offset - g_pProcess->read(start_offset, read_real, (uint8_t *)buffer); + start_offset = readDWord(start_offset);// dereference the start offset + read(start_offset, read_real, (uint8_t *)buffer); } buffer[read_real] = 0; @@ -550,19 +551,19 @@ const string WineProcess::readSTLString (uint32_t offset) Uint32 capacity */ uint32_t start_offset = offset + 4; - uint32_t length = g_pProcess->readDWord(offset + 20); - uint32_t capacity = g_pProcess->readDWord(offset + 24); + uint32_t length = readDWord(offset + 20); + uint32_t capacity = readDWord(offset + 24); char * temp = new char[capacity+1]; // read data from inside the string structure if(capacity < 16) { - g_pProcess->read(start_offset, capacity, (uint8_t *)temp); + read(start_offset, capacity, (uint8_t *)temp); } else // read data from what the offset + 4 dword points to { - start_offset = g_pProcess->readDWord(start_offset);// dereference the start offset - g_pProcess->read(start_offset, capacity, (uint8_t *)temp); + start_offset = readDWord(start_offset);// dereference the start offset + read(start_offset, capacity, (uint8_t *)temp); } temp[length] = 0; diff --git a/dfhack/DFProcess-linux.cpp b/dfhack/DFProcess-linux.cpp index 71220a051..b92c5ca29 100644 --- a/dfhack/DFProcess-linux.cpp +++ b/dfhack/DFProcess-linux.cpp @@ -365,6 +365,7 @@ void NormalProcess::read (const uint32_t offset, const uint32_t size, uint8_t *t cerr << "pread failed: can't read " << size << " bytes at addres " << offset << endl; cerr << "errno: " << errno << endl; errno = 0; + throw Error::MemoryAccessDenied(); } else { @@ -500,10 +501,10 @@ struct _Rep_base size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) { _Rep_base header; - offset = g_pProcess->readDWord(offset); - g_pProcess->read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); + offset = readDWord(offset); + read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); size_t read_real = min((size_t)header._M_length, bufcapacity-1);// keep space for null termination - g_pProcess->read(offset,read_real,(uint8_t * )buffer); + read(offset,read_real,(uint8_t * )buffer); buffer[read_real] = 0; return read_real; } @@ -512,12 +513,12 @@ const string NormalProcess::readSTLString (uint32_t offset) { _Rep_base header; - offset = g_pProcess->readDWord(offset); - g_pProcess->read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); + offset = readDWord(offset); + read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header); // FIXME: use char* everywhere, avoid string char * temp = new char[header._M_length+1]; - g_pProcess->read(offset,header._M_length+1,(uint8_t * )temp); + read(offset,header._M_length+1,(uint8_t * )temp); string ret(temp); delete temp; return ret; diff --git a/dfhack/DFProcess-windows-SHM.cpp b/dfhack/DFProcess-windows-SHM.cpp index 49ceabeac..5f776e93a 100644 --- a/dfhack/DFProcess-windows-SHM.cpp +++ b/dfhack/DFProcess-windows-SHM.cpp @@ -669,7 +669,7 @@ bool SHMProcess::detach() void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); // normal read under 1MB if(size <= SHM_BODY) @@ -706,7 +706,7 @@ void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buff uint8_t SHMProcess::readByte (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -716,7 +716,7 @@ uint8_t SHMProcess::readByte (const uint32_t offset) void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -726,7 +726,7 @@ void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) uint16_t SHMProcess::readWord (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -736,7 +736,7 @@ uint16_t SHMProcess::readWord (const uint32_t offset) void SHMProcess::readWord (const uint32_t offset, uint16_t &val) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -746,7 +746,7 @@ void SHMProcess::readWord (const uint32_t offset, uint16_t &val) uint32_t SHMProcess::readDWord (const uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -755,7 +755,7 @@ uint32_t SHMProcess::readDWord (const uint32_t offset) } void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -769,7 +769,7 @@ void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) void SHMProcess::writeDWord (uint32_t offset, uint32_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -780,7 +780,7 @@ void SHMProcess::writeDWord (uint32_t offset, uint32_t data) // using these is expensive. void SHMProcess::writeWord (uint32_t offset, uint16_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -790,7 +790,7 @@ void SHMProcess::writeWord (uint32_t offset, uint16_t data) void SHMProcess::writeByte (uint32_t offset, uint8_t data) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; D_SHMHDR->value = data; @@ -800,7 +800,7 @@ void SHMProcess::writeByte (uint32_t offset, uint8_t data) void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); // normal write under 1MB if(size <= SHM_BODY) @@ -838,7 +838,7 @@ void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buf // FIXME: butt-fugly const std::string SHMProcess::readCString (uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); std::string temp; char temp_c[256]; @@ -857,7 +857,7 @@ const std::string SHMProcess::readCString (uint32_t offset) const std::string SHMProcess::readSTLString(uint32_t offset) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -867,7 +867,7 @@ const std::string SHMProcess::readSTLString(uint32_t offset) size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = offset; full_barrier @@ -881,7 +881,7 @@ size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapa void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); D_SHMHDR->address = address; strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator @@ -901,7 +901,7 @@ string SHMProcess::readClassName (uint32_t vptr) // get module index by name and version. bool 0 = error bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); modulelookup * payload = D_SHMDATA(modulelookup); payload->version = version; @@ -924,13 +924,13 @@ bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint char * SHMProcess::getSHMStart (void) { - if(!d->locked) throw Error::SHMAccessDenied(); + if(!d->locked) throw Error::MemoryAccessDenied(); return /*d->shm_addr_with_cl_idx*/ d->shm_addr; } bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, uint32_t & PID) { - if(!locked) throw Error::SHMAccessDenied(); + if(!locked) throw Error::MemoryAccessDenied(); SHMDATA(coreattach)->cl_affinity = OS_getAffinity(); if(!SetAndWait(CORE_ATTACH)) return false; diff --git a/dfhack/DFProcess-windows.cpp b/dfhack/DFProcess-windows.cpp index b1dac9568..00a3b56d2 100644 --- a/dfhack/DFProcess-windows.cpp +++ b/dfhack/DFProcess-windows.cpp @@ -315,64 +315,75 @@ void NormalProcess::getMemRanges( vector & ranges ) uint8_t NormalProcess::readByte (const uint32_t offset) { uint8_t result; - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint8_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint8_t), NULL)) + throw Error::MemoryAccessDenied(); return result; } void NormalProcess::readByte (const uint32_t offset,uint8_t &result) { - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint8_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint8_t), NULL)) + throw Error::MemoryAccessDenied(); } uint16_t NormalProcess::readWord (const uint32_t offset) { uint16_t result; - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint16_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint16_t), NULL)) + throw Error::MemoryAccessDenied(); return result; } void NormalProcess::readWord (const uint32_t offset, uint16_t &result) { - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint16_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint16_t), NULL)) + throw Error::MemoryAccessDenied(); } uint32_t NormalProcess::readDWord (const uint32_t offset) { uint32_t result; - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint32_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint32_t), NULL)) + throw Error::MemoryAccessDenied(); return result; } void NormalProcess::readDWord (const uint32_t offset, uint32_t &result) { - ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint32_t), NULL); + if(!ReadProcessMemory(d->my_handle, (int*) offset, &result, sizeof(uint32_t), NULL)) + throw Error::MemoryAccessDenied(); } void NormalProcess::read (const uint32_t offset, uint32_t size, uint8_t *target) { - ReadProcessMemory(d->my_handle, (int*) offset, target, size, NULL); + if(ReadProcessMemory(d->my_handle, (int*) offset, target, size, NULL)) + throw Error::MemoryAccessDenied(); } // WRITING void NormalProcess::writeDWord (const uint32_t offset, uint32_t data) { - WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint32_t), NULL); + if(!WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint32_t), NULL)) + throw Error::MemoryAccessDenied(); } // using these is expensive. void NormalProcess::writeWord (uint32_t offset, uint16_t data) { - WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint16_t), NULL); + if(!WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint16_t), NULL)) + throw Error::MemoryAccessDenied(); } void NormalProcess::writeByte (uint32_t offset, uint8_t data) { - WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint8_t), NULL); + if(!WriteProcessMemory(d->my_handle, (int*) offset, &data, sizeof(uint8_t), NULL)) + throw Error::MemoryAccessDenied(); } void NormalProcess::write (uint32_t offset, uint32_t size, uint8_t *source) { - WriteProcessMemory(d->my_handle, (int*) offset, source, size, NULL); + if(!WriteProcessMemory(d->my_handle, (int*) offset, source, size, NULL)) + throw Error::MemoryAccessDenied(); } @@ -383,7 +394,9 @@ const string NormalProcess::readCString (const uint32_t offset) string temp; char temp_c[256]; DWORD read; - ReadProcessMemory(d->my_handle, (int *) offset, temp_c, 254, &read); // needs to be 254+1 byte for the null term + if(!ReadProcessMemory(d->my_handle, (int *) offset, temp_c, 254, &read)) + throw Error::MemoryAccessDenied(); + // needs to be 254+1 byte for the null term temp_c[read+1] = 0; temp.assign(temp_c); return temp; @@ -403,20 +416,20 @@ Uint32 length Uint32 capacity */ uint32_t start_offset = offset + 4; - size_t length = g_pProcess->readDWord(offset + 20); + size_t length = readDWord(offset + 20); - size_t capacity = g_pProcess->readDWord(offset + 24); + size_t capacity = readDWord(offset + 24); size_t read_real = min(length, bufcapacity-1);// keep space for null termination // read data from inside the string structure if(capacity < 16) { - g_pProcess->read(start_offset, read_real , (uint8_t *)buffer); + read(start_offset, read_real , (uint8_t *)buffer); } else // read data from what the offset + 4 dword points to { - start_offset = g_pProcess->readDWord(start_offset);// dereference the start offset - g_pProcess->read(start_offset, read_real, (uint8_t *)buffer); + start_offset = readDWord(start_offset);// dereference the start offset + read(start_offset, read_real, (uint8_t *)buffer); } buffer[read_real] = 0; @@ -437,19 +450,19 @@ const string NormalProcess::readSTLString (uint32_t offset) Uint32 capacity */ uint32_t start_offset = offset + 4; - uint32_t length = g_pProcess->readDWord(offset + 20); - uint32_t capacity = g_pProcess->readDWord(offset + 24); + uint32_t length = readDWord(offset + 20); + uint32_t capacity = readDWord(offset + 24); char * temp = new char[capacity+1]; // read data from inside the string structure if(capacity < 16) { - g_pProcess->read(start_offset, capacity, (uint8_t *)temp); + read(start_offset, capacity, (uint8_t *)temp); } else // read data from what the offset + 4 dword points to { - start_offset = g_pProcess->readDWord(start_offset);// dereference the start offset - g_pProcess->read(start_offset, capacity, (uint8_t *)temp); + start_offset = readDWord(start_offset);// dereference the start offset + read(start_offset, capacity, (uint8_t *)temp); } temp[length] = 0; diff --git a/dfhack/include/DFError.h b/dfhack/include/DFError.h index 375a5c581..15086b9bb 100644 --- a/dfhack/include/DFError.h +++ b/dfhack/include/DFError.h @@ -236,11 +236,11 @@ namespace DFHack return s.str().c_str(); } }; - class DFHACK_EXPORT SHMAccessDenied : public std::exception + class DFHACK_EXPORT MemoryAccessDenied : public std::exception { public: - SHMAccessDenied() {} - virtual ~SHMAccessDenied() throw(){}; + MemoryAccessDenied() {} + virtual ~MemoryAccessDenied() throw(){}; std::string type; diff --git a/dfhack/include/modules/Creatures.h b/dfhack/include/modules/Creatures.h index aa3627977..38ed7df56 100644 --- a/dfhack/include/modules/Creatures.h +++ b/dfhack/include/modules/Creatures.h @@ -346,7 +346,7 @@ namespace DFHack int32_t squad_leader_id; uint8_t sex; uint32_t pregnancy_timer; //Countdown timer to giving birth - + bool has_default_soul; t_soul defaultSoul; }; diff --git a/dfhack/modules/Buildings.cpp b/dfhack/modules/Buildings.cpp index 580ec5c5f..a3ccaa77c 100644 --- a/dfhack/modules/Buildings.cpp +++ b/dfhack/modules/Buildings.cpp @@ -134,6 +134,8 @@ bool Buildings::Finish() bool Buildings::ReadCustomWorkshopTypes(map & btypes) { + if(!d->Started) + return false; DfVector p_matgloss (g_pProcess, d->custom_workshop_vector, 4); uint32_t size = p_matgloss.getSize(); btypes.clear(); @@ -151,6 +153,8 @@ bool Buildings::ReadCustomWorkshopTypes(map & btypes) int32_t Buildings::GetCustomWorkshopType(t_building & building) { + if(!d->Inited) + return false; int32_t type = (int32_t)building.type; int32_t ret = -1; if(type != -1 && type == d->custom_workshop_id) diff --git a/dfhack/modules/Creatures.cpp b/dfhack/modules/Creatures.cpp index 3ab33f27b..2c29b9fc5 100644 --- a/dfhack/modules/Creatures.cpp +++ b/dfhack/modules/Creatures.cpp @@ -210,23 +210,27 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) DfVector souls(g_pProcess,temp + offs.creature_soul_vector_offset,4); */ uint32_t soul = g_pProcess->readDWord(temp + offs.default_soul_offset); - // get first soul's skills - DfVector skills(g_pProcess, soul + offs.soul_skills_vector_offset, 4 ); - furball.defaultSoul.numSkills = skills.getSize(); - for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++) + furball.has_default_soul = false; + if(soul) { - uint32_t temp2 = * (uint32_t *) skills[i]; - // a byte: this gives us 256 skills maximum. - furball.defaultSoul.skills[i].id = g_pProcess->readByte (temp2); - furball.defaultSoul.skills[i].rating = g_pProcess->readByte (temp2 + 4); - furball.defaultSoul.skills[i].experience = g_pProcess->readWord (temp2 + 8); + furball.has_default_soul = true; + // get first soul's skills + DfVector skills(g_pProcess, soul + offs.soul_skills_vector_offset, 4 ); + furball.defaultSoul.numSkills = skills.getSize(); + for (uint32_t i = 0; i < furball.defaultSoul.numSkills;i++) + { + uint32_t temp2 = * (uint32_t *) skills[i]; + // a byte: this gives us 256 skills maximum. + furball.defaultSoul.skills[i].id = g_pProcess->readByte (temp2); + furball.defaultSoul.skills[i].rating = g_pProcess->readByte (temp2 + 4); + furball.defaultSoul.skills[i].experience = g_pProcess->readWord (temp2 + 8); + } + // mental attributes are part of the soul + g_pProcess->read(soul + offs.soul_mental_offset, sizeof(t_attrib) * 13, (uint8_t *)&furball.defaultSoul.analytical_ability); + + // traits as well + g_pProcess->read(soul + offs.soul_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.defaultSoul.traits); } - // mental attributes are part of the soul - g_pProcess->read(soul + offs.soul_mental_offset, sizeof(t_attrib) * 13, (uint8_t *)&furball.defaultSoul.analytical_ability); - - // traits as well - g_pProcess->read(soul + offs.soul_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.defaultSoul.traits); - //likes /* DfVector likes(d->p, temp + offs.creature_likes_offset, 4); diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index 5ef2d1a0c..3bd7ffea6 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -14,17 +14,8 @@ using namespace std; #include #include #include +#include "miscutils.h" -template -void print_bits ( T val, std::ostream& out ) -{ - T n_bits = sizeof ( val ) * CHAR_BIT; - - for ( unsigned i = 0; i < n_bits; ++i ) { - out<< !!( val & 1 ) << " "; - val >>= 1; - } -} struct matGlosses { vector plantMat; @@ -240,46 +231,46 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) */ cout << endl; - - //skills - cout << "Skills" << endl; - for(unsigned int i = 0; i < creature.defaultSoul.numSkills;i++) + if(creature.has_default_soul) { - if(i > 0) + //skills + cout << "Skills" << endl; + for(unsigned int i = 0; i < creature.defaultSoul.numSkills;i++) { - cout << ", "; + if(i > 0) + { + cout << ", "; + } + cout << mem->getSkill(creature.defaultSoul.skills[i].id) << ": " << creature.defaultSoul.skills[i].rating; } - cout << mem->getSkill(creature.defaultSoul.skills[i].id) << ": " << creature.defaultSoul.skills[i].rating; - } - cout << endl; - - // labors - cout << "Labors" << endl; - for(unsigned int i = 0; i < NUM_CREATURE_LABORS;i++) - { - if(!creature.labors[i]) - continue; - string laborname; - try + cout << endl; + cout << "Traits" << endl; + for(uint32_t i = 0; i < 30;i++) { - laborname = mem->getLabor(i); + string trait = mem->getTrait (i, creature.defaultSoul.traits[i]); + if(!trait.empty()) cout << trait << ", "; } - catch(exception &) + cout << endl; + + // labors + cout << "Labors" << endl; + for(unsigned int i = 0; i < NUM_CREATURE_LABORS;i++) { - break; + if(!creature.labors[i]) + continue; + string laborname; + try + { + laborname = mem->getLabor(i); + } + catch(exception &) + { + break; + } + cout << laborname << ", "; } - cout << laborname << ", "; - } - cout << endl; - - cout << "Traits" << endl; - for(uint32_t i = 0; i < 30;i++) - { - string trait = mem->getTrait (i, creature.defaultSoul.traits[i]); - if(!trait.empty()) - cout << trait << ", "; + cout << endl; } - cout << endl; /* * FLAGS 1 */ @@ -409,18 +400,21 @@ int main (void) cerr << "Can't get name tables" << endl; return 1; } - + vector addrs; //DF.InitViewAndCursor(); for(uint32_t i = 0; i < numCreatures; i++) { DFHack::t_creature temp; Creatures->ReadCreature(i,temp); - if(string(creaturestypes[temp.race].id) == "DWARF") + //if(string(creaturestypes[temp.race].id) == "DWARF") { cout << "index " << i << " "; + printCreature(DF,temp); + addrs.push_back(temp.origin); } } + interleave_hex(DF,addrs,200); /* uint32_t currentIdx; DFHack::t_creature currentCreature; diff --git a/output/Memory.xml b/output/Memory.xml index 89aa73886..ad1c7a066 100644 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1135,6 +1135,7 @@ map_data_1b60_offset 0x1B9c 0X1F4 0X21C 0x238 + 0x23C 0x464