This commit is contained in:
Christian Semmler 2023-06-27 20:48:48 +02:00
commit 4f68528f82
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
10 changed files with 343 additions and 9 deletions

View File

@ -6,7 +6,7 @@ Generally, decompilation is a fairly advanced skill. If you aren't already famil
## Ghidra Server
For documenting the original binaries and generating pseudocode that we decompile with, we primarily use [Ghidra](https://ghidra-sre.org/) (it's free and open source). To help with collaboration, we have a shared Ghidra repository with all of our current work. It is available to the public but read-only; to contribute to it yourself, you'll need approval from a current maintainer.
For documenting the original binaries and generating pseudocode that we decompile with, we primarily use [Ghidra](https://ghidra-sre.org/) (it's free and open source). To help with collaboration, we have a shared Ghidra repository with all of our current work. You are free to check it out and mess around with it locally, however to prevent sabotage, you will need to request permission before you can push back to the server (ask in the Matrix room).
To access the Ghidra repository, use the following details:
@ -21,6 +21,7 @@ In general, we're not exhaustively strict about coding style, but there are some
- `PascalCase` for classes and function names.
- `m_camelCase` for member variables.
- `g_camelCase` for global variables.
- `p_camelCase` for function parameters.
## Kinds of Contributions

View File

@ -1,6 +1,130 @@
#include "mxdsfile.h"
#include <stdio.h>
#define SI_MAJOR_VERSION 2
#define SI_MINOR_VERSION 2
#define FOURCC(a, b, c, d) (((a) << 0) | ((b) << 8) | ((c) << 16) | ((d) << 24))
// OFFSET: LEGO1 0x100cc4b0
MxDSFile::MxDSFile(const char *filename, unsigned long skipReadingChunks)
{
m_filename = filename;
m_skipReadingChunks = skipReadingChunks;
}
// OFFSET: LEGO1 0x100bfed0
MxDSFile::~MxDSFile()
{
Close();
}
// OFFSET: LEGO1 0x100cc590
long MxDSFile::Open(unsigned long uStyle)
{
// No idea what's stopping this one matching, but I'm pretty
// confident it has the correct behavior.
long longResult = 1;
memset(&m_io, 0, sizeof(MXIOINFO));
if (m_io.Open(m_filename.GetData(), uStyle) != 0) {
return -1;
}
m_io.SetBuffer(NULL, 0, 0);
m_position = 0;
if (m_skipReadingChunks == 0) {
longResult = ReadChunks();
}
if (longResult != 0) {
Close(); // vtable + 0x18
}
else {
Seek(0, 0); // vtable + 0x24
}
return longResult;
}
// OFFSET: LEGO1 0x100cc780
long MxDSFile::Read(unsigned char *pch, unsigned long cch)
{
if (m_io.Read((char*)pch, cch) != cch)
return -1;
m_position += cch;
return 0;
}
// OFFSET: LEGO1 0x100cc620
long MxDSFile::ReadChunks()
{
_MMCKINFO topChunk;
_MMCKINFO childChunk;
char tempBuffer[80];
topChunk.fccType = FOURCC('O', 'M', 'N', 'I');
if (m_io.Descend(&topChunk, NULL, MMIO_FINDRIFF) != 0) {
return -1;
}
childChunk.ckid = FOURCC('M', 'x', 'H', 'd');
if (m_io.Descend(&childChunk, &topChunk, 0) != 0) {
return -1;
}
m_io.Read((char*)&m_header, 0xc);
if ((m_header.majorVersion == SI_MAJOR_VERSION) && (m_header.minorVersion == SI_MINOR_VERSION))
{
childChunk.ckid = FOURCC('M', 'x', 'O', 'f');
if (m_io.Descend(&childChunk, &topChunk, 0) != 0) {
return -1;
}
unsigned long* pLengthInDWords = &m_lengthInDWords;
m_io.Read((char *)pLengthInDWords, 4);
m_pBuffer = malloc(*pLengthInDWords * 4);
m_io.Read((char*)m_pBuffer, *pLengthInDWords * 4);
return 0;
}
else
{
sprintf(tempBuffer, "Wrong SI file version. %d.%d expected.", SI_MAJOR_VERSION, SI_MINOR_VERSION);
MessageBoxA(NULL, tempBuffer, NULL, MB_ICONERROR);
return -1;
}
}
// OFFSET: LEGO1 0x100cc7b0
long MxDSFile::Seek(long lOffset, int iOrigin)
{
return (m_position = m_io.Seek(lOffset, iOrigin)) == -1 ? -1 : 0;
}
// OFFSET: LEGO1 0x100cc7e0
unsigned long MxDSFile::GetBufferSize()
{
return this->m_buffersize;
return m_header.bufferSize;
}
// OFFSET: LEGO1 0x100cc7f0
unsigned long MxDSFile::GetStreamBuffersNum()
{
return m_header.streamBuffersNum;
}
// OFFSET: LEGO1 0x100cc740
long MxDSFile::Close()
{
m_io.Close(0);
m_position = -1;
memset(&m_header, 0, sizeof(m_header));
if (m_lengthInDWords != 0)
{
m_lengthInDWords = 0;
free(m_pBuffer);
m_pBuffer = NULL;
}
return 0;
}

View File

@ -1,20 +1,46 @@
#ifndef MXDSFILE_H
#define MXDSFILE_H
class MxDSFile
#include "mxcore.h"
#include "mxstring.h"
#include "mxioinfo.h"
#include "mxdssource.h"
class MxDSFile : public MxDSSource
{
public:
__declspec(dllexport) MxDSFile(const char *,unsigned long);
__declspec(dllexport) MxDSFile(const char *filename, unsigned long skipReadingChunks);
__declspec(dllexport) virtual ~MxDSFile();
__declspec(dllexport) virtual long Close();
__declspec(dllexport) virtual unsigned long GetBufferSize();
__declspec(dllexport) virtual unsigned long GetStreamBuffersNum();
__declspec(dllexport) virtual long Open(unsigned long);
__declspec(dllexport) virtual long Close();
__declspec(dllexport) virtual long Read(unsigned char *,unsigned long);
__declspec(dllexport) virtual long Seek(long,int);
__declspec(dllexport) virtual unsigned long GetBufferSize();
__declspec(dllexport) virtual unsigned long GetStreamBuffersNum();
private:
char m_unknown[0x70];
unsigned long m_buffersize;
long ReadChunks();
struct ChunkHeader {
ChunkHeader()
: majorVersion(0)
, minorVersion(0)
, bufferSize(0)
, streamBuffersNum(0)
{}
unsigned short majorVersion;
unsigned short minorVersion;
unsigned long bufferSize;
short streamBuffersNum;
short reserved;
};
MxString m_filename;
MXIOINFO m_io;
ChunkHeader m_header;
// If false, read chunks immediately on open, otherwise
// skip reading chunks until ReadChunks is explicitly called.
unsigned long m_skipReadingChunks;
};
#endif // MXDSFILE_H

14
LEGO1/mxdssource.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "mxdssource.h"
// OFFSET: LEGO1 0x100bffd0
void MxDSSource::SomethingWhichCallsRead(void* pUnknownObject)
{
// TODO: Calls read, reading into a buffer somewhere in pUnknownObject.
Read(NULL, 0);
}
// OFFSET: LEGO1 0x100bfff0
long MxDSSource::GetLengthInDWords()
{
return m_lengthInDWords;
}

30
LEGO1/mxdssource.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef MXDSSOURCE_H
#define MXDSSOURCE_H
#include "mxcore.h"
class MxDSSource : public MxCore
{
public:
MxDSSource()
: m_lengthInDWords(0)
, m_pBuffer(0)
, m_position(-1)
{}
virtual long Open(unsigned long) = 0;
virtual long Close() = 0;
virtual void SomethingWhichCallsRead(void* pUnknownObject);
virtual long Read(unsigned char *, unsigned long) = 0;
virtual long Seek(long, int) = 0;
virtual unsigned long GetBufferSize() = 0;
virtual unsigned long GetStreamBuffersNum() = 0;
virtual long GetLengthInDWords();
protected:
unsigned long m_lengthInDWords;
void* m_pBuffer;
long m_position;
};
#endif // MXDSSOURCE_H

49
LEGO1/mxioinfo.cpp Normal file
View File

@ -0,0 +1,49 @@
#include "mxioinfo.h"
// OFFSET: LEGO1 0x100cc800
MXIOINFO::MXIOINFO()
{
memset(&m_info, 0, sizeof(MMIOINFO));
}
// OFFSET: LEGO1 0x100cc820
MXIOINFO::~MXIOINFO()
{
Close(0);
}
// OFFSET: LEGO1 0x100cc830
unsigned short MXIOINFO::Open(const char *filename, DWORD fdwOpen)
{
return 0;
}
// OFFSET: LEGO1 0x100cc8e0
void MXIOINFO::Close(long arg)
{
}
// OFFSET: LEGO1 0x100cc930
unsigned long MXIOINFO::Read(HPSTR pch, LONG cch)
{
return 0;
}
// OFFSET: LEGO1 0x100cca00
LONG MXIOINFO::Seek(LONG lOffset, int iOrigin)
{
return 0;
}
// OFFSET: LEGO1 0x100ccbc0
void MXIOINFO::SetBuffer(LPSTR pchBuffer, LONG cchBuffer, LONG unk)
{
}
// OFFSET: LEGO1 0x100cce60
unsigned short MXIOINFO::Descend(LPMMCKINFO pmmcki, const MMCKINFO *pmmckiParent, UINT fuDescend)
{
return 0;
}

View File

@ -1,10 +1,22 @@
#ifndef MXIOINFO_H
#define MXIOINFO_H
#include "legoinc.h"
#include "mmsystem.h"
class MXIOINFO
{
public:
MXIOINFO();
__declspec(dllexport) ~MXIOINFO();
unsigned short Open(const char *filename, DWORD fdwOpen);
void Close(long arg);
LONG Seek(LONG lOffset, int iOrigin);
unsigned long Read(HPSTR pch, LONG cch);
void SetBuffer(LPSTR pchBuffer, LONG cchBuffer, LONG unk);
unsigned short Descend(LPMMCKINFO pmmcki, const MMCKINFO *pmmckiParent, UINT fuDescend);
MMIOINFO m_info;
};
#endif // MXIOINFO_H

View File

@ -16,6 +16,8 @@ class MxString : public MxCore
void ToLowerCase();
const MxString &operator=(MxString *);
inline const char *GetData() const { return m_data; }
private:
char *m_data;
unsigned short m_length;

View File

@ -61,7 +61,10 @@ CLEAN :
-@erase "$(INTDIR)\mxautolocker.obj"
-@erase "$(INTDIR)\mxcore.obj"
-@erase "$(INTDIR)\mxcriticalsection.obj"
-@erase "$(INTDIR)\mxdsfile.obj"
-@erase "$(INTDIR)\mxdsobject.obj"
-@erase "$(INTDIR)\mxdssource.obj"
-@erase "$(INTDIR)\mxioinfo.obj"
-@erase "$(INTDIR)\mxomni.obj"
-@erase "$(INTDIR)\mxomnicreateflags.obj"
-@erase "$(INTDIR)\mxomnicreateparam.obj"
@ -138,7 +141,10 @@ LINK32_OBJS= \
"$(INTDIR)\mxautolocker.obj" \
"$(INTDIR)\mxcore.obj" \
"$(INTDIR)\mxcriticalsection.obj" \
"$(INTDIR)\mxdsfile.obj" \
"$(INTDIR)\mxdsobject.obj" \
"$(INTDIR)\mxdssource.obj" \
"$(INTDIR)\mxioinfo.obj" \
"$(INTDIR)\mxomni.obj" \
"$(INTDIR)\mxomnicreateflags.obj" \
"$(INTDIR)\mxomnicreateparam.obj" \
@ -181,7 +187,10 @@ CLEAN :
-@erase "$(INTDIR)\mxautolocker.obj"
-@erase "$(INTDIR)\mxcore.obj"
-@erase "$(INTDIR)\mxcriticalsection.obj"
-@erase "$(INTDIR)\mxdsfile.obj"
-@erase "$(INTDIR)\mxdsobject.obj"
-@erase "$(INTDIR)\mxdssource.obj"
-@erase "$(INTDIR)\mxioinfo.obj"
-@erase "$(INTDIR)\mxomni.obj"
-@erase "$(INTDIR)\mxomnicreateflags.obj"
-@erase "$(INTDIR)\mxomnicreateparam.obj"
@ -260,7 +269,10 @@ LINK32_OBJS= \
"$(INTDIR)\mxautolocker.obj" \
"$(INTDIR)\mxcore.obj" \
"$(INTDIR)\mxcriticalsection.obj" \
"$(INTDIR)\mxdsfile.obj" \
"$(INTDIR)\mxdsobject.obj" \
"$(INTDIR)\mxdssource.obj" \
"$(INTDIR)\mxioinfo.obj" \
"$(INTDIR)\mxomni.obj" \
"$(INTDIR)\mxomnicreateflags.obj" \
"$(INTDIR)\mxomnicreateparam.obj" \
@ -520,7 +532,9 @@ DEP_CPP_LEGOO=\
".\LEGO1\mxdsaction.h"\
".\LEGO1\mxdsfile.h"\
".\LEGO1\mxdsobject.h"\
".\LEGO1\mxdssource.h"\
".\LEGO1\mxeventmanager.h"\
".\LEGO1\mxioinfo.h"\
".\LEGO1\mxmusicmanager.h"\
".\LEGO1\mxnotificationmanager.h"\
".\LEGO1\mxobjectfactory.h"\
@ -641,8 +655,11 @@ DEP_CPP_MXOMN=\
SOURCE=.\LEGO1\mxvideoparam.cpp
DEP_CPP_MXVID=\
".\LEGO1\legoinc.h"\
".\LEGO1\mxbool.h"\
".\LEGO1\mxcore.h"\
".\LEGO1\mxpalette.h"\
".\LEGO1\mxrect32.h"\
".\LEGO1\mxresult.h"\
".\LEGO1\mxvariabletable.h"\
".\LEGO1\mxvideoparam.h"\
".\LEGO1\mxvideoparamflags.h"\
@ -680,6 +697,7 @@ DEP_CPP_MXOMNI=\
".\LEGO1\mxomnicreateparambase.h"\
".\LEGO1\mxpalette.h"\
".\LEGO1\mxrect32.h"\
".\LEGO1\mxresult.h"\
".\LEGO1\mxstring.h"\
".\LEGO1\mxvariabletable.h"\
".\LEGO1\mxvideoparam.h"\
@ -704,6 +722,7 @@ DEP_CPP_MXOMNIC=\
".\LEGO1\mxomnicreateparambase.h"\
".\LEGO1\mxpalette.h"\
".\LEGO1\mxrect32.h"\
".\LEGO1\mxresult.h"\
".\LEGO1\mxstring.h"\
".\LEGO1\mxvariabletable.h"\
".\LEGO1\mxvideoparam.h"\
@ -769,7 +788,9 @@ DEP_CPP_LEGON=\
".\LEGO1\mxdsaction.h"\
".\LEGO1\mxdsfile.h"\
".\LEGO1\mxdsobject.h"\
".\LEGO1\mxdssource.h"\
".\LEGO1\mxeventmanager.h"\
".\LEGO1\mxioinfo.h"\
".\LEGO1\mxmusicmanager.h"\
".\LEGO1\mxnotificationmanager.h"\
".\LEGO1\mxobjectfactory.h"\
@ -838,6 +859,7 @@ DEP_CPP_MXUNK=\
".\LEGO1\mxbool.h"\
".\LEGO1\mxcore.h"\
".\LEGO1\mxcriticalsection.h"\
".\LEGO1\mxresult.h"\
".\LEGO1\mxunknown100dc6b0.h"\
@ -857,6 +879,7 @@ DEP_CPP_MXVIDEO=\
".\LEGO1\mxcriticalsection.h"\
".\LEGO1\mxpalette.h"\
".\LEGO1\mxrect32.h"\
".\LEGO1\mxresult.h"\
".\LEGO1\mxunknown100dc6b0.h"\
".\LEGO1\mxvariabletable.h"\
".\LEGO1\mxvideomanager.h"\
@ -874,13 +897,62 @@ DEP_CPP_MXVIDEO=\
SOURCE=.\LEGO1\mxpalette.cpp
DEP_CPP_MXPAL=\
".\LEGO1\mxbool.h"\
".\LEGO1\mxcore.h"\
".\LEGO1\mxpalette.h"\
".\LEGO1\mxresult.h"\
"$(INTDIR)\mxpalette.obj" : $(SOURCE) $(DEP_CPP_MXPAL) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LEGO1\mxioinfo.cpp
DEP_CPP_MXIOI=\
".\LEGO1\mxioinfo.h"\
"$(INTDIR)\mxioinfo.obj" : $(SOURCE) $(DEP_CPP_MXIOI) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LEGO1\mxdsfile.cpp
DEP_CPP_MXDSF=\
".\LEGO1\mxbool.h"\
".\LEGO1\mxcore.h"\
".\LEGO1\mxdsfile.h"\
".\LEGO1\mxdssource.h"\
".\LEGO1\mxioinfo.h"\
".\LEGO1\mxstring.h"\
"$(INTDIR)\mxdsfile.obj" : $(SOURCE) $(DEP_CPP_MXDSF) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LEGO1\mxdssource.cpp
DEP_CPP_MXDSS=\
".\LEGO1\mxbool.h"\
".\LEGO1\mxcore.h"\
".\LEGO1\mxdssource.h"\
"$(INTDIR)\mxdssource.obj" : $(SOURCE) $(DEP_CPP_MXDSS) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
# End Target
################################################################################
@ -930,7 +1002,9 @@ DEP_CPP_ISLE_=\
".\LEGO1\mxdsaction.h"\
".\LEGO1\mxdsfile.h"\
".\LEGO1\mxdsobject.h"\
".\LEGO1\mxdssource.h"\
".\LEGO1\mxeventmanager.h"\
".\LEGO1\mxioinfo.h"\
".\LEGO1\mxmusicmanager.h"\
".\LEGO1\mxnotificationmanager.h"\
".\LEGO1\mxobjectfactory.h"\
@ -990,7 +1064,9 @@ DEP_CPP_ISLE_=\
".\LEGO1\mxdsaction.h"\
".\LEGO1\mxdsfile.h"\
".\LEGO1\mxdsobject.h"\
".\LEGO1\mxdssource.h"\
".\LEGO1\mxeventmanager.h"\
".\LEGO1\mxioinfo.h"\
".\LEGO1\mxmusicmanager.h"\
".\LEGO1\mxnotificationmanager.h"\
".\LEGO1\mxobjectfactory.h"\

BIN
isle.mdp

Binary file not shown.