Сейчас на форуме: asfa, _MBK_, Adler (+6 невидимых)

 eXeL@B —› Вопросы новичков —› Реверс-инжиниринг LINQ-выражения
Посл.ответ Сообщение

Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 02 января 2012 16:54 · Поправил: Soloton_
· Личное сообщение · #1

Есть продукт (написан на .NET), который на днях был закрыт автором.
--> Link <--
Исходники автор вряд-ли даст, потому было решено разобрать по косточкам.
DNiD показал, что исполняемый файл защищен DotNet Reactor v4.X, часть dll -- SmartAssembly v 5.X.
Со снятием защиты успешно справилась de4dot. Великолепная программа!
После снятия защиты исходные коды были получены при помощи .NET Reflector и, там где он не справился помогла ILSpy.

Смотрю на один из классов (Имя Class1 было присвоено de4dot после деобфускации). Вот что выдал ILSpy:

Code:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Runtime.CompilerServices;
  5. using System.Text;
  6. namespace ns1
  7. {
  8.    [CompilerGenerated]
  9.    internal sealed class Class1<<<>h__TransparentIdentifier0>j__TPar, <polyRef>j__TPar>
  10.    {
  11.        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  12.        private readonly <<>h__TransparentIdentifier0>j__TPar gparam_0;
  13.        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  14.        private readonly <polyRef>j__TPar gparam_1;
  15.        public <<>h__TransparentIdentifier0>j__TPar <>h__TransparentIdentifier0
  16.        {
  17.            get
  18.            {
  19.                return this.gparam_0;
  20.            }
  21.        }
  22.        public <polyRef>j__TPar polyRef
  23.        {
  24.            get
  25.            {
  26.                return this.gparam_1;
  27.            }
  28.        }
  29.        [DebuggerHidden]
  30.        public Class1(<<>h__TransparentIdentifier0>j__TPar <>h__TransparentIdentifier0, <polyRef>j__TPar polyRef)
  31.        {
  32.            this.gparam_0 = <>h__TransparentIdentifier0;
  33.            this.gparam_1 = polyRef;
  34.        }
  35.        [DebuggerHidden]
  36.        public override string ToString()
  37.        {
  38.            StringBuilder stringBuilder = new StringBuilder();
  39.            stringBuilder.Append("{ <>h__TransparentIdentifier0 = ");
  40.            stringBuilder.Append(this.gparam_0);
  41.            stringBuilder.Append(", polyRef = ");
  42.            stringBuilder.Append(this.gparam_1);
  43.            stringBuilder.Append(" }");
  44.            return stringBuilder.ToString();
  45.        }
  46.        [DebuggerHidden]
  47.        public override bool Equals(object value)
  48.        {
  49.            Class1<<<>h__TransparentIdentifier0>j__TPar, <polyRef>j__TPar> @class = value as Class1<<<>h__TransparentIdentifier0>j__TPar, <polyRef>j__TPar>;
  50.            return @class != null && EqualityComparer<<<>h__TransparentIdentifier0>j__TPar>.Default.Equals(this.gparam_0, @class.gparam_0) && EqualityComparer<<polyRef>j__TPar>.Default.Equals(this.gparam_1, @class.gparam_1);
  51.        }
  52.        [DebuggerHidden]
  53.        public override int GetHashCode()
  54.        {
  55.            int num = -144043021;
  56.            num = -1521134295 * num + EqualityComparer<<<>h__TransparentIdentifier0>j__TPar>.Default.GetHashCode(this.gparam_0);
  57.            return -1521134295 * num + EqualityComparer<<polyRef>j__TPar>.Default.GetHashCode(this.gparam_1);
  58.        }
  59.    }
  60. }


Пример использования Class1:
Code:
  1. // ns4.Class13
  2. [CompilerGenerated]
  3. private int method_19(Class1<Class2<Class15, float[]>, uint> <>h__TransparentIdentifier1)
  4. {
  5.    return this.Query.MarkAreaInCircle(<>h__TransparentIdentifier1.polyRef, <>h__TransparentIdentifier1.<>h__TransparentIdentifier0.loc, <>h__TransparentIdentifier1.<>h__TransparentIdentifier0.danger.Radius, this.Filter, 4);
  6. }


Гугление даёт намёк на то, что так компилятор преобразует LINQ. Но я не настолько силён в .NET, чтобы разобраться, потому прошу помощи здесь.



Ранг: 512.7 (!), 360thx
Активность: 0.270.03
Статус: Модератор

Создано: 02 января 2012 20:49
· Личное сообщение · #2

Soloton_
в чем сенс рыться в коде, который сгенерил компилятор?
(см на аттрибут [CompilerGenerated])

думаетцо вам более интересен код руки автора а не бездушной железяки



Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 02 января 2012 21:16
· Личное сообщение · #3

sendersu
Нужен код, который потом можно будет скомпилировать. Уж не Вы ли автор?

Проблема в том, что сконструированный компилятором класс не пропускает VS2010. А мне подобные выверты (см. выше) тоже не понять. И вообще там таких классов ещё штуки 3.
Прошу помочь перевести в корректный C# или направить на мысль.



Ранг: 512.7 (!), 360thx
Активность: 0.270.03
Статус: Модератор

Создано: 02 января 2012 21:30
· Личное сообщение · #4

как минимум надо коректную версию дот нета использовать - дженерики все же
2) что именно не нравиться компилятору, мож логи какие .... не телепат все же



Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 02 января 2012 21:52 · Поправил: Soloton_
· Личное сообщение · #5

Везде .NET 4.0

Компилятору не нравится строка 9 в первом листинге:
Code:
  1.    internal sealed class Class1<<<>h__TransparentIdentifier0>j__TPar, <polyRef>j__TPar>


Ругается так:
Недопустимая лексема "<<" в объявлении класса, структуры или интерфейса C:\Users\...\Documents\Reflector\Disassembler\WowManager\ns1\Class1.cs

Ну и дальше куча ошибок, которые тянет за собой эта.



Ранг: 590.4 (!), 408thx
Активность: 0.360.18
Статус: Модератор

Создано: 03 января 2012 02:20
· Личное сообщение · #6

Soloton_
Конечно, недопустимая. Если чо, то << это сдвиг влево. Пробелы не забываем ставить.

-----
старый пень




Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 03 января 2012 10:36
· Личное сообщение · #7

r_e
Код сформирован не мной, а ILSpy. Это декомпилятор .NET сборок, такой же как и .NET Reflector. Замечу, что последний выдаёт точно такой же код.
В объявлении класса сдвиг влево не ставят.

Неужели никто не наступал на такие грабли при RE .NET сборок?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 03 января 2012 11:04
· Личное сообщение · #8

На такие грабли-это какие? Намекнули же в посте выше уже, что << -это сдвиг, и надо эти 2 символа разделять пробелом, чтоб компиль это не парсил как сдвиг.



Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 03 января 2012 23:27
· Личное сообщение · #9

Строку поменял. Стало так
Code:
  1. internal sealed class Class1< < < > h__TransparentIdentifier0>j__TPar, <polyRef>j__TPar>

Теперь такая ошибка.
Недопустимая лексема "<" в объявлении класса, структуры или интерфейса C:\Users\...\Documents\Reflector\Disassembler\WowManager\ns1\Class1.cs

Про грабли.
--> По ссылке <-- пример того как компилятор преобразует анонимный тип и как потом Reflector дизасемблирует. На самом деле текущая версия Reflector запросто справляется с задачкой из примера и дизасемблирует как надо, однако на момент написания статьи по ссылке всё было именно так как написано.

Склоняюсь к мысли, что причиной проблемы, с которой столкнулся, является именно обфускация и после -- деобфускация, когда имя класса поменялось на Class1. А до обфускации имя было такое, что декомпилятор парсил IL корректно определяя анонимные классы и/или треклятый TransparentIdentifier.



Ранг: 512.7 (!), 360thx
Активность: 0.270.03
Статус: Модератор

Создано: 04 января 2012 14:12 · Поправил: sendersu
· Личное сообщение · #10

Soloton_
взял код по вашей линке

var anonymousType = new { Name = "chibacity", Age = 21 };

сделал екзе, глянул на ето через рефлектор (7.5) -а у вас какой рефлектор кстати?

вот что он показал -

var anonymousType = new {
Name = "chibacity",
Age = 0x15
};

тоесть 1 в 1 без всех етих дженериков как по линке

вопрос - а как смотрится ваш код до деобфускации?
если правильно -значит виноват именно деобфускатор, если нет - декомпилятор
P.S. похоже в рефлекторе еще есть пару блох при работе с дженериками.
может закинете свое файло? а то както неудобно в воздухе руками махать

P.S. в идеале етого класса сгенеренного компилеров вообще не надо, надо лишь понять что было изначально.




Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 04 января 2012 15:28
· Личное сообщение · #11

Еще можно поиграться с языками, для которых код строится. Например для Delphi рефлектор генерит полный бред, для VB генерит нормальный код, но местами тоже бред, это даже хуже, не сразу видно ошибки, в C# я не шарю, но по аналогии возможно, что тоже есть косяки.

-----
Yann Tiersen best and do not fuck




Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 04 января 2012 17:49
· Личное сообщение · #12

sendersu
Последняя ссылка -- просто пример. Причем прошлогодний. Повторю, что этот пример сейчас Reflector (как 7.3, так и 7.5) декомпилирует в корректный код, т.е. 1:1.

Файло по ссылке из первого поста, не деобфусцированное, т.е. как есть. Первый листинг из WowManager.dll.
На всякий случай приведу всё-же недеобфусцированый код этого класса:
Code:
  1. using ;
  2. using ;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Runtime.CompilerServices;
  7. using System.Text;
  8. namespace 
  9. {
  10.    [CompilerGenerated]
  11.    internal sealed class <<<>h__TransparentIdentifier0>j__TPar, <polyRef>j__TPar>
  12.    {
  13.        [NonSerialized]
  14.        internal static global::. ;
  15.        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  16.        private readonly <<>h__TransparentIdentifier0>j__TPar ;
  17.        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
  18.        private readonly <polyRef>j__TPar ;
  19.        public <<>h__TransparentIdentifier0>j__TPar <>h__TransparentIdentifier0
  20.        {
  21.            get
  22.            {
  23.                return this.;
  24.            }
  25.        }
  26.        public <polyRef>j__TPar polyRef
  27.        {
  28.            get
  29.            {
  30.                return this.;
  31.            }
  32.        }
  33.        [DebuggerHidden]
  34.        public (<<>h__TransparentIdentifier0>j__TPar <>h__TransparentIdentifier0, <polyRef>j__TPar polyRef)
  35.        {
  36.            this.= <>h__TransparentIdentifier0;
  37.            this.= polyRef;
  38.        }
  39.        [DebuggerHidden]
  40.        public override string ToString()
  41.        {
  42.            StringBuilder stringBuilder = new StringBuilder();
  43.            stringBuilder.Append(global::..(31405));
  44.            stringBuilder.Append(this.);
  45.            stringBuilder.Append(global::..(31450));
  46.            stringBuilder.Append(this.);
  47.            stringBuilder.Append(global::..(31353));
  48.            return stringBuilder.ToString();
  49.        }
  50.        [DebuggerHidden]
  51.        public override bool Equals(object value)
  52.        {
  53.            .<<<>h__TransparentIdentifier0>j__TPar, <polyRef>j__TPar>  = value as .<<<>h__TransparentIdentifier0>j__TPar, <polyRef>j__TPar>;
  54.            return  != null && EqualityComparer<<<>h__TransparentIdentifier0>j__TPar>.Default.Equals(this., .) && EqualityComparer<<polyRef>j__TPar>.Default.Equals(this., .);
  55.        }
  56.        [DebuggerHidden]
  57.        public override int GetHashCode()
  58.        {
  59.            int num = -144043021;
  60.            num = -1521134295 * num + EqualityComparer<<<>h__TransparentIdentifier0>j__TPar>.Default.GetHashCode(this.);
  61.            return -1521134295 * num + EqualityComparer<<polyRef>j__TPar>.Default.GetHashCode(this.);
  62.        }
  63.        static ()
  64.        {
  65.            // Note: this type is marked as 'beforefieldinit'.
  66.            global::..(typeof(.<, >));
  67.        }
  68.    }
  69. }


> P.S. в идеале етого класса сгенеренного компилеров вообще не надо, надо лишь понять что было изначально.
Да. Вот и не получается понять.

PE_Kill
Пробую всем, что есть в арсенале Reflector, не помогает, ибо приблизительно всё то же самое.



Ранг: 512.7 (!), 360thx
Активность: 0.270.03
Статус: Модератор

Создано: 05 января 2012 00:37
· Личное сообщение · #13

Soloton_ пишет:
Файло по ссылке из первого поста, не деобфусцированное, т.е. как есть. Первый листинг из WowManager.dll.

как про меня - по линке идут внутри уже деобдуцированные сборки (вижу названия nsX + ClassX)
перепроверьте пож-та



Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 05 января 2012 00:47
· Личное сообщение · #14

sendersu
Прошу прощения.
--> Link <--



Ранг: 512.7 (!), 360thx
Активность: 0.270.03
Статус: Модератор

Создано: 06 января 2012 17:17
· Личное сообщение · #15

Soloton_

внутри WowManager.dll обнаружено SmartAssembly 5.5

после деобфускации того класса в САЕ оказалось следующее:

[CompilerGenerated]
internal sealed class c0000ed<T0, T1>
{
// Fields
[NonSerialized]
internal static delegate02 f000020;
private readonly T0 f000179;
private readonly T1 f00017a;
........
все норм. компилируется (етот отдельный класс)

вывод напрашивается такой - дедот и сае деобфуцируют дженерики по разному

| Сообщение посчитали полезным: Soloton_

Ранг: 1.4 (гость)
Активность: 0=0
Статус: Участник

Создано: 06 января 2012 22:01
· Личное сообщение · #16

sendersu
Точно!
Премного благодарен. На старых версиях исследуемого софта не получалось использовать САЕ (выдавал кучу ошибок и не желал деобфусцировать), потому об этом инструменте не думал вообще. А зря, как выясняется.

Ещё раз спасибо. Тему закрываю.


 eXeL@B —› Вопросы новичков —› Реверс-инжиниринг LINQ-выражения
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати