mirror of
https://codeberg.org/KeybadeBlox/JSRF-Decompilation.git
synced 2026-02-20 10:17:03 +03:00
Compare commits
3 commits
0922356a40
...
d435282a8b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d435282a8b | ||
|
|
149af27b9c | ||
|
|
5d22c39db6 |
10 changed files with 121 additions and 40 deletions
|
|
@ -31,17 +31,19 @@ src/JSRF/Jet2.exe: $(OBJ) $(LIB)
|
||||||
LIB.EXE /NOLOGO /MACHINE:X86 /DEF:$< /OUT:$@
|
LIB.EXE /NOLOGO /MACHINE:X86 /DEF:$< /OUT:$@
|
||||||
|
|
||||||
# Compile object files from source
|
# Compile object files from source
|
||||||
|
.c.obj:
|
||||||
|
CL.EXE /nologo /Wall /W4 /Ogityb0 /GfX /Fo$@ /c $<
|
||||||
.cpp.obj:
|
.cpp.obj:
|
||||||
CL.EXE /nologo /Wall /W4 /Ogityb0 /GfX /Fo$@ /c $<
|
CL.EXE /nologo /Wall /W4 /Ogityb0 /GfX /Fo$@ /c $<
|
||||||
|
|
||||||
|
|
||||||
# Header files used for each object
|
# Header files used for each object
|
||||||
src/JSRF/Jet2.obj: src/JSRF/Core.hpp src/Std.hpp src/XDK/D3D.hpp\
|
src/JSRF/Jet2.obj: src/JSRF/Core.hpp src/Std.hpp src/XDK/D3D.h\
|
||||||
src/XDK/Win32.hpp
|
src/XDK/Win32.h
|
||||||
|
|
||||||
src/JSRF/Core.obj: src/JSRF/Core.hpp src/Smilebit/MMatrix.hpp src/Std.hpp\
|
src/JSRF/Core.obj: src/JSRF/Core.hpp src/Smilebit/MMatrix.hpp src/Std.hpp\
|
||||||
src/XDK/D3D.hpp src/XDK/Win32.hpp
|
src/XDK/D3D.h src/XDK/Win32.h
|
||||||
|
|
||||||
src/JSRF/GameData.obj: src/JSRF/GameData.hpp
|
src/JSRF/GameData.obj: src/JSRF/GameData.hpp
|
||||||
|
|
||||||
src/XDK/CRT/CRT0.obj: src/XDK/Win32.hpp
|
src/XDK/CRT/CRT0.obj: src/XDK/Win32.h
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ Game and GameObj classes that form the foundation of the JSRF game code.
|
||||||
|
|
||||||
#include "../Smilebit/MMatrix.hpp"
|
#include "../Smilebit/MMatrix.hpp"
|
||||||
#include "../Std.hpp"
|
#include "../Std.hpp"
|
||||||
#include "../XDK/D3D.hpp"
|
#include "../XDK/D3D.h"
|
||||||
#include "../XDK/Win32.hpp"
|
#include "../XDK/Win32.h"
|
||||||
|
|
||||||
|
|
||||||
// TODO; move to header for Graphics COM object in Smilebit libraries
|
// TODO; move to header for Graphics COM object in Smilebit libraries
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Save data and closely-related runtime data.
|
||||||
|
|
||||||
#pragma bss_seg(".data")
|
#pragma bss_seg(".data")
|
||||||
|
|
||||||
#include "../XDK/Win32.hpp"
|
#include "../XDK/Win32.h"
|
||||||
#include "GameData.hpp"
|
#include "GameData.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Save data and closely-related runtime data.
|
||||||
#ifndef GAMEDATA_HPP
|
#ifndef GAMEDATA_HPP
|
||||||
#define GAMEDATA_HPP
|
#define GAMEDATA_HPP
|
||||||
|
|
||||||
#include "../XDK/Win32.hpp"
|
#include "../XDK/Win32.h"
|
||||||
|
|
||||||
|
|
||||||
// Data structure actually saved to disk
|
// Data structure actually saved to disk
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ Smilebit's stack-based matrix math library.
|
||||||
|
|
||||||
|
|
||||||
#include "../Std.hpp"
|
#include "../Std.hpp"
|
||||||
#include "../XDK/Win32.hpp"
|
#include "../XDK/Win32.h"
|
||||||
#include "MMatrix.hpp"
|
#include "MMatrix.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Smilebit's stack-based matrix math library.
|
||||||
#ifndef MMATRIX_HPP
|
#ifndef MMATRIX_HPP
|
||||||
#define MMATRIX_HPP
|
#define MMATRIX_HPP
|
||||||
|
|
||||||
#include "../XDK/D3D.hpp"
|
#include "../XDK/D3D.h"
|
||||||
|
|
||||||
|
|
||||||
// 4x4 matrix type
|
// 4x4 matrix type
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,24 @@
|
||||||
/* JSRF Decompilation: XDK/CRT0.cpp
|
/* JSRF Decompilation: XDK/CRT0.c
|
||||||
C runtime initialization.
|
C runtime initialization.
|
||||||
Like other CRT code, there's some magic here with symbols that get special
|
Like other CRT code, there's some magic here with symbols that get special
|
||||||
treatment from the compiler and linker.
|
treatment from the compiler and linker.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../Win32.hpp"
|
#include "../Win32.h"
|
||||||
|
|
||||||
|
|
||||||
// Every program is supposed to have a main(), so we can just assume its
|
// Every program is supposed to have a main(), so we can just assume its
|
||||||
// existence with a declaration here
|
// existence with a declaration here
|
||||||
int main();
|
int main(void);
|
||||||
|
|
||||||
|
|
||||||
void __stdcall mainCRTStartup ();
|
void __cdecl mainCRTStartup (void);
|
||||||
static DWORD _mainXapiStartup(LPVOID lpThreadParameter);
|
DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter);
|
||||||
|
|
||||||
|
|
||||||
// Address: 0x00148023
|
// Address: 0x00148023
|
||||||
// Matching: no
|
// Matching: no
|
||||||
void __stdcall mainCRTStartup() {
|
void __cdecl mainCRTStartup(void) {
|
||||||
/* The true entrypoint of the game, spawning a thread for the rest to run in
|
/* The true entrypoint of the game, spawning a thread for the rest to run in
|
||||||
The linker automatically sets this function to the entrypoint.
|
The linker automatically sets this function to the entrypoint.
|
||||||
*/
|
*/
|
||||||
|
|
@ -26,7 +26,7 @@ The linker automatically sets this function to the entrypoint.
|
||||||
|
|
||||||
// Address: 0x00147FB4
|
// Address: 0x00147FB4
|
||||||
// Matching: no
|
// Matching: no
|
||||||
DWORD _mainXapiStartup(LPVOID const lpThreadParameter) {
|
DWORD __stdcall mainXapiStartup(LPVOID const lpThreadParameter) {
|
||||||
/* Runs some initialization and then calls main() */
|
/* Runs some initialization and then calls main() */
|
||||||
main();
|
main();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
/* JSRF Decompilation: XDK/D3D.hpp
|
/* JSRF Decompilation: XDK/D3D.h
|
||||||
Direct3D8 declarations.
|
Direct3D8 declarations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef D3D_HPP
|
#ifndef D3D_H
|
||||||
#define D3D_HPP
|
#define D3D_H
|
||||||
|
|
||||||
#include "Win32.hpp"
|
#include "Win32.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef DWORD D3DCOLOR;
|
typedef DWORD D3DCOLOR;
|
||||||
|
|
@ -21,4 +26,10 @@ struct D3DRECT {
|
||||||
LONG x1, y1, x2, y2;
|
LONG x1, y1, x2, y2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
/* JSRF Decompilation: XDK/Win32.hpp
|
/* JSRF Decompilation: XDK/Win32.h
|
||||||
Definitions normally provided by Windows headers.
|
Definitions normally provided by Windows headers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WIN32_HPP
|
#ifndef WIN32_H
|
||||||
#define WIN32_HPP
|
#define WIN32_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// The famous Win32 typedefs
|
// The famous Win32 typedefs
|
||||||
typedef unsigned char UCHAR;
|
typedef unsigned char UCHAR;
|
||||||
|
|
@ -55,4 +61,10 @@ LPVOID __stdcall VirtualAlloc(
|
||||||
DWORD flProtect
|
DWORD flProtect
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -5,15 +5,20 @@
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.app.services.DataTypeQueryService;
|
import ghidra.app.services.DataTypeQueryService;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.data.ArrayDataType;
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
|
import ghidra.program.model.data.PointerDataType;
|
||||||
import ghidra.program.model.listing.Data;
|
import ghidra.program.model.listing.Data;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.Function;
|
||||||
import ghidra.program.model.symbol.Namespace;
|
import ghidra.program.model.symbol.Namespace;
|
||||||
import ghidra.program.model.symbol.SourceType;
|
import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.program.model.symbol.Symbol;
|
import ghidra.program.model.symbol.Symbol;
|
||||||
|
import ghidra.util.StringUtilities;
|
||||||
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
@ -34,7 +39,7 @@ public class EnhancedImport extends GhidraScript{
|
||||||
case "func": importFunc(addr, parts); break;
|
case "func": importFunc(addr, parts); break;
|
||||||
default: throw new Exception(
|
default: throw new Exception(
|
||||||
"Symbol type \"" + parts[1] +
|
"Symbol type \"" + parts[1] +
|
||||||
"\" on line " + Integer.toString(i) +
|
"\" on line " + String.valueOf(i) +
|
||||||
" is not \"data\" or \"func\""
|
" is not \"data\" or \"func\""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -54,21 +59,14 @@ public class EnhancedImport extends GhidraScript{
|
||||||
final Symbol s = Optional.ofNullable(getSymbolAt(addr))
|
final Symbol s = Optional.ofNullable(getSymbolAt(addr))
|
||||||
.orElse(createLabel(addr, name, ns, true, SourceType.USER_DEFINED));
|
.orElse(createLabel(addr, name, ns, true, SourceType.USER_DEFINED));
|
||||||
|
|
||||||
// Create data (TODO: parse type name to get base name, then pass base type to PointerDataType and ArrayDataType constructors to create final type)
|
// Create data
|
||||||
final List<DataType> foundTypes = state.getTool()
|
final Optional<DataType> t_maybe = makeType(parts[2]);
|
||||||
.getService(DataTypeQueryService.class)
|
if (t_maybe.orElse(null) instanceof DataType t) {
|
||||||
.findDataTypes(parts[2], null);
|
|
||||||
if (foundTypes.size() == 0) {
|
|
||||||
println(" can't find data type \"" + parts[2] + "\", skipping.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final DataType t = foundTypes.get(0); // Boldly assume first is right
|
|
||||||
|
|
||||||
clearListing(addr, addr.add(Math.max(t.getLength(), 1) - 1));
|
clearListing(addr, addr.add(Math.max(t.getLength(), 1) - 1));
|
||||||
currentProgram.getListing().createData(addr, t);
|
currentProgram.getListing().createData(addr, t);
|
||||||
|
|
||||||
println(" done.");
|
println(" done.");
|
||||||
|
} else println(", skipping.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String unqualified(final String qualifiedName) {
|
private static String unqualified(final String qualifiedName) {
|
||||||
|
|
@ -93,6 +91,64 @@ public class EnhancedImport extends GhidraScript{
|
||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<DataType> makeType(final String type) throws Exception {
|
||||||
|
/* Attempt to create the described type from a known base type */
|
||||||
|
final String baseName = StringUtilities.findWord(type, 0);
|
||||||
|
final List<DataType> foundTypes = state.getTool()
|
||||||
|
.getService(DataTypeQueryService.class)
|
||||||
|
.findDataTypes(baseName, null);
|
||||||
|
if (foundTypes.size() == 0) {
|
||||||
|
print(" can't find data type \"" + baseName + "\"");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(derivedType(
|
||||||
|
foundTypes.get(0), // Boldly assume first is right
|
||||||
|
type.substring(baseName.length())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DataType derivedType(
|
||||||
|
final DataType t,
|
||||||
|
final String modifiers
|
||||||
|
) throws Exception {
|
||||||
|
/* Return the given datatype with given pointer/array modifiers */
|
||||||
|
DataType ret = t;
|
||||||
|
for (int i = 0; i < modifiers.length(); i++) switch (modifiers.charAt(i)) {
|
||||||
|
case '*':
|
||||||
|
ret = new PointerDataType(ret);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
// Read array dimensions
|
||||||
|
final ArrayList<Integer> dims = new ArrayList<>();
|
||||||
|
do {
|
||||||
|
final String n = StringUtilities.findWord(modifiers, i+1);
|
||||||
|
i += n.length() + 1;
|
||||||
|
|
||||||
|
dims.add(Integer.valueOf(n));
|
||||||
|
} while (modifiers.charAt(i) == '[');
|
||||||
|
|
||||||
|
// Apply array
|
||||||
|
Collections.reverse(dims);
|
||||||
|
for (int dim : dims) ret = new ArrayDataType(ret, dim);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Exception(
|
||||||
|
"Unexpected character \"" +
|
||||||
|
String.valueOf(modifiers.charAt(i)) +
|
||||||
|
"\" in type modifiers"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
private void importFunc(
|
private void importFunc(
|
||||||
final Address addr,
|
final Address addr,
|
||||||
final String[] parts
|
final String[] parts
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue