Rewrote hitdump to use a parser and Shutdown_M

This commit is contained in:
Fatbag 2012-12-26 09:51:32 -06:00
parent 6dddbd2efa
commit 5488883991
8 changed files with 311 additions and 323 deletions

3
.gitignore vendored
View file

@ -110,6 +110,9 @@ qrc_*.cpp
*.tar.* *.tar.*
*.zip *.zip
*.7z *.7z
*.gz
*.bz2
*.xz
*.rar *.rar
*.cab *.cab
*.msi *.msi

View file

@ -29,11 +29,12 @@ static IFFFile IFFFileInfo;
static int iffcreated = 0; static int iffcreated = 0;
static void Shutdown_M(const char * Message){ static void Shutdown_M(const char * Message){
fprintf(stderr, "iffexport: error: %s.", Message); fprintf(stderr, "iffexport: error: %s.\n", Message);
if(iffcreated) if(iffcreated)
iff_delete(&IFFFileInfo); iff_delete(&IFFFileInfo);
free(IFFData); free(IFFData);
fclose(hFile); if(hFile)
fclose(hFile);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View file

@ -39,10 +39,11 @@ static uint8_t * UTKData = NULL;
static uint8_t * WaveData = NULL; static uint8_t * WaveData = NULL;
static void Shutdown_M(const char * Message){ static void Shutdown_M(const char * Message){
fprintf(stderr, "utkdecode: error: %s.", Message); fprintf(stderr, "utkdecode: error: %s.\n", Message);
free(WaveData); free(WaveData);
free(UTKData); free(UTKData);
fclose(hFile); if(hFile)
fclose(hFile);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View file

@ -39,10 +39,11 @@ static uint8_t * XAData = NULL;
static uint8_t * WaveData = NULL; static uint8_t * WaveData = NULL;
static void Shutdown_M(const char * Message){ static void Shutdown_M(const char * Message){
fprintf(stderr, "xadecode: error: %s.", Message); fprintf(stderr, "xadecode: error: %s.\n", Message);
free(WaveData); free(WaveData);
free(XAData); free(XAData);
fclose(hFile); if(hFile)
fclose(hFile);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View file

@ -53,7 +53,7 @@ static void KillGLWindow()
static int CreateGLWindow(const char *__restrict title, uint16_t width, uint16_t height) static int CreateGLWindow(const char *__restrict title, uint16_t width, uint16_t height)
{ {
PIXELFORMATDESCRIPTOR pfd = { const PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), 1, /* Size and version */ sizeof(PIXELFORMATDESCRIPTOR), 1, /* Size and version */
PFD_DRAW_TO_WINDOW | /* dwFlags */ PFD_DRAW_TO_WINDOW | /* dwFlags */
PFD_SUPPORT_OPENGL | PFD_SUPPORT_OPENGL |

View file

@ -19,50 +19,126 @@
#include <basetyps.h> #include <basetyps.h>
#pragma pack(0) #pragma pack(0)
DECLARE_INTERFACE(cUnknownObject1) DECLARE_INTERFACE(cRZString)
{ {
DWORD Zero1; void * vtable1_cRZString;
DWORD Zero2; char * mpBegin; //Pointer to beginning of string
void * vtable5; char * mpEnd; //Pointer to null terminator
char ** Strings1; char * mpCapacity; //mpEnd + 1
char ** Strings2; DWORD mAllocator; //0
char ** Strings3; DWORD Zero1; //0
DWORD Zero3;
DWORD Zero4;
DWORD Zero5;
void ** Pointer1; //12 bytes
void ** Pointer2; //4 bytes
void ** Pointer3;
DWORD Flags;
DWORD * Pointer4; //4 bytes
void * Pointer5;
void * Pointer6;
DWORD Unknown11;
DWORD Unknown12;
}; };
DECLARE_INTERFACE(cTSOEdithEditorDCOMDirector) struct stringstruct
{ {
void * vtable2; DWORD StringID;
void * vtable1; DWORD Unknown;
cUnknownObject1 Object1; char * PointerToBuffer; //Buffer
void * vtable4; DWORD SizeOfBuffer; //256
void * vtable3; char Buffer[256];
cUnknownObject1 Object2; };
cUnknownObject1 Object3;
DECLARE_INTERFACE(cEdithEditorCOMDirector)
{
void * vtable_1_cEdithEditorCOMDirector;
void * vtable_2_cEdithEditorCOMDirector;
DWORD Zero1; DWORD Zero1;
DWORD Zero2; DWORD Zero2;
DWORD Zero3; cRZString string;
DWORD Zero4;
DWORD Zero5; DWORD Zero5;
DWORD Zero6; DWORD Zero6;
DWORD Zero7; DWORD Zero7;
DWORD Zero8; DWORD Zero8;
DWORD Zero9; DWORD Zero9;
DWORD Zero10; DWORD Zero10;
DWORD Unknown1;
DWORD Pointer1;
DWORD Pointer2;
DWORD Zero11; DWORD Zero11;
void * ptr;
DWORD Value1; //2
DWORD Value2; //1
float Value3; //1.0f
DWORD Value4; //0x40000000
DWORD Value5; //2
DWORD Value6; //0
DWORD Value7; //1
DWORD Value8; //0
stringstruct string0; //StringID:0, Unknown:40, value:"index"
stringstruct string1; //StringID:1, Unknown:40, value:"value"
stringstruct string2; //StringID:2, Unknown:150, value:"Name"
stringstruct string3; //StringID:3, Unknown:200, value:"Description"
DWORD Value9; //0
DWORD Value10; //0
stringstruct string4; //StringID:0, Unknown:90, value:"Calling Tree"
stringstruct string5; //StringID:1, Unknown:86, value:"Type"
stringstruct string6; //StringID:2, Unknown:83, value:"Title"
stringstruct string7; //StringID:3, Unknown:65, value:"Yes"
stringstruct string8; //StringID:4, Unknown:65, value:"No"
stringstruct string9; //StringID:5, Unknown:65, value:"Cancel"
stringstruct string10; //StringID:6, Unknown:300, value:"Message"
stringstruct string11; //StringID:7, Unknown:45, value:"Tree ID"
stringstruct string12; //StringID:8, Unknown:50, value:"Node #"
};
DECLARE_INTERFACE(cTSOEdithEditorDCOMDirector)
{
void * vtable1_cTSOEdithEditorDCOMDirector;
void * vtable2_cTSOEdithEditorDCOMDirector;
DWORD Zero1;
DWORD Zero2;
cRZString String1;
DWORD Zero5;
DWORD Zero6;
cEdithEditorCOMDirector ** memptr_1;
void ** memptr_2;
void ** memptr_3; //Same as memptr_2
DWORD Zero7;
DWORD Zero8;
void * dllptr_4_100B5834; //CMemoryException TD
DWORD Value1; //1
DWORD Value2; //0
float Value3; //1.0f
DWORD Value4; //0x40000000
DWORD Value5; //0
DWORD Value6; //0
DWORD Value7; //1
cRZString String2;
cRZString String3;
cRZString String4;
cRZString String5;
cRZString String6;
cRZString String7;
cRZString String8;
cRZString String9;
DWORD Zero9;
DWORD Zero10;
DWORD Zero11;
DWORD Zero12;
DWORD Zero13;
DWORD Zero14;
DWORD Zero15;
cRZString String10;
cRZString String11;
cRZString String12;
cRZString String13;
cRZString String14;
DWORD Zero16;
DWORD Zero17;
DWORD Zero18;
DWORD Zero19;
DWORD Zero20;
cRZString String15;
cRZString String16;
cRZString String17;
cRZString String18;
cRZString String19;
cRZString String20;
cRZString String21;
cRZString String22;
cRZString String23;
cRZString String24;
cRZString String25;
cRZString String26;
cRZString String27;
cRZString String28;
cRZString String29;
cRZString String30;
}; };

View file

@ -16,6 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -33,6 +34,8 @@
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1))) #define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
#endif #endif
static void Shutdown_M(const char * Message, ...);
enum { enum {
hsm, hot, evt, hit, out, filecount hsm, hot, evt, hit, out, filecount
}; };
@ -333,6 +336,55 @@ static __inline const char * find_global(uint32_t x, const global_t * Globals, s
return NULL; return NULL;
} }
typedef struct {
uint8_t * Data;
size_t Size;
} ByteReaderContext;
enum TokenizeType {
TK_STRING,
TK_ID
};
static int parser_find(ByteReaderContext *brc, ...){
va_list args;
va_start(args, brc);
while(1){
uint8_t * Start = brc->Data;
const char * Pattern;
size_t Length;
void * Destination;
enum TokenizeType Type;
Pattern = va_arg(args, const char *);
if(Pattern == NULL){
va_end(args);
return 1;
}
for(Length = strlen(Pattern); ; brc->Data++, brc->Size--){
if(brc->Size < Length){
va_end(args);
return 0;
}
if(!memcmp(brc->Data, Pattern, Length)) break;
}
*brc->Data = '\0';
brc->Data += Length; brc->Size -= Length;
Destination = va_arg(args, void *);
if(Destination == NULL)
continue;
Type = va_arg(args, enum TokenizeType);
if(Type == TK_STRING)
*((char**)Destination) = (char*)Start;
else
*((uint32_t*)Destination) = strtoul((char*)Start, NULL, 0);
}
}
typedef struct { typedef struct {
uint32_t LogicalAddress; uint32_t LogicalAddress;
uint32_t TrackID; uint32_t TrackID;
@ -348,8 +400,11 @@ typedef struct {
} addresslist_t; } addresslist_t;
static address_t * add_address(addresslist_t * List){ static address_t * add_address(addresslist_t * List){
if(List->Count == List->Size) if(List->Count == List->Size){
List->Entries = realloc(List->Entries, (List->Size <<= 1) * sizeof(address_t)); List->Entries = realloc(List->Entries, (List->Size <<= 1) * sizeof(address_t));
if(!List->Entries)
Shutdown_M("%sCould not allocate memory for address list.\n", "hitdump: Error: ");
}
return memset(List->Entries + List->Count++, 0, sizeof(address_t)); return memset(List->Entries + List->Count++, 0, sizeof(address_t));
} }
@ -390,35 +445,21 @@ static __inline address_t * find_address_by_name(addresslist_t * List, const cha
} }
static __inline void read_hit_addresses(uint8_t * Data, size_t Size, addresslist_t * AddressList, uint32_t * SymbolTable){ static __inline void read_hit_addresses(uint8_t * Data, size_t Size, addresslist_t * AddressList, uint32_t * SymbolTable){
uint8_t * Start = Data, * TableData; uint8_t * TableData;
unsigned i, count = 0; unsigned i, count = 0;
ByteReaderContext brc;
brc.Data = Data; brc.Size = Size;
if(Size < 32) return; if(!parser_find(&brc, "ENTP", NULL, NULL) || brc.Size < 4) return;
Data += 16; TableData = brc.Data;
Size -= 16; *SymbolTable = TableData - 4 - Data;
/* Find the table start */
while(memcmp(Data, "ENTP", 4)){
if(Size < 17) return;
Data++; Size--;
}
TableData = Data;
Data += 4;
Size -= 4;
/* Find the table end */
while(memcmp(Data, "EENT", 4)){ while(memcmp(Data, "EENT", 4)){
if(Size < 12) return; if(Size < 12) return;
Data+=8; Size-=8; Data+=8; Size-=8;
count++; count++;
} }
*SymbolTable = TableData - Start;
if(count == 0) return;
TableData += 4;
for(i=0; i<count; i++){ for(i=0; i<count; i++){
address_t * Address = add_address(AddressList); address_t * Address = add_address(AddressList);
Address->Exported = 1; Address->Exported = 1;
@ -428,106 +469,45 @@ static __inline void read_hit_addresses(uint8_t * Data, size_t Size, addresslist
} }
static __inline void read_evt_addresses(uint8_t * Data, size_t Size, addresslist_t * AddressList){ static __inline void read_evt_addresses(uint8_t * Data, size_t Size, addresslist_t * AddressList){
if(Size < 13) return; ByteReaderContext brc;
brc.Data = Data; brc.Size = Size;
while(1){ while(1){
uint8_t * Name = Data, * TrackIDPos;
address_t * Address; address_t * Address;
char *Name;
uint32_t TrackID; uint32_t TrackID;
if(!parser_find(&brc,
",", &Name, TK_STRING,
",", NULL,
",", &TrackID, TK_ID,
NULL)) return;
Data++; Size--;
/* End of first field: address name */
while(*Data != ','){
if(Size < 13) return;
Data++; Size--;
}
*Data = '\0';
Data++; Size--;
/* End of second field: unneeded */
while(*Data != ','){
if(Size < 11) return;
Data++; Size--;
}
Data++; Size--;
TrackIDPos = Data;
/* End of third field: Track ID */
while(*Data != ','){
if(Size < 9) return;
Data++; Size--;
}
*Data = '\0';
Data++; Size--;
TrackID = atoi((char*)TrackIDPos);
Address = find_address_by_track_id(AddressList, TrackID); Address = find_address_by_track_id(AddressList, TrackID);
if(!Address){ if(!Address){
Address = add_address(AddressList); Address = add_address(AddressList);
Address->Exported = 1; Address->Exported = 1;
Address->TrackID = TrackID; Address->TrackID = TrackID;
} }
Address->Name = (char*)Name; Address->Name = Name;
if(!parser_find(&brc, "\n", NULL, NULL)) return;
while(*Data != '\n'){
if(Size < 15) return;
Data++; Size--;
}
Data++; Size--;
} }
} }
static __inline void read_hsm_addresses(uint8_t * Data, size_t Size, addresslist_t * AddressList){ static __inline void read_hsm_addresses(uint8_t * Data, size_t Size, addresslist_t * AddressList){
if(Size < 24) return; ByteReaderContext brc;
brc.Data = Data; brc.Size = Size;
while(1){ while(1){
uint8_t * Name, * IDPos;
address_t * Address; address_t * Address;
char * Name;
uint32_t SoundID, LogicalAddress; uint32_t SoundID, LogicalAddress;
if(!parser_find(&brc,
/* Find the next constant that begins with "tkd_" */ "\ntkd_", NULL,
while(memcmp(Data, "\ntkd_", 5)){ " ", &Name, TK_STRING,
if(Size < 25) return; " ", &SoundID, TK_ID,
Data++; Size--; " ", NULL,
} " ", &LogicalAddress, TK_ID,
Name = Data += 5; NULL)) return;
Size -= 5;
/* End of tkd constant name */
while(*Data != ' '){
if(Size < 19) return;
Data++; Size--;
}
*Data = '\0';
Data++; Size--;
IDPos = Data;
/* End of tkd constant value */
while(*Data != ' '){
if(Size < 17) return;
Data++; Size--;
}
*Data = '\0';
Data++; Size--;
SoundID = atoi((char*)IDPos);
/* End of address constant name */
while(*Data != ' '){
if(Size < 9) return;
Data++; Size--;
}
Data++; Size--;
IDPos = Data;
/* End of address constant value */
while(*Data != ' '){
if(Size < 7) return;
Data++; Size--;
}
*Data = '\0';
Data++; Data--;
LogicalAddress = atoi((char*)IDPos);
Address = find_address_by_logical_address(AddressList, LogicalAddress); Address = find_address_by_logical_address(AddressList, LogicalAddress);
if(!Address){ if(!Address){
@ -537,52 +517,25 @@ static __inline void read_hsm_addresses(uint8_t * Data, size_t Size, addresslist
Address->Name = (char*)Name; Address->Name = (char*)Name;
} }
Address->LogicalAddress = LogicalAddress; Address->LogicalAddress = LogicalAddress;
} else Address->Name = (char*)Name; } else Address->Name = Name;
Address->SoundID = SoundID; Address->SoundID = SoundID;
while(*Data != '\n'){
if(Size < 25) return;
Data++; Size--;
}
} }
} }
static __inline void read_hot_trackdata(uint8_t * Data, size_t Size, addresslist_t * AddressList){ static __inline void read_hot_trackdata(uint8_t * Data, size_t Size, addresslist_t * AddressList){
if(Size < 19) return; ByteReaderContext brc;
brc.Data = Data; brc.Size = Size;
while(memcmp(Data, "[TrackData]", 11)){ if(!parser_find(&brc, "[TrackData]", NULL, NULL)) return;
if(Size < 20) return;
Data++; Size--;
}
Data += 12;
Size -= 12;
if(*Data == '\n'){
Data++; Size--;
}
while(1){ while(1){
uint8_t * IDPos = Data;
address_t * Address; address_t * Address;
uint32_t SoundID, LogicalAddress; uint32_t SoundID, LogicalAddress;
if(!brc.Size || *brc.Data == '\n' || *brc.Data == '[') return;
/* End of key: Sound ID */ if(!parser_find(&brc,
while(*Data != '='){ "=", &SoundID, TK_ID,
if(Size < 5) return; "\n", &LogicalAddress, TK_ID,
Data++; Size--; NULL)) return;
}
*Data = '\0';
SoundID = strtol((char*)IDPos, NULL, 0);
Data++; Size--;
IDPos = Data;
while(*Data != '\n'){
if(Size < 2) return;
Data++; Size--;
}
*Data = '\0';
LogicalAddress = strtol((char*)IDPos, NULL, 0);
Data++; Size--;
Address = find_address_by_logical_address(AddressList, LogicalAddress); Address = find_address_by_logical_address(AddressList, LogicalAddress);
if(!Address){ if(!Address){
@ -593,59 +546,25 @@ static __inline void read_hot_trackdata(uint8_t * Data, size_t Size, addresslist
} }
Address->LogicalAddress = LogicalAddress; Address->LogicalAddress = LogicalAddress;
} else Address->SoundID = SoundID; } else Address->SoundID = SoundID;
if(Size < 8) return;
while(*Data == '\r' || *Data == '\n' || *Data == ' ' || *Data == '\t'){
if(Size < 8) return;
Data++; Size--;
}
if(*Data == '[') return;
} }
} }
static __inline void read_hot_track(uint8_t * Data, size_t Size, addresslist_t * AddressList){ static __inline void read_hot_track(uint8_t * Data, size_t Size, addresslist_t * AddressList){
if(Size < 28) return; ByteReaderContext brc;
brc.Data = Data; brc.Size = Size;
while(memcmp(Data, "[Track]", 7)){ if(!parser_find(&brc, "[Track]", NULL, NULL)) return;
if(Size < 29) return;
Data++; Size--;
}
Data += 8;
Size -= 8;
if(*Data == '\n'){
Data++; Size--;
}
while(1){ while(1){
uint8_t * IDPos = Data, * Name;
address_t * Address; address_t * Address;
char * Name;
uint32_t TrackID; uint32_t TrackID;
if(!brc.Size || *brc.Data == '\n' || *brc.Data == '[') return;
/* End of key: Track ID */ if(!parser_find(&brc,
while(*Data != '='){ "=", &TrackID, TK_ID,
if(Size < 20) return; ",", NULL,
Data++; Size--; ",", &Name, TK_STRING,
} NULL)) return;
*Data = '\0';
TrackID = strtol((char*)IDPos, NULL, 0);
Data++; Size--;
/* End of first field: Unknown */
while(*Data != ','){
if(Size < 18) return;
Data++; Size--;
}
Data++; Size--;
Name = Data;
/* End of second field: Name */
while(*Data != ','){
if(Size < 16) return;
Data++; Size--;
}
*Data = '\0';
Address = find_address_by_name(AddressList, (char*)Name); Address = find_address_by_name(AddressList, (char*)Name);
if(!Address){ if(!Address){
@ -654,17 +573,11 @@ static __inline void read_hot_track(uint8_t * Data, size_t Size, addresslist_t *
Address = add_address(AddressList); Address = add_address(AddressList);
Address->TrackID = TrackID; Address->TrackID = TrackID;
} }
Address->Name = (char*)Name; Address->Name = Name;
} else Address->TrackID = TrackID; } else Address->TrackID = TrackID;
Address->Exported = 1; Address->Exported = 1;
if(Size < 36) return; if(!parser_find(&brc, "\n", NULL, NULL)) return;
while(*Data == '\r' || *Data == '\n' || *Data == ' ' || *Data == '\t'){
if(Size < 22) return;
Data++; Size--;
}
if(*Data == '[') return;
} }
} }
@ -673,25 +586,46 @@ static __inline void read_hot_addresses(uint8_t * Data, size_t Size, addresslist
read_hot_track(Data, Size, AddressList); read_hot_track(Data, Size, AddressList);
} }
static FILE *hFile = NULL;
static char *path[filecount] = {NULL};
static uint8_t *data[filecount] = {NULL};
static char *basename = NULL;
static addresslist_t AddressList = {0};
static void Shutdown(){
unsigned i;
for(i=0; i<filecount; i++){
free(path[i]);
free(data[i]);
}
free(basename);
free(AddressList.Entries);
if(hFile)
fclose(hFile);
}
static void Shutdown_M(const char * Message, ...){
va_list args;
va_start(args, Message);
vfprintf(stderr, Message, args);
va_end(args);
Shutdown();
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
unsigned i, addr; unsigned i, j, addr;
int SimsVersion = 0; int SimsVersion = 0;
int overwrite = 0; int overwrite = 0;
int ShowAddresses = 0; int ShowAddresses = 0;
int length; int length;
char *basename;
char *path[filecount] = {NULL};
uint8_t *data[filecount-1] = {NULL};
size_t filesize[filecount-1]; size_t filesize[filecount-1];
FILE * hFile;
const global_t * Globals; const global_t * Globals;
size_t GlobalCount; size_t GlobalCount;
uint32_t SymbolTable = 0; uint32_t SymbolTable = 0;
uint32_t BaseSoundID = 0, BaseSoundIDSet = 0; uint32_t BaseSoundID = 0, BaseSoundIDSet = 0;
/* collected data */
addresslist_t AddressList;
/**** /****
** Parse the command-line arguments ** Parse the command-line arguments
*/ */
@ -718,7 +652,7 @@ int main(int argc, char *argv[]){
else if(!strcmp(argv[i], "-f")) overwrite = 1; else if(!strcmp(argv[i], "-f")) overwrite = 1;
else if(!strcmp(argv[i], "-a")) ShowAddresses = 1; else if(!strcmp(argv[i], "-a")) ShowAddresses = 1;
else if(i != (unsigned)argc-2){ else if(i != (unsigned)argc-2){
if(!strcmp(argv[i], "-out")) path[out] = argv[++i]; if(!strcmp(argv[i], "-o")) path[out] = argv[++i];
else if(!strcmp(argv[i], "-hsm")) path[hsm] = argv[++i]; else if(!strcmp(argv[i], "-hsm")) path[hsm] = argv[++i];
else if(!strcmp(argv[i], "-hot")) path[hot] = argv[++i]; else if(!strcmp(argv[i], "-hot")) path[hot] = argv[++i];
else if(!strcmp(argv[i], "-evt")) path[evt] = argv[++i]; else if(!strcmp(argv[i], "-evt")) path[evt] = argv[++i];
@ -726,11 +660,13 @@ int main(int argc, char *argv[]){
} }
else break; else break;
} }
path[hit] = argv[i];
for(j=0; j<filecount; j++)
if(path[j])
path[j] = strdup(path[j]); /* necessary for free(path[i]) in Shutdown_M */
if(!SimsVersion){ if(!SimsVersion)
fprintf(stderr, "%sSims version not specified. (Use -ts1 or -tso.)\n", "hitdump: Error: "); Shutdown_M("%sSims version not specified. (Use -ts1 or -tso.)\n", "hitdump: Error: ");
return -1;
}
if(SimsVersion == VERSION_TS1){ if(SimsVersion == VERSION_TS1){
Globals = TS1Globals; Globals = TS1Globals;
@ -740,7 +676,6 @@ int main(int argc, char *argv[]){
GlobalCount = TSOGlobalCount; GlobalCount = TSOGlobalCount;
} }
path[hit] = argv[i];
length = strlen(path[hit]); length = strlen(path[hit]);
if(path[out] == NULL){ if(path[out] == NULL){
path[out] = malloc(max(length+1, 5)); path[out] = malloc(max(length+1, 5));
@ -757,57 +692,50 @@ int main(int argc, char *argv[]){
*/ */
for(i=0; i<filecount-1; i++){ for(i=0; i<filecount-1; i++){
size_t bytestransferred;
if(!path[i]) continue; if(!path[i]) continue;
hFile = fopen(path[i], "rb"); hFile = fopen(path[i], "rb");
if(hFile == NULL){ if(hFile == NULL){
if(i != hit){ if(i != hit){
fprintf(stderr, "%sCould not open file: %s\n", "hitdump: Warning: ", path[i]); fprintf(stderr, "%sCould not open file: %s.\n", "hitdump: Warning: ", path[i]);
continue; continue;
}else{ }else
fprintf(stderr, "%sCould not open file: %s\n", "hitdump: Error: ", path[i]); Shutdown_M("%sCould not open file: %s.\n", "hitdump: Error: ", path[i]);
return -1;
}
} }
fseek(hFile, 0, SEEK_END); fseek(hFile, 0, SEEK_END);
filesize[i] = ftell(hFile); filesize[i] = ftell(hFile);
if(filesize[i] == 0){ if(filesize[i] == 0){
fclose(hFile); fclose(hFile); hFile = NULL;
if(i != hit){ if(i != hit){
fprintf(stderr, "%sFile is invalid: %s\n", "hitdump: Warning: ", path[i]); fprintf(stderr, "%sFile is invalid: %s.\n", "hitdump: Warning: ", path[i]);
continue; continue;
}else{ }else
fprintf(stderr, "%sFile is invalid: %s\n", "hitdump: Error: ", path[i]); Shutdown_M("%sFile is invalid: %s.\n", "hitdump: Error: ", path[i]);
return -1;
}
} }
data[i] = malloc(filesize[i]); data[i] = malloc(filesize[i]);
if(data[i] == NULL){ if(data[i] == NULL){
fclose(hFile); fclose(hFile); hFile = NULL;
if(i != hit){ if(i != hit){
fprintf(stderr, "%sCould not allocate memory for file: %s\n", "hitdump: Warning: ", path[i]); fprintf(stderr, "%sCould not allocate memory for file: %s.\n", "hitdump: Warning: ", path[i]);
continue; continue;
}else{ }else
fprintf(stderr, "%sCould not allocate memory for file: %s\n", "hitdump: Error: ", path[i]); Shutdown_M("%sCould not allocate memory for file: %s.\n", "hitdump: Error: ", path[i]);
return -1;
}
} }
fseek(hFile, 0, SEEK_SET); fseek(hFile, 0, SEEK_SET);
if(fread(data[i], 1, filesize[i], hFile) != filesize[i]){ bytestransferred = fread(data[i], 1, filesize[i], hFile);
fclose(hFile); fclose(hFile); hFile = NULL;
if(bytestransferred != filesize[i]){
free(data[i]); data[i] = NULL;
if(i != hit){ if(i != hit){
fprintf(stderr, "%sCould not read file: %s\n", "hitdump: Warning: ", path[i]); fprintf(stderr, "%sCould not read file: %s.\n", "hitdump: Warning: ", path[i]);
continue; continue;
}else{ }else
fprintf(stderr, "%sCould not read file: %s\n", "hitdump: Error: ", path[i]); Shutdown_M("%sCould not read file: %s.\n", "hitdump: Error: ", path[i]);
return -1;
}
} }
fclose(hFile);
} }
/**** /****
@ -819,29 +747,23 @@ int main(int argc, char *argv[]){
if(hFile != NULL){ if(hFile != NULL){
/* File exists */ /* File exists */
char c; char c;
fclose(hFile); fclose(hFile); hFile = NULL;
fprintf(stderr, "hitdump: File \"%s\" exists.\nContinue anyway? (y/n) ", path[out]); fprintf(stderr, "%sFile \"%s\" exists.\nContinue anyway? (y/n) ", "hitdump: ", path[out]);
c = getchar(); c = getchar();
if(c != 'y' && c != 'Y'){ if(c != 'y' && c != 'Y')
printf("\nAborted.\n"); Shutdown_M("\nAborted.\n");
return -1;
}
} }
} }
hFile = fopen(path[out], "wb"); hFile = fopen(path[out], "wb");
if(hFile == NULL){ if(hFile == NULL)
fprintf(stderr, "%sCould not open file: %s\n", "hitdump: Error: ", path[out]); Shutdown_M("%sCould not open file: %s.\n", "hitdump: Error: ", path[out]);
return -1;
}
/**** /****
** Verify the header of the HIT file ** Verify the header of the HIT file
*/ */
if(filesize[hit] < 16 || memcmp(data[hit], HITHeader, 16)){ if(filesize[hit] < 16 || memcmp(data[hit], HITHeader, 16))
fprintf(stderr, "%sFile is invalid: %s\n", "hitdump: Error: ", path[hit]); Shutdown_M("%sFile is invalid: %s.\n", "hitdump: Error: ", path[hit]);
return -1;
}
/**** /****
** Build up the address list ** Build up the address list
@ -868,7 +790,7 @@ int main(int argc, char *argv[]){
AddressList.Entries[i].Exported, AddressList.Entries[i].Exported,
AddressList.Entries[i].TrackID, AddressList.Entries[i].TrackID,
AddressList.Entries[i].SoundID, AddressList.Entries[i].SoundID,
AddressList.Entries[i].Name, AddressList.Entries[i].Name ? AddressList.Entries[i].Name : "",
AddressList.Entries[i].LogicalAddress AddressList.Entries[i].LogicalAddress
); );
} }
@ -956,26 +878,19 @@ int main(int argc, char *argv[]){
} }
opcode = data[hit][addr]; opcode = data[hit][addr];
if(opcode == 0 || opcode > 96){ if(opcode == 0 || opcode > 96)
fprintf(stderr, "%sIllegal opcode 0x%02X at address 0x%08X.\n", "hitdump: Error: ", opcode, addr); Shutdown_M("%sIllegal opcode 0x%02X at address 0x%08X.\n", "hitdump: Error: ", opcode, addr);
return -1;
}
instruction = Instructions + opcode - 1; instruction = Instructions + opcode - 1;
operands = instruction->Operands; operands = instruction->Operands;
if(operands == UNIMPLEMENTED){ if(operands == UNIMPLEMENTED)
fprintf(stderr, "%sUnimplemented instruction '%s' at address 0x%08X.\n", "hitdump: Error: ", Shutdown_M("%sUnimplemented instruction '%s' at address 0x%08X.\n", "hitdump: Error: ", instruction->Name, addr);
instruction->Name, addr);
return -1;
}
addr++; addr++;
if(filesize[hit] - addr < (operands & 15)){ if(filesize[hit] - addr < (operands & 15))
fprintf(stderr, "%sInsufficient operand bytes for '%s' instruction at address 0x%08X (%u of %u supplied).\n", Shutdown_M("%sInsufficient operand bytes for '%s' instruction at address 0x%08X (%u of %u supplied).\n",
"hitdump: Error: ", instruction->Name, addr, filesize[hit] - addr, instruction->Operands); "hitdump: Error: ", instruction->Name, addr, filesize[hit] - addr, instruction->Operands);
return -1;
}
fprintf(hFile, "\r\n\t\t%s", instruction->Name); fprintf(hFile, "\r\n\t\t%s", instruction->Name);
for(i=0; (operands >>= 4) != 0; i++){ for(i=0; (operands >>= 4) != 0; i++){
@ -998,11 +913,9 @@ int main(int argc, char *argv[]){
int x = data[hit][addr]; int x = data[hit][addr];
if(x > 16){ if(x > 16){
const char * Global = find_global(x, Globals, GlobalCount); const char * Global = find_global(x, Globals, GlobalCount);
if(Global == NULL){ if(Global == NULL)
fprintf(stderr, "%sInvalid %s operand 0x%02X for '%s' instruction at address 0x%08X (expected %s).\n", Shutdown_M("%sInvalid %s operand 0x%02X for '%s' instruction at address 0x%08X (expected %s).\n",
"hitdump: Error: ", position[i], x, instruction->Name, addr, "argument, register, or global"); "hitdump: Error: ", position[i], x, instruction->Name, addr, "argument, register, or global");
return -1;
}
fprintf(hFile, " %s", Global); fprintf(hFile, " %s", Global);
} else fprintf(hFile, " %s", Registers[x]); } else fprintf(hFile, " %s", Registers[x]);
addr += 1; addr += 1;
@ -1011,12 +924,9 @@ int main(int argc, char *argv[]){
if(filesize[hit]-addr >= 4) if(filesize[hit]-addr >= 4)
x = read_uint32(data[hit]+addr); x = read_uint32(data[hit]+addr);
else if(data[hit][addr] != 0x05 && data[hit][addr] != 0x06){ else if(data[hit][addr] != 0x05 && data[hit][addr] != 0x06)
fprintf(stderr, Shutdown_M("%sInsufficient operand bytes for '%s' instruction at address 0x%08X (%u of %u supplied).\n",
"%sInsufficient operand bytes for '%s' instruction at address 0x%08X (%u of %u supplied).\n",
"hitdump: Error: ", instruction->Name, addr, filesize[hit] - addr, 4); "hitdump: Error: ", instruction->Name, addr, filesize[hit] - addr, 4);
return -1;
}
if(x >= 16 && x < filesize[hit]){ if(x >= 16 && x < filesize[hit]){
Address = find_address_by_logical_address(&AddressList, x); Address = find_address_by_logical_address(&AddressList, x);
@ -1027,12 +937,9 @@ int main(int argc, char *argv[]){
x = data[hit][addr]; x = data[hit][addr];
if(x > 16){ if(x > 16){
const char * Global = find_global(x, Globals, GlobalCount); const char * Global = find_global(x, Globals, GlobalCount);
if(Global == NULL){ if(Global == NULL)
fprintf(stderr, Shutdown_M("%sInvalid %s operand 0x%02X for '%s' instruction at address 0x%08X (expected %s).\n",
"%sInvalid %s operand 0x%02X for '%s' instruction at address 0x%08X (expected %s).\n",
"hitdump: Error: ", position[i], x, instruction->Name, addr, "argument, register, or global"); "hitdump: Error: ", position[i], x, instruction->Name, addr, "argument, register, or global");
return -1;
}
fprintf(hFile, " %s", Global); fprintf(hFile, " %s", Global);
} else fprintf(hFile, " %s", Registers[x]); } else fprintf(hFile, " %s", Registers[x]);
addr += (data[hit][addr] != 0x05 && data[hit][addr] != 0x06) ? 4 : 1; addr += (data[hit][addr] != 0x05 && data[hit][addr] != 0x06) ? 4 : 1;
@ -1043,7 +950,7 @@ int main(int argc, char *argv[]){
fprintf(hFile, "\r\n]\r\n\r\n"); fprintf(hFile, "\r\n]\r\n\r\n");
fclose(hFile); Shutdown();
return 0; return 0;
} }

View file

@ -193,8 +193,7 @@ struct PEFile {
~PEFile(){ ~PEFile(){
if(hFile) if(hFile)
fclose(hFile); fclose(hFile);
if(Data) free(Data);
free(Data);
} }
inline bool seek(size_t pos, int offset = 0){ inline bool seek(size_t pos, int offset = 0){
@ -305,7 +304,7 @@ struct PEFile {
PEFile * PEFile::ptr; PEFile * PEFile::ptr;
static void Shutdown_M(const char * Message){ static void Shutdown_M(const char * Message){
fprintf(stderr, "rtti-reader: error: %s.", Message); fprintf(stderr, "rtti-reader: error: %s.\n", Message);
if(PEFile::ptr) if(PEFile::ptr)
PEFile::ptr->~PEFile(); PEFile::ptr->~PEFile();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -344,13 +343,13 @@ int main(int argc, char *argv[]){
for(i=0; i<SegmentCount; i++){ for(i=0; i<SegmentCount; i++){
if(!DLL.strcmp(".rdata")){ if(!DLL.strcmp(".rdata")){
DLL.skip(8); DLL.rdata.size = DLL.read32(); DLL.skip(16); DLL.rdata.size = DLL.read32();
DLL.rdata.offset = DLL.read32(); DLL.rdata.offset = DLL.read32();
DLL.skip(24); DLL.skip(16);
} else if(!DLL.strcmp(".data")){ } else if(!DLL.strcmp(".data")){
DLL.skip(8); DLL.data.size = DLL.read32(); DLL.skip(16); DLL.data.size = DLL.read32();
DLL.data.offset = DLL.read32(); DLL.data.offset = DLL.read32();
DLL.skip(24); DLL.skip(16);
} else DLL.skip(40); } else DLL.skip(40);
} }
if(DLL.rdata.size == 0) if(DLL.rdata.size == 0)
@ -409,7 +408,7 @@ int main(int argc, char *argv[]){
Shutdown_M("Unexpectedly reached end of binary"); Shutdown_M("Unexpectedly reached end of binary");
DLL.lookat(DLL.rdata); DLL.lookat(DLL.rdata);
COL.VTableAddress = (DLL.find32(COLAddress)) ? DLL.brc.position + ImageBase : (uint32_t)-1; COL.VTableAddress = (DLL.find32(COLAddress)) ? DLL.brc.position + ImageBase + 4: (uint32_t)-1;
if(newclass){ if(newclass){
if(!DLL.seek(COL.Fields.ClassDescriptorAddress - ImageBase)) if(!DLL.seek(COL.Fields.ClassDescriptorAddress - ImageBase))