Skip to content

Commit b7afe78

Browse files
committed
Lib: Add more supported dynCall offset calculations
1 parent ed90670 commit b7afe78

1 file changed

Lines changed: 23 additions & 2 deletions

File tree

LibCpp2IL/Wasm/WasmFile.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ public WasmFunctionDefinition GetFunctionFromIndexAndSignature(ulong index, stri
8989
index = (ulong)((long)(index & coefficients.andWith) + coefficients.addConstant);
9090

9191
//Use element section to look up real index
92-
var realIndex = ElementSection.Elements[0].FunctionIndices![(int)index]; //Minus 1 because the first element in the actual memory layout is FFFFFFFF
92+
//Ghidra plugin inserts a 00000000 entry at the top of the table which makes it look like you don't need the -1 here
93+
//i.e. pointer in metadata is 4386, you want the item which ghidra shows [4386] at the end of the line for
94+
//but we don't have that, so without the -1 this would map to what ghidra shows as [4387], which is wrong.
95+
var realIndex = ElementSection.Elements[0].FunctionIndices![(int)index - 1];
9396

9497
//Look up real index in function table
9598
return FunctionTable[(int)realIndex];
@@ -155,6 +158,8 @@ private void CalculateDynCallOffsets()
155158
LibLogger.WarnNewline($"\t\tCouldn't calculate coefficients for {signature}, got only 2 instructions but the last was {relevantInstructions[^1].Mnemonic}, not I32And or I32Add");
156159
continue;
157160
}
161+
162+
LibLogger.VerboseNewline($"\t\tCoefficients for {signature}: andWith {andWith}, addConstant {add}");
158163
}
159164
else if (relevantInstructions.Length == 4)
160165
{
@@ -176,12 +181,15 @@ private void CalculateDynCallOffsets()
176181
add = -add;
177182
LibLogger.WarnNewline($"\t\tCoefficient for {signature} using I32Sub not I32Add, this may not work!");
178183
}
184+
185+
LibLogger.VerboseNewline($"\t\tCoefficients for {signature}: andWith {andWith}, addConstant {add}");
179186
}
180187
else if (disassembled.All(d => d.Mnemonic is WasmMnemonic.LocalGet or WasmMnemonic.CallIndirect or WasmMnemonic.End))
181188
{
182189
//No remapping
183190
andWith = int.MaxValue;
184191
add = 0;
192+
LibLogger.VerboseNewline($"\t\tAssuming index is not manipulated for dynCall_{signature} (method only contains LocalGet, CallIndirect, End instructions)");
185193
}
186194
else if (disassembled[^1].Mnemonic == WasmMnemonic.End && disassembled[^2].Mnemonic == WasmMnemonic.CallIndirect && disassembled[^3].Mnemonic == WasmMnemonic.LocalGet && (byte)disassembled[^3].Operands[0] == 0)
187195
{
@@ -190,13 +198,26 @@ private void CalculateDynCallOffsets()
190198
LibLogger.VerboseNewline($"\t\tAssuming index is not manipulated for dynCall_{signature} (method ends with LocalGet 0, CallIndirect, End)");
191199
andWith = int.MaxValue;
192200
add = 0;
201+
} else if (disassembled.FindIndex(i => i.Mnemonic == WasmMnemonic.CallIndirect) is var callIdx and > 0 &&
202+
Enumerable.Range(0, callIdx).Select(i => disassembled[i]).All(i => i.Mnemonic == WasmMnemonic.LocalGet))
203+
{
204+
//CallIndirect and everything before is just LocalGet, we assume not modified
205+
LibLogger.VerboseNewline($"\t\tAssuming index is not manipulated for dynCall_{signature} (only LocalGet instructions before the CallIndirect)");
206+
andWith = int.MaxValue;
207+
add = 0;
208+
} else if (disassembled.FindIndex(i => i.Mnemonic == WasmMnemonic.CallIndirect) is var callIdx2 and > 0 && disassembled[callIdx2 - 1] is { Mnemonic: WasmMnemonic.LocalGet, Operands: [(byte) 0] })
209+
{
210+
//CallIndirect with LocalGet 0 just before, assume not modified - this is sketchy though
211+
LibLogger.VerboseNewline($"\t\tAssuming index is not manipulated for dynCall_{signature} (LocalGet 0 instruction immediately before the CallIndirect)");
212+
andWith = int.MaxValue;
213+
add = 0;
193214
}
194215
else
195216
{
196217
LibLogger.WarnNewline($"\t\tCouldn't calculate coefficients for {signature}, got {relevantInstructions.Length} instructions; expecting 4");
197218
continue;
198219
}
199-
220+
200221
DynCallCoefficients[signature] = new() { andWith = andWith, addConstant = add, };
201222
}
202223
}

0 commit comments

Comments
 (0)