Есть исходный код, например new int[]{123,234,345,456}, как получить это значение из il-кода?
11 ldc.i4.s 19
13 newarr System.Int32
18 dup
19 ldtoken __StaticArrayInitTypeSize=76 CE36A67CA5F79C82610678BDC9AFDDE06635EE7C
1e call Void InitializeArray(System.Array, System.RuntimeFieldHandle)
Токен ldtoken имеет тип 4 - поле, но получаемый "странный" обьект содержит информацию про исходный обьект, но не получается её нормально достать.
Набросаю пример, как я получаю данные
MethodBase mi = t.Module.ResolveMethod(token);
int ip = 0x19;
byte[] cod = mi.GetMethodBody().GetILAsByteArray();
object q = t.Module.ResolveField( BitConverter.ToInt32(cod, ip - 4)).GetValue(null);
// получили обьект токена
GCHandle gc = GCHandle.Alloc(q);
IntPtr ptr =GCHandle.ToIntPtr(gc);
ptr = Marshal.ReadIntPtr(ptr);
Type tt = t.Module.ResolveType(BitConverter.ToInt32(cod,ip-10));
//тип обьекта берём из токена адрес 14h, при newarr Int32
ptr = new IntPtr(ptr.ToInt32() + 4); // смещаем на 4 байта (для x86)
object item = Marshal.PtrToStructure(ptr, tt);
/*Первый элемент структуры*/
t - это класс, за которым закреплён метод с токеном token. Но можно и по имени. q - это уже нужный "обьект" равный 123, из памяти через GC и Marshal я могу вытрусить с него данные, но может можно как-то получить обьект "массив" сразу, а не кусками?
Решение было спрятано в самом InitializeArray.
MethodBase mi = t.Module.ResolveMethod(token);
int ip = 0x19;
byte[] cod = mi.GetMethodBody().GetILAsByteArray();
Type tt =t.Module.ResolveType(BitConverter.ToInt32(cod,ip-10));
int.TryParse(q.ToString().Split('=')[1], out i);
Array q= Array.CreateInstance(tt, i /Marshal.SizeOf(tt));
System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(q,t.Module.ResolveField(BitConverter.ToInt32(cod, ip - 4)).FieldHandle);
string s = null;
foreach (object item26 in item25) {
s = (s==null)?"":s+",";
s = s + item26.ToString();
}
s = string.Format("new {0}[]{1}{2}{3}", tt.Name, '{', s, '}');
Продвижение своими сайтами как стратегия роста и независимости