Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.97.248] |
|
Сообщ.
#1
,
|
|
|
Добрый день.
Подскажите как правильно сделать переход из соглашения __fastcall в соглашение cdecl? Я хукаю __fastcall функцию и вызываю в хуке свою функцию cdecl. Делал так: резервировал буфер в целевом процессе, и в этот буфер записывал состояние регистров MOV [ADR], ESI MOV [ADR], EAX MOV [ADR], ECX MOV [ADR], EDX MOV [ADR], EBX тут вызываю свою функцию cdecl и восстанавливаю регистры MOV ESI, [ADR] MOV EAX, [ADR] MOV ECX, [ADR] MOV EDX, [ADR] MOV EBX, [ADR] потом делаю PUSH ESI, чтоб вернуть адрес возврата в стек Все это шаманство работало до поры, но сейчас спотыкается. Уверен, что все это жуткий костыль, и вобще так делать нельзя. Подскажите пожалуйста как правильно сделать переходник? Чтобы после работы моей функции стек и регистры вернулись "как и было"? |
Сообщ.
#2
,
|
|
|
Никакого стандарта на соглашение __fastcall не существует. Каждый компилятор может трактовать его по-разному. Посему нет и определённых правил преобразования __fastcall во что-то иное, кроме тех, которые известны самому компилятору, выполнившему этот самый __fastcall. Если это соглашение описано в документации на компилятор, то следует изучить материал, и написать соответствующий переходник будет несложно. Но проще просто изначально отказаться от __fastcall. В противном случае шаманства, работающего на честном слове, не избежать.
|
Сообщ.
#3
,
|
|
|
Спасибо разъяснил про фасткал. А если я например знаю, как передаются параметры? Есть же какие то общие принципы таких переходников, и в них врят-ли делали так же как я (сохраняли регистры в буфер)?
С вызовом моей функции на cdecl проблем нет - cdecl берет все из стека, загнать нужное туда не проблема. Проблема после ее работы восстановить регистры и стек в изначальное состояние... |
Сообщ.
#4
,
|
|
|
Цитата Rzonex @ Ну а я-то об чём. Не зная соглашений целевого компилятора, ты ничего надёжного не сделаешь. Вот с чего ты взял, что сохранения регистров достаточно? Или даже, что сохранение регистров ничего не поломает? А вдруг компилятор через какой-нибудь EBP передаёт и возвращает ссылку на какие-то дополнительные стековые фреймы? Проблема после ее работы восстановить регистры и стек в изначальное состояние... |
Сообщ.
#5
,
|
|
|
Жаль Можно еще вопрос - как из стека верхнюю запись удалить? Можно засрать регистр сделав pop ESI например. А можно не засирая регистры ее удалить совсем?
|
Сообщ.
#6
,
|
|
|
Цитата Rzonex @ как из стека верхнюю запись удалить? add esp,4 ; удалить один аргумент sub esp,4 ; зарезервировать dword в стеке |