-
-
Save unarist/65faf28aa58aa5d34ef4aa234a4be6a4 to your computer and use it in GitHub Desktop.
Mono.Cecilで配列を埋め込む
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 参考: http://lifeinhex.com/how-to-inject-byte-array-using-dnlib/ | |
var asm = AssemblyDefinition.ReadAssembly("target.exe"); | |
var data = File.ReadAllBytes("in.dat"); | |
// 適当な型に、(ここではコンパイラと同じ名前を使うので競合に注意) | |
var cls = new TypeDefinition("", "<PrivateImplementationDetails>", Mono.Cecil.TypeAttributes.Sealed, asm.MainModule.TypeSystem.Object); | |
asm.MainModule.Types.Add(cls); | |
// a. 目的のサイズの構造体(メンバはなくてよい) | |
var sized = new TypeDefinition("", $"__StaticArrayInitTypeSize={data.Length}", | |
Mono.Cecil.TypeAttributes.NestedPrivate | Mono.Cecil.TypeAttributes.Sealed | Mono.Cecil.TypeAttributes.ExplicitLayout, | |
asm.MainModule.Import(typeof(ValueType))); | |
sized.PackingSize = 1; | |
sized.ClassSize = data.Length; | |
cls.NestedTypes.Add(sized); | |
// b. 上記構造体のフィールドに初期値としてデータを埋め込む | |
var field = new FieldDefinition("適当な名前", | |
Mono.Cecil.FieldAttributes.Static | Mono.Cecil.FieldAttributes.InitOnly | Mono.Cecil.FieldAttributes.HasFieldRVA, | |
sized); | |
field.InitialValue = asm2; | |
cls.Fields.Add(field); | |
// そして空の配列を生成し、RuntimeHelpers.InitializeArrayでデータをコピーしてくる | |
var initarr = asm.MainModule.Import(typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("InitializeArray")); | |
var write = asm.MainModule.Import(typeof(File).GetMethod("WriteAllBytes")); | |
// ※とりあえずEmitで書いたけど新規作成するなり挿入するなり | |
var il = asm.MainModule.EntryPoint.Body.GetILProcessor(); | |
il.Emit(OpCodes.Ldstr, @"out.dat"); | |
il.Emit(OpCodes.Ldc_I4, data.Length); | |
il.Emit(OpCodes.Newarr, asm.MainModule.TypeSystem.Byte); | |
il.Emit(OpCodes.Dup); | |
il.Emit(OpCodes.Ldtoken, field); | |
il.Emit(OpCodes.Call, initarr); | |
il.Emit(OpCodes.Call, write); | |
il.Emit(OpCodes.Ret); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment