GTA Builder Форум

GTA Vice City => Программирование => Тема начата: graveman от Ноябрь 26, 2013, 07:19:44 am

Название: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 26, 2013, 07:19:44 am
Всем привет. Как заменить вызов call на nop, чтобы определенная функция не вызывалась?
Как правильно поменять передаваемое в push целочисленное значение аргумента?
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 26, 2013, 11:27:12 am
Цитировать
Как заменить вызов call на nop, чтобы определенная функция не вызывалась?


Приведите конкретный пример, какую бы вы хотели функцию затереть. На данный момент скажу, что обязательно надо затереть сами ее передаваемые параметры и затем саму функцию с адресом. При этом опять вы должны установить память на чтение/запись.

Цитировать
Как правильно поменять передаваемое в push целочисленное значение аргумента?

Это совсем не сложно. Для этого надо знать размер самого параметра, затем задать в VirtualProtect атрибут как чтение записать, записать и готово.

Метод точно такой же как в этих статьях:

Чтение и запись адресов GTA Vice City (http://gtabuilder.ru/chtenie-i-zapis-adresov-gta-vice-city/)
Чтение и запись адресов GTA Vice City часть 2 (http://gtabuilder.ru/chtenie-i-zapis-adresov-gta-vice-city-chast-2/)

Единственно это нужно будет проделать в командах push, обычно которые заталкивают параметры в стек, перед вызовом.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 26, 2013, 12:01:32 pm
Цитировать
Приведите конкретный пример, какую бы вы хотели функцию затереть.
Например, в функции "Render" хочу попробовать затереть вызов функции "sub_5C1710".
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 26, 2013, 12:24:07 pm
Значит поступаем следующим образом. Находим то место, где идет вызов данной процедуры, и затем я выделил то что нам надо будет затереть. Так как параметры не передаются, нам нужно затереть саму команду call и ее адрес:

(http://cs7002.vk.me/c421018/v421018441/9fab/7Ff8awR0rpA.jpg)

Команда NOP - имеет значение опкода 0x90.

Дальше все просто:

Код: C++
  1. case DLL_PROCESS_ATTACH:
  2.                
  3.                 DWORD _old;
  4.                 VirtualProtect((LPVOID)0x04A6594, 5,  PAGE_READWRITE, &_old);
  5.  
  6.                 *(BYTE*)0x04A6594 = 0x90;  //E8
  7.                 *(BYTE*)0x04A6595 = 0x90;  //77
  8.                 *(BYTE*)0x04A6596 = 0x90;  //B1
  9.                 *(BYTE*)0x04A6597 = 0x90;  //11
  10.                 *(BYTE*)0x04A6598 = 0x90;  //00
  11.  
  12.                 VirtualProtect((LPVOID)0x04A6594, 5, _old, &_old);

Прописываем это в dll, т.е в ASI плагине. Уроки были про DLL_PROCESS_ATTACH. Этот код выполниться тогда когда dll будет загружена. Судя по коду, сперва мы меняем по нужному нам адресу, атрибут памяти на чтение/запись. Затем уже не посредственно вписываем наши NOP-ы, по нужным нам адресам. Это те самые адреса, что я выделил на картинки. После возвращаем данный участок памяти в исходное положение.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 26, 2013, 12:34:43 pm
Отлично, спасибо. Надо будет попробовать. А я задавал смещения *(patch+1), *(patch+2)...
Цитировать
Уроки были про DLL_PROCESS_ATTACH
Да, с написанием asi-плагина я освоился, благодаря твоим статьям. Я просто переименовываю расширение релизной библиотеки с "dll" на "asi" и копирую этот asi-плагин в папку "mss".

Sector, а как заменить "mov eax, dword_xxx" на "mov eax, int", то бишь засылку переменной засылкой явно заданным целым числом? То же 5 байт поменять, как приведено выше - первый на код операции, второй на число, а остальные на ноль?
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 26, 2013, 12:49:22 pm
Цитировать
Отлично, спасибо. Надо будет попробовать. А я задавал смещения *(patch+1), *(patch+2)...
Можно и так.  Так как значения одинаковые 0x90, то можно вообще распределить таким образом

Код: C++
  1. memset((PVOID)0x04A6594, 0x90, 5);

Это будет тогда выглядеть более компактно, в одну строчку.

Цитировать
Да, с написанием asi-плагина я освоился, благодаря твоим статьям. Я просто переименовываю расширение релизной библиотеки с "dll" на "asi" и копирую этот asi-плагин в папку "mss".

Да по сути одна и та же DLL, переименовать расширение это проще простого. На данный момент я приболел да еще и дел полно, как только выздоровлю и будет свободное время, так напишу продолжение пошаговых статей.

Цитировать
"mov eax, dword_xxx" на "mov eax, int"
Типы на уровне ассемблерных команд, особой роли не играют , за исключением float. Если говорить о разных размерах, то обычными правками не обойтись. Для этого уже нужно переписывать саму функцию и затем заменять, путем как инжектом. Приводите конкретный пример, что и где именно вы хотите заменить с адресами. Мне так лучше будет видно.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 26, 2013, 01:10:06 pm
Да, приведу код, если не удастся решить, просто исходник дома.
Цитировать
Если говорить о разных размерах, то обычными правками не обойтись. Для этого уже нужно переписывать саму функцию и затем заменять, путем как инжектом.
Я вот про инжект не понял, зачем записывается "function - (address + 5)", а не просто "function" и что означает "5"?
Цитировать
На данный момент я приболел
Выздоравливай.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 26, 2013, 01:44:06 pm
Цитировать
Я вот про инжект не понял, зачем записывается "function - (address + 5)", а не просто "function" и что означает "5"?
Об, этом я расскажу как освобожусь, более в деталях и подробно.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 27, 2013, 07:14:53 am
Пытался выводить в лог значения некоторых переменных через SetTimer(...Update) в теле Update(). Похоже, что идет вызов из определенного места кода, так как переменные должны быть явно больше нуля (при выводе большое отрицательное число), так как из использования их в качестве аргумента в функции RW ясно, что это счетчики вершин.
Вопрос - нельзя ли как-то применить gta_log или вызвать свой Log в теле экзешника?
Я пробовал обрывать цикл в одной из функций обнулением счетчика в for{} - в игре при этом становились полупрозрачными некоторые стены и детали автомобилей (лонжероны, капот).


Такой вопрос. Правильно ли я начал менять код. Есть проверка переменной на нуль через cmp. Я смотрю там 7 байт. В то время как test eax, eax занимает всего 2 байта. При том эта переменная потом все равно заносится в eax. Что если заменить cmp на засылку переменной в eax с последующим test eax, eax,  jz      short loc_5C2935 переписать на адрес сразу за test eax, eax. Останется 5 свободных байт, достаточных для вызова call или jump near. Вообщем, картинка для пояснения:
(http://forum.gtabuilder.ru/index.php?action=dlattach;topic=114.0;attach=17;image)
Можно ли на освободившиеся 5 байт прописать call для своей функции из dll?
Короче дома попробую.


Sector, я кстати нашел ответ на вопрос:
Я вот про инжект не понял, зачем записывается "function - (address + 5)", а не просто "function" и что означает "5"?


Источник: http://habrahabr.ru/post/90377/ (http://habrahabr.ru/post/90377/)
Цитата из него:
Цитировать
Итак, теперь мы разобрались, как происходит вызов функции и готовы к ее перехвату. Осталась одна деталь – а как же собственно сделать перехват?

Для этого, все что нам нужно – это поставить в начало функции инструкцию jmp с адресом, который будет указывать на начало нашей функции. Однако, не все так просто. Дело в том, что инструкция jmp, которая бы принимала абсолютный адрес нашей функции, размером 5 байт просто не существует. Единственный jump, который работает с абсолютными адресами – это jump far, который занимает 6 байт.

Поэтому, мы будем использовать jump near, который принимает относительный адрес (то есть разность между адресом точки назначения и следующей за jump near инструкцией). По факту, для вычисления параметра операции jump near, надо из адреса точки назначения вычесть адрес исходной точки и прибавить 5 байт (именно столько эта инструкция занимает).


PS: можно статью по замене функций как бы дополнить этим.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 27, 2013, 12:26:17 pm
По поводу инжекст функции, я думаю лучше отдельно потом статью написать. Потому-что многим и так тяжело все читать и понимать.
gta_log, есть такой плагин, я его прикрепил сюда, вместе с исходником. Автор его Listener.


Цитировать
Такой вопрос. Правильно ли я начал менять код.

Скриншота не вижу.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: xanser от Ноябрь 27, 2013, 12:42:28 pm
Ууу, зря я сюда заглянул, это из другой сказки  :-\
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 27, 2013, 02:20:32 pm
Вот скрин, походу у меня в кэше. Кстати как картинки постить?
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 27, 2013, 02:51:01 pm
Цитировать
Можно ли на освободившиеся 5 байт прописать call для своей функции из dll?

Можно, но для этого нужно еще учитывать, используются параметры или нет. Тогда просто call - 1 байт, 4 байта относительный адрес, не примой, но функции. Вообще скажу прямо, что такими методами не рекомендую заниматься, такими правками. Они не эффективны и в дальнейшем не подлежат для хороших модификаций. Рекомендую только переписывать все функции в сорцы, и делать потом инжекты. Об этом я тоже хочу в будущем статьи написать, методики переписывания...  Объясню почему, одними ассемблерными правками, не обойтись, второе логика всего будет утеряна, когда все лучше разрабатывать на C++. В результате если работать таким методом, то к хорошему в будущем это не приведет. Надо просто брать переписывать функции, изначально можно объявлять прототипы по адресам.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 27, 2013, 03:06:53 pm
Я это делаю для изучения переменных и не найденных еще функций. Не для мода. Та переменная засветилась во многих функциях рендера и связана с количеством каких-то вершин.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 27, 2013, 03:25:03 pm
Цитировать
Я это делаю для изучения переменных и не найденных еще функций. Не для мода. Та переменная засветилась во многих функциях рендера и связана с количеством каких-то вершин.

Эту глобальную не проинициализированную переменную можно найти во всех местах где она используется, нажав на нее кнопку "X". Изначально надо цепляться за то, откуда идет первая ей запись. Вроде бы равна к нулю. Возможно это какое-то состояние, пока что и сам точно не знаю. В рендере еще не копался, начал с самого простого.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 27, 2013, 03:40:55 pm
У меня подозрения, что она используется за слежением наполненности какого-то глобального массива вершин. То есть на определенном этапе рендера счетчик обнуляется и в массив набиваются вершины каких-то объектов, они рендерятся и счетчик снова обнуляется. То, что я выводил его в лог по таймеру, похоже происходило вне этих функций. Не знаю, в документации к RW упоминается о каком-то кэшировании геометрии. Походу это типа кэша. Сегодня попробую вывести логи.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 27, 2013, 03:52:12 pm
Код: ASM
  1. .text:005BD7AC 0E0 81 3D 74 5F 9B 00 FC 01 00 00                 cmp     ds:dword_9B5F74, 1FCh
  2. .text:005BD7B6 0E0 7C 57                                         jl      short loc_5BD80F

Вот тут идет процесс сравнения этой переменной с не маленьким значением.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 27, 2013, 04:16:41 pm
Код: ASM
  1. .text:005BD7AC 0E0 81 3D 74 5F 9B 00 FC 01 00 00                 cmp     ds:dword_9B5F74, 1FCh
  2. .text:005BD7B6 0E0 7C 57                                         jl      short loc_5BD80F

Вот тут идет процесс сравнения этой переменной с не маленьким значением.
508 - это немного, походу общий буфер для каких-то мелких объектов. На выходных надо разобраться с "immediate mode" RW, чтобы лучше понять.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 28, 2013, 07:10:12 am
Не получилось, игра вылетает. Похоже, что нужно взять всю функцию, поместить в свой плагин, джампить на ее копию в плагине и уже в копии в плагине что-то посылать на лог.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 28, 2013, 11:16:40 am
Цитировать
Не получилось, игра вылетает.
С какой ошибкой вылетела? Там кажись адрес должен быть показан в MessageBox.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 28, 2013, 12:01:21 pm
С какой ошибкой вылетела? Там кажись адрес должен быть показан в MessageBox.
Я разные варианты пробовал, разные адреса были, в том числе и адреса возврата. Вообщем, я считаю этот метод слишком трудоемким. Проще всю функцию перенести в плагин, а в экзешнике поставить джамп на нее, а в коде плагина уже править ее как надо.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 28, 2013, 12:12:25 pm
Цитировать
Вообщем, я считаю этот метод слишком трудоемким.
Я ранее говорил, что этот метод не эффективный. Обычно этот метод используют, для не больших правок и то в нашем случае, оно не нужно. В дальнейшем к моддингу не подлежит, все это дело. Дело в том что когда есть переписанные функции, мы быстро можем в них что-то добавить свое, изменить да что угодно сделать на C++. При этом не упереться на ассемблерные инструкции, а разрабатывать плагины на языке высокого уровня. Кода естественно будет не мало, вот по этому все нужно переписывать так, что-бы оно было в соответствующих модулях.  Это 10-тками статьями не рассказать, нужно гораздо больше написать и также я планировал сделать как практические статьи, где какой-то мод на плагине мы будем делать своими руками, пошагово.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Ноябрь 29, 2013, 07:35:02 am
Начал было sub_5C1710 переписывать на c++. Компилятор ругался, пока я не исправил DWORD sub_5C1710 = на void* sub_5C1710 =, а лучше выполнять приведение адреса прямо в месте вызова, а то компилятор ругается матом постоянно.
Короче облом в том, что там есть структура CCamera и не известно смещения ее полей, а в коде функции идет многоуровневое обращение к полю сначала CCamera, потом к полям ее полей  - до 4-х уровней.
Еще не понятно, что такое UNDEF(число). Так что тоже не простой метод.
Короче надо копаться сразу во всем коде, искать взаимосвязи, намеки на тип, искать среди аргументоы уже исследованных функций.
Кстати в Code:Blocks есть такая возможность в подсветке синтаксиса. Когда выделяешь переменную в одном месте, она выделяется во всем коде - удобно. Не знаю, есть ли это в MSVC.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Ноябрь 29, 2013, 11:08:15 pm
Код: ASM
  1. .text:005C1710         sub_5C1710      proc near  

Это статичный метод камеры.

Кстати:

Код: ASM
  1. .text:005C1750                                   loc_5C1750:                             ; CODE XREF: sub_5C1710+2Dj
  2. .text:005C1750 0C0 B9 98 46 7E 00                                mov     ecx, offset _camera.__parent.matrix.__parent.top
  3. .text:005C1755 0C0 D9 41 08                                      fld     dword ptr [ecx+8]
  4. .text:005C1758 0C0 D8 1D 78 CD 69 00                             fcomp   flt_69CD78
  5. .text:005C175E 0C0 DF E0                                         fnstsw  ax
  6. .text:005C1760 0C0 F6 C4 45                                      test    ah, 45h
  7. .text:005C1763 0C0 0F 85 82 00 00 00                             jnz     loc_5C17EB
  8. .text:005C1769 0C0 D9 41 04                                      fld     dword ptr [ecx+4]

Исправь вот эти вещи:

fld     dword ptr [ecx+8]
dword ptr [ecx+4]


Выделив их и нажав, на клавишу "T" найди структуру RwV3d. Должно получится так:

Код: ASM
  1. .text:005C1750 0C0 B9 98 46 7E 00                                mov     ecx, offset _camera.__parent.matrix.__parent.top
  2. .text:005C1755 0C0 D9 41 08                                      fld     [ecx+RwV3d.z]
  3. .text:005C1758 0C0 D8 1D 78 CD 69 00                             fcomp   flt_69CD78
  4. .text:005C175E 0C0 DF E0                                         fnstsw  ax
  5. .text:005C1760 0C0 F6 C4 45                                      test    ah, 45h
  6. .text:005C1763 0C0 0F 85 82 00 00 00                             jnz     loc_5C17EB
  7. .text:005C1769 0C0 D9 41 04                                      fld     [ecx+RwV3d.y]

С камерой все просто, это статично выделенный объект, он находиться по этому адресу:

Код: ASM
  1. .bss:007E4688 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+    _camera         CCamera <?>  

Достаточно переписать структуры камеры в один .h файл, и сделать подхват переменной (http://gtabuilder.ru/podxvat-peremennyx-v-gta-vice-city/)

в данном случае так:

Код: C++
  1. auto pCamera  = (CCamera*)0x07E4688;

ну и в принципе все, она наша, мы можем потом делать? что угодно с ее полями, через переменную pCamera.

Структуру камеры можно взять в этом посте (http://forum.gtabuilder.ru/index.php?topic=117.msg299#msg299) в vcCamera.h

Но на самом деле CCamera - это класс, но пока можно использовать как обычную структуру. Просто нужно переписывать ее методы, для того что-бы получился полноценный класс камеры.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Декабрь 02, 2013, 07:11:15 am
Очень полезная информация, Sector.
Начал разбирать эту функцию. Это
RwV3d field_8B8;
RwV3d field_8C4;
RwV3d field_8D0;
RwV3d field_8DC;
возможно нормали плоскостей пирамиды видимости камеры.

Sector, не знаешь, как найти смещение метода класса в классе?
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Декабрь 02, 2013, 11:59:58 am
Цитировать
Sector, не знаешь, как найти смещение метода класса в классе?

Обычные методы, не какой роли к полям не играют за исключением виртуальных методов. Обычные методы, могут сами по себе лежать где угодно в коде. Работает также как функция, только перед вызовом помещается указатель на объект класса в ecx.

Цитировать
Начал разбирать эту функцию. Это
RwV3d field_8B8;
RwV3d field_8C4;
RwV3d field_8D0;
RwV3d field_8DC;

Еще одно пояснение. Это не функции, это обычные структурные поля.

Код: C++
  1. struct RwV3d{
  2.   float x;
  3.   float y;
  4.   float z;
  5. };


Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: xanser от Апрель 01, 2014, 04:48:01 pm
А у меня вопрос по замене ассемблерного кода ассемблерным. Хочу заменить первый кусок кода на второй. Сначала я делал в лоб, писал команды подряд, после них все занупил. Программа вылетела на нулевом адресе 0x000000, не знаю что это такое, я так понял мой код не понравился, хотя я сто раз его проверил и уверен в правильности. Тогда я сделал то же самое, но распределил команды по строкам так, чтобы сохранить количество байтов в строках, т.е. меняю 5 байтов на 5, 2 на 2 и т.д., между ними занупил и все заработало. Вопрос - нужно ли сохранять эту построчную структуру байтов или можно писать любые команды подряд и они правильно поймутся?

Оригинал:

Код: ASM
  1. .text:00601A52 50                                            push    eax             ; phkResult
  2. .text:00601A53 68 19 00 02 00                                push    20019h          ; samDesired
  3. .text:00601A58 6A 00                                         push    0               ; ulOptions
  4. .text:00601A5A 68 88 63 6D 00                                push    offset SubKey   ; "Software\\Microsoft\\Windows\\CurrentVersi"...
  5. .text:00601A5F 68 01 00 00 80                                push    80000001h       ; hKey
  6. .text:00601A64 FF 15 C0 23 6F 00                             call    ds:RegOpenKeyExA
  7. .text:00601A6A 85 C0                                         test    eax, eax
  8. .text:00601A6C 0F 85 AC 00 00 00                             jnz     loc_601B1E
  9. .text:00601A72 C7 84 24 BC 00 00 00 00 01 00 00              mov     [esp+0E4h+cbData], 100h
  10. .text:00601A7D 8D 84 24 BC 00 00 00                          lea     eax, [esp+0E4h+cbData]
  11. .text:00601A84 50                                            push    eax             ; lpcbData
  12. .text:00601A85 8D 84 24 BC 00 00 00                          lea     eax, [esp+0E8h+Type]
  13. .text:00601A8C 68 F8 3E 78 00                                push    offset userdir_path ; lpData
  14. .text:00601A91 50                                            push    eax             ; lpType
  15. ........

Работающий код:

Код: ASM
  1. .text:00601A52 90                                            nop
  2. .text:00601A53 68 50 BD 68 00                                push    _programPath
  3. .text:00601A58 90 90                                         nop
  4. .text:00601A5A 68 F8 3E 78 00                                push    userdir_path
  5. .text:00601A5F E8 FC 0A 04 00                                call    _strcpy
  6. .text:00601A64 90 90 90 90 90 90                             nop
  7. .text:00601A6A 90 90                                         nop
  8. .text:00601A6C 90 90 90 90 90 90                             nop
  9. .text:00601A72 90 90 90 90 90 90 90 90 90 90 90              nop
  10. .text:00601A7D 90 90 90 90 90 90 90                          nop
  11. .text:00601A84 59                                            pop    ecx
  12. .text:00601A85 90 90 90 90 90 90 90                          nop
  13. .text:00601A8С 90 90 90 90 90                                nop
  14. .text:00601A91 59                                            pop    ecx
  15. ........

Неработающий код:

Код: ASM
  1. .text:00601A52 68 50 BD 68 00                                push    _programPath
  2. .text:00601A57 68 F8 3E 78 00                                push    userdir_path
  3. .text:00601A5С E8 FF 0A 04 00                                call    _strcpy
  4. .text:00601A61 59                                            pop    ecx
  5. .text:00601A62 59                                            pop    ecx
  6. .text:00601A63 90 90 90 90 90 90 90 90 90 90 90+             nop
  7. ........
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Апрель 01, 2014, 04:50:45 pm
Pop - тоже надо нопить, ведь это выталкивание их стека... Конечно будут вылеты... Есть ли код целиком этого самого участка?
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: xanser от Апрель 01, 2014, 05:16:17 pm
Код я собрал для примера, все это у меня в cpp подменивается побайтово. Глубину стэка я проверил, в примере идет блок считывания из реестра, т.е. в начале и в конце блока глубина стека например 0E4 (я просто не дописал и там много push в начале). Точно также в моей замене, в начале и в конце 0E4, внутри идет два push и два pop, чтобы восстановить уровень стека. Мой блок работает, но внутри команды с разрывами nop, как только я пытаюсь написать без разрывов, а nop до конца блока, кажется что код понимается уже по другому. Так вот про строки байтов - это принциально сохранить при замене длину команд в байтах или она не важна и ошибка была в чем-то другом?
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Апрель 01, 2014, 07:29:13 pm
Если говорить про строки, то туда в push передается адрес строки, т.е указатель 4 байта.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: xanser от Апрель 01, 2014, 07:42:00 pm
Я имею ввиду строки команд, которые создает IDA PRO. Я смогу заменить например 1-байтовую команду 5-байтовой? Cоответственно вторая команда у меня начнется уже с 6-го байта, а не со 2-го как в оригинале, остальное подкорректирую нупами. Или нужно менять только один к одному 1 на 1, 5 на 5 и никакой сдвиг не допустим внутри законченного блока?

Вобщем мне нужно понять, эти варианты замены идентичны или один из них ошибочный?

Замена команд такой же длины

Код: ASM
  1.                                байты
  2.          |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
  3. оригинал |___|_________|___|_________|_________|_|_____|___|_____|
  4. замена   |x x|_________|x x|_________|x x x x x|_|x x x|___|x x x|   // работает

Последовательная замена

Код: ASM
  1.                                байты
  2.          |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
  3. оригинал |___|_________|___|_________|_________|_|_____|___|_____|
  4. замена   |_________|_________|_|___|x x x x x x x x x x x x x x x|   // не работает
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Апрель 01, 2014, 09:39:15 pm
Один вопрос. Это все дело статичного патчинга или опять через плагин?
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: xanser от Апрель 02, 2014, 05:14:47 am
Через плагин, а есть разница? Так-то я пробовал оба способа, результат одинаковый
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Апрель 02, 2014, 06:26:53 am
Тогда все просто:

выделаем строку выше

Код: C++
  1. char str[] = "тут пишем что угодно";

а далее получаем адрес str, и записываем заместо того.

.text:00601A57 68 F8 3E 78 00      push    userdir_path
F8 3E 78 00 - эти байты, просто патчим на свой адрес строки та что в памяти.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: xanser от Апрель 02, 2014, 07:38:43 am
Мы о разных вещах говорим, менять значения, менять адреса это действительно просто. Как правильно писать команды ассемблера в очищенном блоке. Туда можно писать произвольный асм-код подряд? потом сделать jmp куда нужно? У меня сложилось впечатление, что подряд нельзя, а только в определенные места с сохранением длины команд, несмотря на то, что весь блок уже очищен.

Наверное я не могу правильно объяснить, что мне нужно
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: DK от Апрель 05, 2014, 11:41:44 pm
xanser, это делается асм-вставкой.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: Sektor от Апрель 06, 2014, 12:37:59 am
Цитировать
это делается асм-вставкой.
Ты имеешь введу ему, голый код юзать? Т.е __declspec(naked) ?
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: DK от Апрель 06, 2014, 12:52:02 am
Зависит от того, что надо менять и где.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: graveman от Июнь 09, 2014, 07:52:36 am
Пытался поменять инструкцию ассемблера и даже просто заменить функцию. Обычно был вылет. Но несколько удивляло, что когда изменение прокатывало, измененная функция (в ней был вывод сообщения в лог) не вызывалась. Стал проверять значения ячеек, которые заменяю. Обнаружил, что вместо тех значений, которые должны быть судя по базе Alien'а, там смещенные на 0x20. То есть, чтобы поменять в exe значение ячейки, нужно к адресу в базе Alien прибавить 0x20. Может это уже известно, не знаю. Я только вчера обнаружил.
Вопрос еще такой. Инструкция call принимает разность между адресом функции, которая вызывается и адресом следующей за call инструкцией (где об этом почитать)?

Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: xanser от Июнь 09, 2014, 12:37:21 pm
Пытался поменять инструкцию ассемблера и даже просто заменить функцию. Обычно был вылет...
У меня пока все инструкции получилось поменять, но при условии, что длина байт в строке остается такой же (я этот вопрос так и не прояснил, иначе у меня вылет)

Цитировать
Стал проверять значения ячеек, которые заменяю. Обнаружил, что вместо тех значений, которые должны быть судя по базе Alien'а, там смещенные на 0x20

Очень похоже на версию exe 1.1, там многое сдвинуто на 0x20, база для 1.0.

Цитировать
Инструкция call принимает разность между адресом функции, которая вызывается и адресом следующей за call инструкцией...
Именно так, если функция впереди, но она может быть и до, тогда там обратное смещение.
Название: Re: Вопросы по замене ассемблерных инструкций в asi.
Отправлено: DK от Июнь 11, 2014, 08:24:51 pm
xanser, можно заменять участки любой длины.