fix(dotnet): correct CLI pointer and byref signatures

This commit is contained in:
N0zoM1z0 2026-07-17 20:01:57 +08:00
parent dcd94f1472
commit fb9ff5659d
3 changed files with 40 additions and 8 deletions

View File

@ -362,6 +362,11 @@ const ELEMENT_TYPES = new Map<number, string>([
[0x1c, "object"],
]);
const ELEMENT_TYPE_SUFFIXES = new Map<number, string>([
[0x0f, "*"],
[0x10, "&"],
]);
const readTypeSignature = (
blob: Buffer,
offset: number,
@ -370,13 +375,10 @@ const readTypeSignature = (
if (kind === undefined) throw new RangeError("truncated type signature");
const named = ELEMENT_TYPES.get(kind);
if (named !== undefined) return { value: named, next: offset + 1 };
if (kind === 0x0f) {
const suffix = ELEMENT_TYPE_SUFFIXES.get(kind);
if (suffix !== undefined) {
const inner = readTypeSignature(blob, offset + 1);
return { value: `${inner.value}&`, next: inner.next };
}
if (kind === 0x10) {
const inner = readTypeSignature(blob, offset + 1);
return { value: `${inner.value}*`, next: inner.next };
return { value: `${inner.value}${suffix}`, next: inner.next };
}
if (kind === 0x11 || kind === 0x12) {
const token = readCompressed(blob, offset + 1);

View File

@ -2,9 +2,11 @@ interface ManagedPeFixtureOptions {
readonly cliFlags?: number;
readonly corruptMetadataSignature?: boolean;
readonly fieldName?: string;
readonly fieldSignature?: Buffer;
readonly ilBody?: Buffer;
readonly metadataValidMaskExtra?: bigint;
readonly methodName?: string;
readonly methodSignature?: Buffer;
readonly mvid?: Buffer;
readonly pinvoke?: {
readonly importName?: string;
@ -292,8 +294,12 @@ export const buildManagedPeFixture = (
strings.add(name),
);
const tokenBlob = blobs.add(Buffer.from("b77a5c561934e089", "hex"));
const fieldSignature = blobs.add(Buffer.from([0x06, 0x08]));
const methodSignature = blobs.add(Buffer.from([0x00, 0x00, 0x01]));
const fieldSignature = blobs.add(
options.fieldSignature ?? Buffer.from([0x06, 0x08]),
);
const methodSignature = blobs.add(
options.methodSignature ?? Buffer.from([0x00, 0x00, 0x01]),
);
const constructorSignature = blobs.add(Buffer.from([0x20, 0x01, 0x01, 0x0e]));
const attributeBlob = blobs.add(
fixedStringAttributeBlob(

View File

@ -153,6 +153,30 @@ describe("managed PE/CLI static provider", () => {
expect(boundaries.identity_scope.requires_mvid).toBe(result.module?.mvid);
});
it("decodes ECMA-335 pointer and byref element types without swapping them", () => {
const bytes = buildManagedPeFixture({
fieldSignature: Buffer.from([0x06, 0x1d, 0x0f, 0x0f, 0x08]),
methodSignature: Buffer.from([
0x00, 0x02, 0x10, 0x08, 0x0f, 0x08, 0x10, 0x0e,
]),
});
const result = inspectManagedMembersBytes(
bytes,
target(bytes),
memberLimits,
);
expect(result.fields.items[0]?.signature).toMatchObject({
parse_status: "decoded",
field_type: "i4**[]",
});
expect(result.methods.items[0]?.signature).toMatchObject({
parse_status: "decoded",
return_type: "i4&",
parameter_types: ["i4*", "string&"],
});
});
it("reads fat method header size from the full flags-and-size word", () => {
const il = Buffer.from([
0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x22, 0x00,