c# как получить массив для ldtoken?

263
24 августа 2017, 18:25

Есть исходный код, например 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 я могу вытрусить с него данные, но может можно как-то получить обьект "массив" сразу, а не кусками?

Answer 1

Решение было спрятано в самом 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, '}');
READ ALSO
Преследование врага

Преследование врага

В моих планах - кликнуть пкм на врага, чтобы персонаж подбежал к врагу и, когда игрок к нему уже будет подбегать, чтобы бежал не к его прошлому...

171
Как передать параметр windows service?

Как передать параметр windows service?

Есть написанная службаИз программы запускаю эту службу

282
REST. Один GET запрос для разных ролей

REST. Один GET запрос для разных ролей

Есть три роли: admin, area(оператор района) и school(оператор школы)

247