mirror of
https://github.com/morluto/rea.git
synced 2026-10-30 11:25:39 +00:00
feat(il2cpp): read member names, string literals and metadata versions 24 and 27 (#5326)
* feat(il2cpp): read member names, string literals and metadata versions 24 and 27 Adds field, property, event and parameter names with their owners, managed string literals, and the version 24 and 27 header layouts to inspect_il2cpp_metadata, with filtered pages for the new collections. Member decoding yields between row batches like the other row readers. * fix(il2cpp): bound metadata expansion and query parameter owners * test(il2cpp): cover nonempty property and event tables --------- Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
This commit is contained in:
1 parent
052956af34
commit
21e0c580e7
24 files changed
+1707
-315
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import { Il2cppMetadataFormatFailure } from "./Il2cppMetadataFormat.js";
|
||||
import { setImmediate } from "node:timers/promises";
|
||||
import {
|
||||
readStableArtifact,
|
||||
@@ -17,6 +18,7 @@ import type { ExecutionOptions } from "../application/AnalysisProvider.js";
|
||||
import type { Il2cppMetadataPort } from "../application/il2cpp/Il2cppMetadataPort.js";
|
||||
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
||||
import { createEvidence } from "../domain/evidence.js";
|
||||
import { createIl2cppMetadataAdmission } from "./Il2cppMetadataAdmission.js";
|
||||
import { jsonValueByteLength } from "../domain/jsonValueByteLength.js";
|
||||
import {
|
||||
AnalysisAccessDeniedError,
|
||||
@@ -36,7 +38,6 @@ import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
||||
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
||||
import { err, ok, type Result } from "../domain/result.js";
|
||||
import {
|
||||
Il2cppMetadataFormatFailure,
|
||||
readIl2cppMetadataSteps,
|
||||
type Il2cppMetadataRowCounts,
|
||||
} from "./Il2cppMetadataFile.js";
|
||||
@@ -51,25 +52,6 @@ const OPERATION = "inspect_il2cpp_metadata";
|
||||
const INPUT_BYTES = 256 * 1024 * 1024;
|
||||
// A 12.9 MB Unity 6000.4 file with 112,232 methods serializes to 7.8 MB.
|
||||
const OUTPUT_BYTES = 64 * 1024 * 1024;
|
||||
// The smallest JSON a row can take: empty names and one-digit numbers.
|
||||
const EMPTY_NAME = JSON.stringify("").length;
|
||||
|
||||
/** JSON characters of one row besides its strings, with one-digit numbers. */
|
||||
const rowOverhead = (row: Record<string, string | number>) =>
|
||||
JSON.stringify(row).length -
|
||||
2 * Object.values(row).filter((value) => typeof value === "string").length;
|
||||
const IMAGE_ROW = rowOverhead({ name: "", type_start: 0, type_count: 0 });
|
||||
const TYPE_ROW = rowOverhead({
|
||||
name: "",
|
||||
namespace: "",
|
||||
method_start: 0,
|
||||
method_count: 0,
|
||||
nested_type_start: 0,
|
||||
nested_type_count: 0,
|
||||
declaring_type: 0,
|
||||
});
|
||||
const METHOD_ROW = rowOverhead({ name: "", declaring_type: 0 });
|
||||
|
||||
const failureForPrimary = (cause: unknown, path: string): AnalysisError => {
|
||||
if (cause instanceof AnalysisError) return cause;
|
||||
if (cause instanceof ArtifactReaderFailure && cause.reason === "integrity")
|
||||
@@ -170,12 +152,6 @@ const reportLimit = (path: string, maximumBytes: number) =>
|
||||
{ maximum_report_bytes: maximumBytes },
|
||||
);
|
||||
|
||||
/** Lower bound from row counts alone, so oversized files fail before rows are allocated. */
|
||||
const countLowerBound = ({ images, types, methods }: Il2cppMetadataRowCounts) =>
|
||||
images * (IMAGE_ROW + EMPTY_NAME) +
|
||||
types * (TYPE_ROW + 2 * EMPTY_NAME) +
|
||||
methods * (METHOD_ROW + EMPTY_NAME);
|
||||
|
||||
const sourceArtifact = (path: string, snapshot: StableArtifactSnapshot) => ({
|
||||
path,
|
||||
sha256: snapshot.sha256,
|
||||
@@ -301,11 +277,14 @@ export class Il2cppMetadataProvider implements Il2cppMetadataPort {
|
||||
observed.artifact = artifact;
|
||||
assertArtifactReadActive(options?.signal);
|
||||
const limit = this.outputBytes;
|
||||
const admission = createIl2cppMetadataAdmission(limit, () => {
|
||||
throw reportLimit(input.path, limit);
|
||||
});
|
||||
const steps = readIl2cppMetadataSteps(snapshot.bytes, {
|
||||
...admission,
|
||||
beforeRows: (counts) => {
|
||||
observed.counts = counts;
|
||||
if (countLowerBound(counts) > limit)
|
||||
throw reportLimit(input.path, limit);
|
||||
admission.beforeRows(counts);
|
||||
},
|
||||
});
|
||||
let step = steps.next();
|
||||
@@ -319,9 +298,9 @@ export class Il2cppMetadataProvider implements Il2cppMetadataPort {
|
||||
...decoded,
|
||||
artifact,
|
||||
limitations: [
|
||||
"Only unencrypted global-metadata.dat versions 29, 31 and 39 are decoded; image, type and method names and counts are observed file content, not runtime behavior.",
|
||||
"Native code addresses, IL2CPP binary registration, fields, properties, signatures and generic instances are not recovered.",
|
||||
"declaring_type for types is derived from the nestedTypes section; row positions are the metadata TypeDefinitionIndex and MethodIndex values.",
|
||||
"Only unencrypted global-metadata.dat versions 24, 27, 29, 31 and 39 are decoded; names, counts and string literals are observed file content, not runtime behavior.",
|
||||
"Native code addresses, IL2CPP binary registration, member types, signatures and generic instances are not recovered.",
|
||||
"declaring_type for types is derived from the nestedTypes section, and member and parameter owners from the owners' index ranges; row positions are the metadata indices.",
|
||||
],
|
||||
};
|
||||
if (jsonValueByteLength(report, limit) > limit)
|
||||
|
||||
Reference in new issue
Block a user