-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFlowscriptFramework.cs
More file actions
127 lines (108 loc) · 4.38 KB
/
Copy pathFlowscriptFramework.cs
File metadata and controls
127 lines (108 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using p5rpc.flowscriptframework.interfaces;
using p5rpc.flowscriptframework.structs;
using p5rpc.flowscriptframework.Utils;
using Reloaded.Hooks.Definitions;
using System.Security.Cryptography;
using System.Text;
namespace p5rpc.flowscriptframework;
internal class FlowscriptFramework
{
private readonly Dictionary<ushort, FlowFunction> Functions;
private readonly List<AsmHookWrapper> FunctionCallHook;
private readonly IReloadedHooks _hooks;
private delegate FlowStatus d_flowFunction();
private delegate FlowFunctionInfo d_GetFlowFunction(ushort scriptTableSectionId, ushort scriptFunctionIndex, FlowFunctionInfo p_flowFunctionInfo);
private readonly d_GetFlowFunction _getFlowFunction;
internal unsafe FlowscriptFramework(IReloadedHooks hooks)
{
_hooks = hooks;
Functions = new Dictionary<ushort, FlowFunction>();
FunctionCallHook = new List<AsmHookWrapper>();
_getFlowFunction = GetFlowFunction;
Scanner.SigScan("48 8B 00 FF D0", "ExecuteFlowFunction", (result) => // 0x1416e7b3f
{
string[] asm =
{
"use64",
"sub rsp, 0x20",
Memory.PushCallerRegisters,
"mov rcx, rsi",
"mov rdx, rbp",
"mov r8, rax",
hooks.Utilities.GetAbsoluteCallMnemonics(_getFlowFunction, out var reverseWrapper),
Memory.PopCallerRegisters,
"add rsp, 0x20",
};
FunctionCallHook.Add(new AsmHookWrapper(
hooks.CreateAsmHook(asm, result, Reloaded.Hooks.Definitions.Enums.AsmHookBehaviour.ExecuteFirst).Activate(),
reverseWrapper
));
});
Scanner.SigScan("8B 47 ?? 29 43 ?? 8B 43", "ExecuteFlowFunction2", (result) => // 0x1416e7b7a
{
string[] asm =
{
"use64",
"sub rsp, 0x20",
Memory.PushCallerRegisters,
"mov rcx, rsi",
"mov rdx, rbp",
"mov r8, rdi",
hooks.Utilities.GetAbsoluteCallMnemonics(_getFlowFunction, out var reverseWrapper),
Memory.PopCallerRegisters,
"mov rdi, rax",
"add rsp, 0x20",
};
FunctionCallHook.Add(new AsmHookWrapper(
hooks.CreateAsmHook(asm, result, Reloaded.Hooks.Definitions.Enums.AsmHookBehaviour.ExecuteFirst).Activate(),
reverseWrapper
));
});
}
internal ushort Register(string functionName, int argCount, Func<FlowStatus> function, ushort idOverride = 0xffff)
{
ushort index = IsVanillaFunction(idOverride) ? idOverride : GenerateFunctionIndex(functionName);
var flowFunction = new FlowFunction(functionName, argCount, function);
d_flowFunction func = flowFunction.Invoke;
flowFunction.FunctionInvokeWrapper = _hooks.CreateReverseWrapper(func);
flowFunction.NativeStruct = new FlowFunctionInfo(flowFunction);
Functions.TryAdd(index, flowFunction);
Logger.Log($"Registered Function {functionName} with {argCount} args at index 0x{index:X4}");
return index;
}
private static ushort GenerateFunctionIndex(string functionName)
{
ushort hashValue;
byte[] bytes = Encoding.UTF8.GetBytes(functionName);
do
{
bytes = SHA256.HashData(bytes);
hashValue = BitConverter.ToUInt16(bytes, 0);
} while (IsVanillaFunction(hashValue));
return hashValue;
}
private static bool IsVanillaFunction(ushort index)
{
var section = (index & 0xF000) >> 0xc;
ushort[] highestVanillaIds = {
0x01a7,
0x1390,
0x21cc,
0x30b5,
0x40ae,
0x5007
};
if (section >= highestVanillaIds.Length || index > highestVanillaIds[section])
return false;
return true;
}
private unsafe FlowFunctionInfo GetFlowFunction(ushort scriptTableSectionId, ushort scriptFunctionIndex, FlowFunctionInfo p_flowFunctionInfo)
{
ushort scriptFunctionId = (ushort)(scriptTableSectionId * 0x1000 + scriptFunctionIndex);
if (Functions.TryGetValue(scriptFunctionId, out var flowFunction))
{
p_flowFunctionInfo = flowFunction.NativeStruct;
}
return p_flowFunctionInfo;
}
}