Skip to content

Commit aea647d

Browse files
committed
Move the sig offsets into json
Allow for different mapping, split FFXIV_ACT_Plugin map and OverlayPlugin map
1 parent 8e0c62b commit aea647d

File tree

3 files changed

+55
-22
lines changed

3 files changed

+55
-22
lines changed

OpcodeExtractorVTable.cs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Text.Json.Nodes;
1+
using System.Text.Json;
2+
using System.Text.Json.Nodes;
23
using System.Text.RegularExpressions;
34

45
namespace OpcodeExtractor;
@@ -7,7 +8,7 @@ public static class OpcodeExtractorVTable
78
{
89
private static Regex WhitespaceRegex = new Regex("\\s");
910

10-
internal unsafe static Dictionary<int, string> Extract(JsonNode opcodeMapData, byte[] gameData, bool dumpAllOpcodes)
11+
internal unsafe static Dictionary<int, string> Extract(JsonNode opcodeMapData, byte[] gameData, bool dumpAllOpcodes, string inputMapKey)
1112
{
1213
var signatureData = opcodeMapData["signature"]!;
1314
string signature = "";
@@ -31,8 +32,8 @@ internal unsafe static Dictionary<int, string> Extract(JsonNode opcodeMapData, b
3132

3233
Dictionary<int, string> indexMap = [];
3334

34-
var mapData = opcodeMapData["map"]!;
35-
if (mapData.GetValueKind() != System.Text.Json.JsonValueKind.Object)
35+
var mapData = opcodeMapData[inputMapKey]!;
36+
if (mapData == null || mapData.GetValueKind() != System.Text.Json.JsonValueKind.Object)
3637
{
3738
Console.Error.WriteLine("Invalid data type for \"map\" in opcodes file");
3839
return [];
@@ -44,6 +45,12 @@ internal unsafe static Dictionary<int, string> Extract(JsonNode opcodeMapData, b
4445
indexMap[entryIndex] = entry.Key;
4546
}
4647

48+
if (!ReadJSONInt(opcodeMapData, "switchTableOffset_offset", out var switchTableOffset_offset)) return [];
49+
if (!ReadJSONInt(opcodeMapData, "switchTableCount_offset", out var switchTableCount_offset)) return [];
50+
if (!ReadJSONInt(opcodeMapData, "defaultCaseAddr_offset", out var defaultCaseAddr_offset)) return [];
51+
if (!ReadJSONInt(opcodeMapData, "imageBaseOffset_offset", out var imageBaseOffset_offset)) return [];
52+
if (!ReadJSONInt(opcodeMapData, "switchTableDataOffset_offset", out var switchTableDataOffset_offset)) return [];
53+
4754
Console.WriteLine($"Scanning for opcode maps for {indexMap.Count} opcodes, dumping all: {dumpAllOpcodes}");
4855

4956
var offset = matches[0];
@@ -54,11 +61,11 @@ internal unsafe static Dictionary<int, string> Extract(JsonNode opcodeMapData, b
5461
{
5562
byte* funcPtr = ptr + offset;
5663

57-
var switchTableOffset = *(sbyte*)(funcPtr + 15);
58-
var switchTableCount = *(int*)(funcPtr + 17);
59-
var defaultCaseAddr = offset + 23 + Common.ExtractRIPOffsetFromPtr(funcPtr + 23);
60-
var imageBaseOffset = offset + 30 + Common.ExtractRIPOffsetFromPtr(funcPtr + 30);
61-
var switchTableDataOffset = *(int*)(funcPtr + 40);
64+
var switchTableOffset = *(sbyte*)(funcPtr + switchTableOffset_offset);
65+
var switchTableCount = *(int*)(funcPtr + switchTableCount_offset);
66+
var defaultCaseAddr = offset + defaultCaseAddr_offset + Common.ExtractRIPOffsetFromPtr(funcPtr + defaultCaseAddr_offset);
67+
var imageBaseOffset = offset + imageBaseOffset_offset + Common.ExtractRIPOffsetFromPtr(funcPtr + imageBaseOffset_offset);
68+
var switchTableDataOffset = *(int*)(funcPtr + switchTableDataOffset_offset);
6269
var switchTableDataPtr = (int*)(ptr + imageBaseOffset + switchTableDataOffset);
6370

6471
for (int i = 0; i <= switchTableCount; ++i)
@@ -90,6 +97,20 @@ internal unsafe static Dictionary<int, string> Extract(JsonNode opcodeMapData, b
9097
return opcodeMap;
9198
}
9299

100+
private static bool ReadJSONInt(JsonNode opcodeMapData, string key, out int value)
101+
{
102+
var mapData = opcodeMapData[key]!;
103+
if (mapData.GetValueKind() != System.Text.Json.JsonValueKind.Number)
104+
{
105+
Console.Error.WriteLine($"Invalid data type for \"${key}\" in opcodes file");
106+
value = 0;
107+
return false;
108+
}
109+
110+
value = mapData.GetValue<int>();
111+
return true;
112+
}
113+
93114
private static unsafe int GetVFTableIndex(byte* caseBodyPtr)
94115
{
95116
int index;

Program.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,26 @@ static async Task<int> Main(string[] args)
2727
var outputFormatArgument = new Argument<OutputFormat>(
2828
name: "outputFormat",
2929
description: "Which output format to use. Default = \"All\"");
30+
var inputMapKeyArgument = new Argument<string>(
31+
name: "inputMapKey",
32+
description: "Which opcode map key to use. Default = \"FFXIV_ACT_Plugin\"");
3033
dumpAllOpcodesArgument.SetDefaultValue(false);
3134
outputFormatArgument.SetDefaultValue(OutputFormat.All);
35+
inputMapKeyArgument.SetDefaultValue("FFXIV_ACT_Plugin");
3236

3337
var rootCommand = new RootCommand("Map opcodes as defined in opcodeMapFile for executable gameExecutable");
3438
rootCommand.AddArgument(opcodeFileMapArgument);
3539
rootCommand.AddArgument(gameExecutableArgument);
3640
rootCommand.AddArgument(dumpAllOpcodesArgument);
3741
rootCommand.AddArgument(outputFormatArgument);
42+
rootCommand.AddArgument(inputMapKeyArgument);
3843

39-
rootCommand.SetHandler((opcodeMapFile, gameExecutable, dumpAllOpcodes, outputFormat) =>
44+
rootCommand.SetHandler((opcodeMapFile, gameExecutable, dumpAllOpcodes, outputFormat, inputMapKey) =>
4045
{
41-
var opcodes = ExtractOpcodes(opcodeMapFile!, gameExecutable!, dumpAllOpcodes);
46+
var opcodes = ExtractOpcodes(opcodeMapFile!, gameExecutable!, dumpAllOpcodes, inputMapKey);
4247
OutputOpcodes(opcodes, outputFormat);
4348
},
44-
opcodeFileMapArgument, gameExecutableArgument, dumpAllOpcodesArgument, outputFormatArgument);
49+
opcodeFileMapArgument, gameExecutableArgument, dumpAllOpcodesArgument, outputFormatArgument, inputMapKeyArgument);
4550

4651
return await rootCommand.InvokeAsync(args);
4752
}
@@ -93,7 +98,7 @@ private static void OutputOpcodesForOverlayPlugin(Dictionary<int, string> opcode
9398
/// <param name="opcodeMapFile">The opcode map to use</param>
9499
/// <param name="gameExecutable">The game executable to map</param>
95100
/// <param name="dumpAllOpcodes">Whether to dump all opcodes, or just the mapped opcodes</param>
96-
public static Dictionary<int, string> ExtractOpcodes(FileInfo opcodeMapFile, FileInfo gameExecutable, bool dumpAllOpcodes)
101+
public static Dictionary<int, string> ExtractOpcodes(FileInfo opcodeMapFile, FileInfo gameExecutable, bool dumpAllOpcodes, string inputMapKey)
97102
{
98103
var opcodeMapData = JsonSerializer.Deserialize<JsonNode>(File.ReadAllText(opcodeMapFile.FullName), new JsonSerializerOptions()
99104
{
@@ -107,7 +112,7 @@ public static Dictionary<int, string> ExtractOpcodes(FileInfo opcodeMapFile, Fil
107112
switch (opcodeMethod)
108113
{
109114
case "vtable":
110-
return OpcodeExtractorVTable.Extract(opcodeMapData, gameData, dumpAllOpcodes);
115+
return OpcodeExtractorVTable.Extract(opcodeMapData, gameData, dumpAllOpcodes, inputMapKey);
111116
}
112117
return [];
113118
}

resources/global.jsonc

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
// MOV R9D,dword ptr [R11 + RAX*offset switchD_141987dbf::switchdataD_14198a304 + 0x198a304]
2828
"45 8B 8C 83 ?? ?? ?? ??"
2929
],
30-
"map": {
31-
"RSVData": 127,
32-
"Countdown": 147,
33-
"CountdownCancel": 148,
30+
"switchTableOffset_offset": 15,
31+
"switchTableCount_offset": 17,
32+
"defaultCaseAddr_offset": 23,
33+
"imageBaseOffset_offset": 30,
34+
"switchTableDataOffset_offset": 40,
35+
"FFXIV_ACT_Plugin": {
3436
"StatusEffectList": 207,
3537
"StatusEffectList2": 209,
3638
"BossStatusEffectList": 211,
@@ -52,15 +54,20 @@
5254
"ActorMove": 272,
5355
"ActorSetPos": 275,
5456
"ActorCast": 277,
57+
"SystemLogMessage": 408,
58+
"PresetWaymark": 534,
59+
"Waymark": 535,
60+
"ActorGauge": 585
61+
},
62+
"OverlayPlugin": {
63+
"RSVData": 127,
64+
"Countdown": 147,
65+
"CountdownCancel": 148,
5566
"SpawnObject": 284,
5667
"DespawnObject": 285,
5768
"MapEffect": 402,
58-
"SystemLogMessage": 408,
5969
"BattleTalk2": 414,
6070
"NpcYell": 448,
61-
"PresetWaymark": 534,
62-
"Waymark": 535,
63-
"ActorGauge": 585,
6471
"CEDirector": 649
6572
}
6673
}

0 commit comments

Comments
 (0)