Русский / Russian English / Английский

Сейчас на форуме: Vicshann, maddmaks (+3 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS ·

 eXeL@B —› Вопросы новичков —› Простые способы замены кода в dotNet
. 1 . 2 . >>
Посл.ответ Сообщение

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 2 марта 2019 13:09 New!
Цитата · Личное сообщение · #1

Здравствуйте, ув. Профессионалы!
Хочу научиться производить замену кода в приложениях dotNet. Для этого создал на C# очень простое тестовое приложение. При нажатии на кнопку Calculate приложение просто складывает два числа, которые были введены в текстовые поля и результат выводит в третье текстовое поле.

Задача заменить исходную функцию сложения на следующую:
Code:
  1. public static string Read_From_txt()
  2. {
  3.          string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Result.txt");
  4.          string result;
  5.          try
  6.          {
  7.                  FileStream stream = new FileStream(path, FileMode.Open);
  8.                  StreamReader streamReader = new StreamReader(stream, Encoding.GetEncoding("windows-1251"));
  9.                  result = streamReader.ReadLine();
  10.                  streamReader.Close();
  11.          }
  12.          catch
  13.          {
  14.                  result = "";
  15.          }
  16.          return result;
  17. }

Код функции читает первую строку из файла Result.txt и возвращает ее в качестве результата. Также хочу обратить внимание, что код фунции использует библиотеку 'using System.IO;', которая не подключена в исходном приложении

Файлы с тестовым приложением выложил здесь --> Link <--
в архиве 'Calc.exe' - исходное приложение, 'FileRead.dll' - функция для замены, 'Result.txt' - текстовый файл, откуда будет читаться первая строка

По возможности, просьба подробно указывать ЧТО, КАК И С ПОМОЩЬЮ КАКИХ ИНСТРУМЕНТОВ следует делать для замены кода. По Вашим рекомендациям я буду учиться


Ранг: 322.8 (мудрец)
Статус: Участник

Создано: 2 марта 2019 14:42 New!
Цитата · Личное сообщение · #2

Ждём medsft по данному вопросу )

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


Ранг: 582.9 (!)
Статус: Модератор

Создано: 2 марта 2019 18:47 New!
Цитата · Личное сообщение · #3

dnSpy правой кнопкой по методу, редактировани и пишешь новый код на шарпе. Потом компиляция и Сохранить.

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


Ранг: 15.0 (новичок)
Статус: Участник

Создано: 2 марта 2019 22:58 New!
Цитата · Личное сообщение · #4

r_e пишет:
dnSpy правой кнопкой по методу, редактировани и пишешь новый код на шарпе. Потом компиляция и Сохранить.

dnSpy при попытке скомпилировать измененный код выдает много ошибок, сделал скрин: --> Link <--

Ранг: 582.9 (!)
Статус: Модератор

Создано: 2 марта 2019 23:09 New!
Цитата · Личное сообщение · #5

"Учу читать. Дорого." (с) энторнет
Ну там же написано в чем проблема. Или все за тебя предлагаешь сделать?

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 3 марта 2019 10:36 New!
Цитата · Личное сообщение · #6

r_e пишет:
Ну там же написано в чем проблема

Ура-а-а-а!!! Получилось!!!

Первому способу замены кода в приложениях dotNet я научился:
№1. Замена кода с помощью dnSpy

Обучение на этом не закончилось, прошу писать еще способы

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 4 марта 2019 08:48 New!
Цитата · Личное сообщение · #7

DenCoder пишет:
Ждём medsft по данному вопросу )
улыбнуло


rukop84 пишет:
Задача заменить исходную функцию

Решение:
1) Можно целиком переписать приложение
2) При отсутствии обфускации, dictionary, структур - dnspy в руки
3) При невозможности обратной декомпиляции - инжект статик класса (только моим движком))) ногами не пинать с Инди не сравнивать)
4) При невозможности декомпиляции - если размер тела исходного метода позволяет байт патчинг его
но тут проблемы стринг придется подать нетрадиционным способом, иначе без перекомпиляции #US стрима никак... (хотя попробовать мне надо может там в конце место есть)

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


Ранг: 15.0 (новичок)
Статус: Участник

Создано: 4 марта 2019 09:42 New!
Цитата · Личное сообщение · #8

Medsft заинтересовал третий способ - инъекция кода с помощью dll. Если сумею разобраться в нем, то цель создания Тему буду считать достигнутой. Сразу уточнения по этому методу:

1. с Инди не сравнивать
А что такое инди?

2. инжект статик класса
Класс для инъекции должен быть паблик или без разницы?

3. только моим движком
Кроме самого метода для инъекции нужно ли добавлять еще какой-либо код в класс или эту работу сделает уже сам ILSpector?

4. Библиотеки dll для инъекции, которые следует отдавать ILSpector'у могут быть написаны на любом языке программирования (например, на Visual Basic 6)?

5. Правильно ли я понял структуру своих действий для реализации этого метода:
5.1 создать dll для инъекции;
5.2 в IlSpector привязать dll (сделать инъекцию)
5.3 с помощью битпатчинга приложения вызвать функцию из привязанной dll

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 4 марта 2019 10:05 · Поправил: Medsft New!
Цитата · Личное сообщение · #9

rukop84 пишет:
А что такое инди?
- это главная загадка форума
rukop84 пишет:
Класс для инъекции должен быть паблик или без разницы?
public static
rukop84 пишет:
Правильно ли я понял
неправильно, речь идет только о manadged только (пока так)
Делаешь простую dll c одним единстенным public static классом и ilspeсtorom инжектишь его (класс в сборку) -> сохраняешь что получилось -> а далее простым байт патчингом в нужный метод вставляешь его вызов остальное затираешь

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 4 марта 2019 14:00 · Поправил: rukop84 New!
Цитата · Личное сообщение · #10

Мастер Medsft, что-то ILSpector не хочет инжектить dll, сделал скрин --> Link <--


Ранг: 72.3 (постоянный)
Статус: Участник

Создано: 5 марта 2019 05:25 New!
Цитата · Личное сообщение · #11

rukop84

> Хочу научиться производить замену кода в приложениях dotNet.

Это весьма сложный вопрос, пока ты его масштаб не понимаешь.

Что значит замена кода - всякий код вызывается по ссылке, это либо указатель, либо относительное ветвление, зашитое в код(граф). Поэтому что значит изменить код - перехватить какое то событие через указатель или изменить непосредственно сам код ?

А если это виртуальная машина, то кода как такового нет, один и тот же транслятор выполняет эмуляцию.

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 5 марта 2019 08:34 New!
Цитата · Личное сообщение · #12

rukop84 пишет:
что-то ILSpector не хочет инжектить dll
класс целиком инжекти, только не в другой класс, а рядом

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 5 марта 2019 10:57 · Поправил: rukop84 New!
Цитата · Личное сообщение · #13

Medsft пишет:
класс целиком инжекти, только не в другой класс, а рядом

не, все равно ILSpector наотрез инжектить отказывается. Вот скрин --> Link <--

Экспериментировал разными способами (не только как в скрине), результат один и тот же: либо "Not support method to inject", либо "Operation error"

А в самой dll модификаторы доступа у меня правильно объявлены для того, чтобы корректно произошла инъекция этого класса?
Code:
  1.     public static class clsInject
  2.     {
  3.         public static string Read_From_txt()


А в природе, кроме ILSpector'а, существуют ли еще инструменты, позволяющие произвести инъекцию dll в сборку? В интернете довольно много инструментов это умеют делать в запущенный процесс, но не встретил ни одного, чтобы сделать это в сам exe-файл

Добавлено спустя 8 минут
Если надо, файлы для экспериментов с инъекцией выложил здесь --> Link <--

Добавлено спустя 16 минут
Какими еще способами можно решить поставленную задачу по инъекции dll в сборку?

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 5 марта 2019 12:23 · Поправил: Medsft New!
Цитата · Личное сообщение · #14

http://prntscr.com/mtfssl
Семен Семеныч))) тыж со стрингом хочешь заинжектить метод, а этого делать нельзя т.к. добавление стринга меняет стримы, обиграй стринг по другому

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 5 марта 2019 12:53 · Поправил: rukop84 New!
Цитата · Личное сообщение · #15

Medsft, прежде, чем обыгрывать string хочу уяснить для себя следующее:
dll класс с методом типа string вообще нельзя инжектить в сборку что ли?

Или нельзя только в данном случае, так как в сборке отсутствуют методы с типом string?

А если бы у меня функция Calc складывала бы цифры и возвращала бы тип string, тогда можно было бы инжектить данную dll?

Кстати, обыграть тип string в моем случае никак не удастся, так как в текстовом файле содержатся слова, а не цифры. И слова никак не смогут стать типом integer. Другое дело - это переписать функцию калькулятора, чтобы производилось сложение и результат конвертировался в тип string

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 5 марта 2019 13:01 · Поправил: Medsft New!
Цитата · Личное сообщение · #16

rukop84 пишет:
прежде, чем обыгрывать string
еще раз задашь вопрос из школьного курса, туда и пойдешь учиться.

int[] цифроваяжопа = new int[]{126,234,345, 256};
string жопа = string.empty;
for (int i = 0; i< цифроваяжопа.Lenght; i++)
{
жопа +=new char(цифроваяжопа[i]);
}

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


Ранг: 15.0 (новичок)
Статус: Участник

Создано: 5 марта 2019 23:03 · Поправил: rukop84 New!
Цитата · Личное сообщение · #17

Мастер, в общем я запутался...

Привел Ваш код к более читабельному виду:
Code:
  1.             int[] NumArray = new int[] {126, 234, 345, 256};
  2.             string text = "";
  3.  
  4.             for (int i = 0; i < NumArray.Length; i++)
  5.             {
  6.                 text = text + new char(NumArray[i]);
  7.             }

последнюю строку кода text += new char(NumArray[i]) Visual Studio подчеркивает, говорит, что так нельзя делать

следующее, что не сходится - это то, что вышеприведенный алгоритм решает задачу перевода типа integer в тип string, а перед нами стоит прямо противоположная задача. Надо превратить как-то текстовую строку "Hello-World!" в набор цифр целого типа

ну, допустим я как-то решу такую задачу с помощью дополнительного кода в dll:
1) создам массив переменных
2) каждой такой переменной присвою по символу от строки "Hello-World!"
3) затем каждый символ переведу в число целого типа
4) и на выходе получу набор цифр целого типа
!!!Но тогда вопрос: как этот набор цифр обратно я буду превращать в буквы уже в целевом приложении, если по плану у нас следует только пропатчить целевое приложение, а лишний код затереть?!

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 6 марта 2019 09:11 New!
Цитата · Личное сообщение · #18

rukop84 пишет:
Visual Studio подчеркивает
это концепция была, А вот решение https://stackoverflow.com/questions/4648781/how-to-get-character-for-a-given-ascii-value
rukop84 пишет:
каждой такой переменной присвою по символу от строки "Hello-World!
майкрософт за тебя уже давно таблицы сделал
rukop84 пишет:
Но тогда вопрос
да сделай все в своем классе а в исходном методе вызов его

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 6 марта 2019 10:29 New!
Цитата · Личное сообщение · #19

Medsft пишет:
да сделай все в своем классе а в исходном методе вызов его

дак, а если мой класс будет сначала превращать string в integer, а затем integer в string, то на выходе функции все равно получится string и тогда получается, что задача "обыграть string" не выполнена. Правильно я понимаю?

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 6 марта 2019 10:44 New!
Цитата · Личное сообщение · #20

rukop84 ты вообще вьезжаешь в разницу сборка на как файл, и сборка как процесс в памяти, инжект не позволяет добавлять новые стринги в сборку которая сохраняется потом на диск, в пямяти мути потом че хошь

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 6 марта 2019 12:26 · Поправил: rukop84 New!
Цитата · Личное сообщение · #21

Medsft пишет:
ты вообще вьезжаешь

не, не въезжаю, но пытаюсь осмыслить глубокую мысль Мастера:

то есть, получается, что задача сводится к тому, чтобы ни один метод в классе dll не имел тип string. И в то же время нужно сделать так, чтобы он этот тип возвращал во время выполнения программы

Получается, что в своем классе я должен объявить функцию с типом int и при этом функция должна вернуть тип string. Но как такое реализовать!!! Функцию с типом int и возвращаемым типом string даже скомпилировать не удастся

Ранг: 68.4 (постоянный)
Статус: Участник

Создано: 6 марта 2019 22:23 New!
Цитата · Личное сообщение · #22

rukop84
Пойми - ты можешь в своей функе сделать все, вне зависимости что она получает..
Т.Е. передав функе int - ты на return можешь забрать string..

Добавлено спустя 2 минуты
rukop84 пишет:
Функцию с типом int и возвращаемым типом string даже скомпилировать не удастся

Учи МатЧасть..

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


Ранг: 15.0 (новичок)
Статус: Участник

Создано: 7 марта 2019 09:25 · Поправил: rukop84 New!
Цитата · Личное сообщение · #23

sefkrd, тогда подскажите пожалуйста как скомпилировать такой код:
Code:
  1.         private void btnTest_Click(object sender, RoutedEventArgs e)
  2.         {
  3.             string sResult = GetSum();
  4.             MessageBox.Show(sResult);
  5.         }
  6.  
  7.         private int GetSum()
  8.         {
  9.             int x = 3;
  10.             int y = 6;
  11.             int z = x + y;
  12.  
  13.             string text = "Hello-World!";
  14.             return text;
  15.         }

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 7 марта 2019 10:16 New!
Цитата · Личное сообщение · #24

rukop84 я тебе пару ответов выше уже написал как обойти string

Добавлено спустя 1 минуту
private int GetSum()
{
int x = 3;
int y = 6;
int z = x + y;

string text = "Hello-World!";
return text;
}
это вообще хуйня полная

Ранг: 582.9 (!)
Статус: Модератор

Создано: 7 марта 2019 11:30 New!
Цитата · Личное сообщение · #25

Да он просто не догоняет что строки как константы нельзя пихать в метод, но при этом можно чтобы функция оперировала строками.
Можно сделать
Code:
  1. private string getHello() {
  2.   int[] helloAsInts = new int[] { ... };
  3.   string result = string.Empty;
  4.   for (...) { result += ...; }
  5.   return result;
  6. }

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


Ранг: 68.4 (постоянный)
Статус: Участник

Создано: 7 марта 2019 11:53 New!
Цитата · Личное сообщение · #26

rukop84 пишет:
как скомпилировать такой код:

Он не скомпелируется..
private int GetSum() заменить на private string GetSum()
Тогда соберешь..

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 7 марта 2019 11:55 · Поправил: rukop84 New!
Цитата · Личное сообщение · #27

r_e пишет:
Да он просто не догоняет что строки как константы нельзя пихать в метод, но при этом можно чтобы функция оперировала строками

дак, вот она где истина

Добавлено спустя 5 минут
sefkrd пишет:
Он не скомпелируется..
private int GetSum() заменить на private string GetSum()
Тогда соберешь..

это все понятно, просто Medsft дал задание избавиться от стрингов и я понял это так, что нельзя инжектить функции с типом string, но при этом каким-то загадочным образом этот тип должен был вернуться

Добавлено спустя 10 часов 1 минуту
Ну, теперь я точно знаю, что такое "стринги" на сленге мастеров крэкинга.
Это не какие-то там пляжные трусики и даже не функция с типом string, а всего лишь несколько строковых значений в моем коде, которые надо было обыграть с помощью Ascii кода

Подправил немного код своей dll:
Code:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6.  
  7. namespace FileRead
  8. {
  9.     public static class clsInject
  10.     {
  11.         public static string Read_From_txt()
  12.         {
  13.             int[] Nums1 = new int[] { 82, 101, 115, 117, 108, 116, 46, 116, 120, 116 };
  14.             int[] Nums2 = new int[] { 119, 105, 110, 100, 111, 119, 115, 45, 49, 50, 53, 49 };
  15.  
  16.             string text1 = IntsToText(Nums1);
  17.             string text2 = IntsToText(Nums2);
  18.  
  19.             string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, text1);
  20.             string text;
  21.  
  22.             try
  23.             {
  24.                 FileStream file1 = new FileStream(path, FileMode.Open); //создаем файловый поток
  25.                 StreamReader reader = new StreamReader(file1, Encoding.GetEncoding(text2)); //создаем "потоковый читатель" и связываем его с файловым потоком
  26.                 text = reader.ReadLine(); //считываем одну строку
  27.                 reader.Close(); //закрываем поток
  28.             }
  29.             catch
  30.             {
  31.                 text = string.Empty;
  32.             }
  33.             return text;
  34.         }
  35.  
  36.         private static string IntsToText(int[] Arr)
  37.         {
  38.             string text = string.Empty;
  39.             for (int i = 0; i < Arr.Length; i++)
  40.             {
  41.                 text += char.ConvertFromUtf32(Arr[i]);
  42.             }
  43.             return text;
  44.         }
  45.     }
  46. }


Уже завтра буду продолжать эксперименты

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 8 марта 2019 11:02 · Поправил: rukop84 New!
Цитата · Личное сообщение · #28

В общем обыграл строковые значения (стринги), но dll все равно инжектиться не хочет (выдает ошибку). Прикрепил скрин --> Link <--

Обновленную dll и сопутствующие файлы для экспериментов залил сюда: --> Link <--

Жду Ваших советов и рекомендаций

Ранг: 324.7 (мудрец)
Статус: Участник
ILSpector Team

Создано: 11 марта 2019 14:05 New!
Цитата · Личное сообщение · #29

rukop84 пишет:
все равно инжектиться не хочет
залей куда нибудь оба файла, посмотрю

Ранг: 15.0 (новичок)
Статус: Участник

Создано: 11 марта 2019 14:52 New!
Цитата · Личное сообщение · #30

Мастер, все залито (смотрите в предыдущем сообщении)

Добавлено спустя 2 минуты
на всякий случай продублирую еще раз ссылку: --> Link <--
. 1 . 2 . >>
 eXeL@B —› Вопросы новичков —› Простые способы замены кода в dotNet
Эта тема закрыта. Ответы больше не принимаются.

Видеокурс ВЗЛОМ