-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathSetFieldOpCode.cs
More file actions
65 lines (58 loc) · 2.53 KB
/
Copy pathSetFieldOpCode.cs
File metadata and controls
65 lines (58 loc) · 2.53 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
using AsmResolver.DotNet;
using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
using AsmResolver.DotNet.Signatures.Types;
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables.Rows;
namespace UseEveryOpCode.OpCodes;
using static CilOpCodes;
public class SetFieldOpCode : IOpCode
{
private readonly CilOpCode _opCode;
public SetFieldOpCode(CilOpCode opCode)
{
_opCode = opCode;
}
public IList<CilInstruction> CallingInstructions => new List<CilInstruction>();
public MethodDefinition? Generate(TypeDefinition typeDefinition)
{
var name = _opCode.ToString().Replace(".", "_");
var subType = new TypeDefinition(typeDefinition.Namespace, $"{name}Dummy",
TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.NestedPublic,
typeDefinition.Module.CorLibTypeFactory.Object.ToTypeDefOrRef());
var constructor = new MethodDefinition(".ctor",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RuntimeSpecialName,
MethodSignature.CreateInstance(typeDefinition.Module.CorLibTypeFactory.Void));
constructor.CilMethodBody = new CilMethodBody(constructor)
{
Instructions = { { Ret } }
};
var dummyField = new FieldDefinition($"{name}Dummy", FieldAttributes.Public,
new FieldSignature(typeDefinition.Module.CorLibTypeFactory.Int32));
subType.Fields.Add(dummyField);
subType.Methods.Add(constructor);
var dummyMethod = new MethodDefinition($"{name}DummyMethod", MethodAttributes.Public,
MethodSignature.CreateInstance(typeDefinition.Module.CorLibTypeFactory.Void));
dummyMethod.CilMethodBody = new CilMethodBody(dummyMethod)
{
Instructions = { { Ret } }
};
subType.Methods.Add(dummyMethod);
typeDefinition.NestedTypes.Add(subType);
subType.ImportWith(new ReferenceImporter(typeDefinition.Module));
var method = new MethodDefinition(name, MethodAttributes.Public | MethodAttributes.Static,
new MethodSignature(CallingConventionAttributes.Default, typeDefinition.Module!.CorLibTypeFactory.Void,
Enumerable.Empty<TypeSignature>()));
method.CilMethodBody = new CilMethodBody(method)
{
Instructions =
{
{ Newobj, constructor },
{ Ldc_I4_0 },
{ _opCode, dummyField },
{ Ret }
}
};
return method;
}
}