Сейчас на форуме: asfa, bartolomeo (+7 невидимых) |
![]() |
eXeL@B —› Вопросы новичков —› Как вызывать функции по адресу? |
Посл.ответ | Сообщение |
|
Создано: 07 июня 2012 16:15 · Поправил: Dim77 · Личное сообщение · #1 Существует две задачи. 1. Нужно добавить дополнительную строку инициализации данных в код, приведенный ниже. В этом коде в асме из той функции, куда нужно добавить строку вызываются другие функции. Учитывая, что у функций в декомпилированном ехе нет имен только адреса, то есть ли способ, как написать вызов функции по адресу в С++, который был бы эквивалентен call <address> в асме. Зачем это нужно - код гораздо понятнее и удобнее для последующих модификаций в С++ чем если писать дополнения в асме. Т.е. нужно добавить строку типа: Code:
2. В функции ниже есть ссылки на переменные - глобальные (захардкодированные) и переменные класса, которые инициализируются runtime. Глобальные переменные я заменил их значениями: т.е. вместо Code:
Code:
Следующий шаг - что делать с переменными класса, под которые выделена память по адресу 8372C0 и т.д. Идея такая - заменить адреса на произвольные (подходящие по смыслу) имена и заменить все функции, которые эти данные используют, прописав вместо unk_8372C0 - aLraceId_human, например. Т.к. это переменные класса this в этом примере, то сработает ли такой подход и возможно ли таким способом будет добавить переменную в этот класс? Оригинальный код асма: Code:
Код, сгенеренный HRay (можно и самому, но так удобнее для начала): Code:
Мой код переделанной функции (в процессе, еще не решил, что делать с *(_DWORD *)this = &off_6E7234; - не смотрел еще что по адресу 6E7234 находится и sub_57ED2E(this, a3, Dir, (char *)aLrace_dbf); еще не изучал): Code:
![]() |
|
Создано: 07 июня 2012 16:45 · Поправил: reversecode · Личное сообщение · #2 |
|
Создано: 07 июня 2012 23:08 · Личное сообщение · #3 reversecode пишет: this всегда ходит первым параметром Хмм, в случае с sub_57EDA6 видно, что он второй. По комментам к аргументам в асме это то же видно. Code:
Другое дело, что первый параметр - это адрес, по которому переменная будет записана, так что формально this первый. Посмотрю еще, может это не ссылка на объект класса, но очень на то похоже. reversecode пишет: и четко формулируй вопросы, а то в рассуждениях теряется мысль 1. Какой эквивалент в С++ вызову функции по адресу: call 57EDA6? Имени функции нет, только адрес 57EDA6. Вместо sub_57EDA6 что в С++ писать? 2. Сработает ли переименование адресов переменных (int)&unk_8372C0 в поименованные переменные типа aLraceId_human, если такая замена будет произведена во всех функциях, которые использовали адреса (int)&unk_8372C0? 3. Можно ли расширять класс, добавляя ему переменную при помощи строки: Code:
Где aLraceId_green - новая переменная. ЗЫ По идее, должно сработать, ибо функция sub_57EDA6 выделяет под эту переменную память и записывает туда ее значение. Но я не уверен, как в асме происходит инициализация класса, и достаточно ли того, что я выше написал, чтобы вставить туда дополнительную переменную. ![]() |
|
Создано: 07 июня 2012 23:49 · Поправил: Vamit · Личное сообщение · #4 Вместо sub_57EDA6 что в С++ писать? Что за странный вопрос - реверсом что-ли не занимался? Если не можешь придумать имя функции по смыслу её действия, то так и пиши - sub_57EDA6(ля..., ля..., ля...), по крайней мере будет соответствовать Иде - не заблудишься, а переименовать в любое время можно, только делай это одновременно в отреверсенном коде и в Иде. sub_57EDA6(aLraceId_green, this, aL_green, aLrace_dbf); а вот это уже почти бред, так никто не пишет, причем учти, что компиляторы VisualStudio не ниже 2008 this могуть передать в любую функцию как любым аргументом, так и любым регистром, поэтому, если распознал, что это действительно this, то делай функцию членом класса, а не тыкай this в аргументы. Но по вашей логике - рано вам ещё заниматься реверсом... ----- Everything is relative... ![]() |
|
Создано: 08 июня 2012 00:06 · Поправил: reversecode · Личное сообщение · #5 Dim77 пишет: Хмм, в случае с sub_57EDA6 видно, что он второй. По комментам к аргументам в асме это то же видно. значит это не this, либо ты нетак его разобрал this в MSVC ходит прямо через ecx минуя стек бывают конечно исключения, но они исключительные большинство же прог скомпилены стандартно, this-ecx углубись вообщем во все дерево функций которые идет вниз после перых функций что ты привел Code:
vtbl класса там ![]() |
|
Создано: 08 июня 2012 01:21 · Личное сообщение · #6 ----- 127.0.0.1, sweet 127.0.0.1 ![]() |
|
Создано: 08 июня 2012 01:32 · Поправил: Dim77 · Личное сообщение · #7 Vamit пишет: Если не можешь придумать имя функции по смыслу её действия, то так и пиши - sub_57EDA6(ля..., ля..., ля...) Мне кажется вы не поняли. Я мог бы ее назвать как мне нравится или переименовать, если бы я ее решил переписать в своей длл. Но по такой логике я должен буду переписать все дерево функций, которые вызываются из той функции, которую я действительно хочу изменить. Т.е. попробую еще раз: я изменяю функцию sub_57EB99. Ее я либо так оставлю, либо переименую. Тут все понятно. Из функции sub_57EB99 происходит вызов sub_57EDA6. sub_57EDA6 я переписывать не хочу. Хочу оставить ее такой, какая она есть в уже скомпиленном ехе. О sub_57EDA6 мне известен ее статический адрес в ехе, который естесственно: 0057EDA6 Вопрос: Как мне по этому адресу вызвать функцию в С++? sub_57EDA6 как мы все понимаем не прокатит, т.к. такой функции нет, если я ее не определю сам. Можно ли обратиться к функции только по ее адресу? ЗЫ можно было бы, конечно, в своей длл прописать функцию sub_57EDA6 ничего там не меняя, просто взять и вставить туда асм из ехе с адреса 57EDA6. Тогда вызов sub_57EDA6 замечательно бы сработал. Но таким образом моя длл превратится в копию ехе с большей частью асма скопированного из ехе в длл. Вопрос собственно был в том, чтобы такого не делать, по возможности. reversecode пишет: большинство же прог скомпилены стандартно, this-ecx углубись вообщем во все дерево функций которые идет вниз после перых функций что ты привел Да, посмотрю и отпишусь. Спасибо. ![]() |
|
Создано: 08 июня 2012 05:56 · Поправил: TOM_RUS · Личное сообщение · #8 Dim77 пишет: Вопрос: Как мне по этому адресу вызвать функцию в С++? sub_57EDA6 как мы все понимаем не прокатит, т.к. такой функции нет, если я ее не определю сам. Можно ли обратиться к функции только по ее адресу? Про function pointers слышали? Помоему это то что Вы ищите... http://paste2.org/p/2048284 ![]() |
|
Создано: 08 июня 2012 13:27 · Личное сообщение · #9 |
|
Создано: 08 июня 2012 14:03 · Поправил: reversecode · Личное сообщение · #10 |
|
Создано: 09 июня 2012 01:23 · Личное сообщение · #11 |
|
Создано: 10 июня 2012 16:50 · Поправил: Dim77 · Личное сообщение · #12 reversecode пишет: большинство же прог скомпилены стандартно, this-ecx В ecx - адрес, по этому адресу Code:
Code:
Т.е., если принять, что это vtbl, то таким образом он и передается функции sub_57EDA6, что в общем-то логично. Как, кстати, прописать в С передачу параметра через ecx? Или нужно вызывающую функцию поменять, чтобы можно было вызываемую функцию задекларировать как thiscall c последующей передачей this как первого параметра? По типу: Code:
![]() |
|
Создано: 12 июня 2012 19:25 · Поправил: Hexxx · Личное сообщение · #13 Dim77 пишет: Как, кстати, прописать в С передачу параметра через ecx? thiscall - это псевдо конвенция о которой знает только IDA. По-хорошему нужно класс объявить с виртуальным методом и перегрузить. Ну или __fastcall юзать если это MSVC. Сишный фасткол - это будет ecx, edx, стек. Так что придется поддельный аргумент в edx запихивать. ----- Реверсивная инженерия - написание кода идентичного натуральному ![]() |
|
Создано: 13 июня 2012 16:21 · Личное сообщение · #14 Hexxx пишет: По-хорошему нужно класс объявить с виртуальным методом и перегрузить. Т.е. нужно переписать существующий класс. Было бы, конечно, здорово, хотя и не тривиально, учитывая, что в реверсинге я такого еще не делал... Hexxx пишет: Сишный фасткол - это будет ecx, edx, стек Тут понятно. Попробую. ![]() |
|
Создано: 27 июня 2012 01:14 · Поправил: Dim77 · Личное сообщение · #15 Hexxx пишет: Ну или __fastcall юзать если это MSVC. Сишный фасткол - это будет ecx, edx, стек. Короче говоря, написал, используя fastcall. Почти работает, но почти как известно не считается. Ниже кусок кода до вызова первой функции. В эту функцию VtblPtr_proc (0057ED2E) аргументы передаются такими, какими они должны быть, только стек отличается от оригинального. Внутри этой функции все идет нормально до тех пор пока не вызывается функция, которая использует первый аргумент. На этом месте по адресу первого аргумента со смещением записывается какая-то ерунда вместо того, чтобы собственно использовать сам адрес. Подозрения три - 1. я что-то накосячил с первым аргументом 0057ED2E 2. Порушился стек каким-то образом 3. Тип функции 0057ED2E должен быть другим (в Иде она stdcall) Code:
Это по идее должно было заменой коду: Code:
![]() |
|
Создано: 27 июня 2012 01:30 · Личное сообщение · #16 |
|
Создано: 10 июля 2012 00:30 · Поправил: Dim77 · Личное сообщение · #17 CTPaHHuk пишет: пользуйся вкладкой Править а не плоди посты) Хотелось отделить предыдущие изыскания от так сказать результатов долгого последующего труда... =) В общем, дальнейшие прогоны с разными вариантами функции показывают, что здесь: *(DWORD *)Lrace_vtbl = off_6E7234; записывается какая-то хрень. Т.е. в базовой функции вроде бы это указатель на нужный объект, а в вызываемой по адресу Lrace_vtbl записывается левое значение. Откуда он там берется - неясно (пока что). Был бы благодарен за подсказку как подправить С++ код, чтобы указатель Lrace_vtbl нормально работал. Код функции выше. Удалось реализовать функцию при помощи нового класса. В решении ниже vtbl записывается в thisptr->vtbl, что очевидно не то же самое, что *(DWORD *) Lrace_vtbl = off_6E7234; в решении с fastcall. Плюс еще пришлось привести thiscall к stdcall. Осталась одна деталь. Последняя функция: sub_57ECE9(thisptr) является thiscall и выпадает по исключению. Решение было найдено. Функция успешно реверсирована. Тему закрываю. ![]() |
![]() |
eXeL@B —› Вопросы новичков —› Как вызывать функции по адресу? |
Эта тема закрыта. Ответы больше не принимаются. |