Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions test/agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ Il2Cpp.perform(() => {
});

test("Il2Cpp.Image::classCount", () => {
assert(Il2Cpp.domain.assembly("GameAssembly").image.classes.length).is(33);
assert(Il2Cpp.domain.assembly("GameAssembly").image.classCount).is(33);
assert(Il2Cpp.domain.assembly("GameAssembly").image.classes.length).is(36);
assert(Il2Cpp.domain.assembly("GameAssembly").image.classCount).is(36);
});

test("Il2Cpp.Class::image", () => {
Expand Down Expand Up @@ -619,4 +619,35 @@ Il2Cpp.perform(() => {
"Cannot create nullable value type out of a reference type 'System.Object'"
);
});
// --- Struct return hook tests (Interceptor.replace via .implementation) ---

test("Hooked method returning medium struct with passthrough result", () => {
const SRT = Il2Cpp.domain.assembly("GameAssembly").image.class("StructReturnTest");
const method = SRT.method<Il2Cpp.ValueType>("GetMediumResult");

method.implementation = function (...args) {
return method.invoke(...args);
};

const result = method.invoke(3, 77);
assert(result.field<number>("Code").value).is(3);
assert(result.field<number>("Value").value).is(77);
SRT.method("GetMediumResult").revert();
});

test("Hooked method returning large struct (sret) with passthrough result", () => {
const SRT = Il2Cpp.domain.assembly("GameAssembly").image.class("StructReturnTest");
const method = SRT.method<Il2Cpp.ValueType>("GetLargeResult");
const msg = Il2Cpp.string("passthrough");
const entity = Il2Cpp.corlib.class("System.Object").new();

method.implementation = function (...args) {
return method.invoke(...args);
};

const result = method.invoke(5, msg, entity);
assert(result.field<number>("Reason").value).is(5);
assert(result.field<Il2Cpp.String>("Message").value.content).is("passthrough");
SRT.method("GetLargeResult").revert();
});
}).then(() => send({ action: "stop" }));
32 changes: 32 additions & 0 deletions test/src/GameAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,35 @@ static int CoalesceInt(int? a, int? b)
return a ?? b ?? 777;
}
}

public struct MediumStructResult
{
public int Code;
public int Value;
}

public struct LargeStructResult
{
public int Reason;
public string Message;
public object Entity;
}

public static class StructReturnTest
{
public static MediumStructResult GetMediumResult(int code, int value)
{
return new MediumStructResult { Code = code, Value = value };
}

public static LargeStructResult GetLargeResult(int code, string message, object entity)
{
return new LargeStructResult
{
Reason = code,
Message = message,
Entity = entity
};
}

}