Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.RU > Assembler > __fastcall -> cdecl |
Автор: Rzonex 28.04.19, 11:53 |
Добрый день. Подскажите как правильно сделать переход из соглашения __fastcall в соглашение cdecl? Я хукаю __fastcall функцию и вызываю в хуке свою функцию cdecl. Делал так: резервировал буфер в целевом процессе, и в этот буфер записывал состояние регистров <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> 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, чтоб вернуть адрес возврата в стек Все это шаманство работало до поры, но сейчас спотыкается. Уверен, что все это жуткий костыль, и вобще так делать нельзя. Подскажите пожалуйста как правильно сделать переходник? Чтобы после работы моей функции стек и регистры вернулись "как и было"? |
Автор: Qraizer 28.04.19, 17:03 |
Никакого стандарта на соглашение __fastcall не существует. Каждый компилятор может трактовать его по-разному. Посему нет и определённых правил преобразования __fastcall во что-то иное, кроме тех, которые известны самому компилятору, выполнившему этот самый __fastcall. Если это соглашение описано в документации на компилятор, то следует изучить материал, и написать соответствующий переходник будет несложно. Но проще просто изначально отказаться от __fastcall. В противном случае шаманства, работающего на честном слове, не избежать. |
Автор: Rzonex 28.04.19, 18:54 |
Спасибо разъяснил про фасткал. А если я например знаю, как передаются параметры? Есть же какие то общие принципы таких переходников, и в них врят-ли делали так же как я (сохраняли регистры в буфер)? С вызовом моей функции на cdecl проблем нет - cdecl берет все из стека, загнать нужное туда не проблема. Проблема после ее работы восстановить регистры и стек в изначальное состояние... |
Автор: Qraizer 28.04.19, 19:27 |
Ну а я-то об чём. Не зная соглашений целевого компилятора, ты ничего надёжного не сделаешь. Вот с чего ты взял, что сохранения регистров достаточно? Или даже, что сохранение регистров ничего не поломает? А вдруг компилятор через какой-нибудь EBP передаёт и возвращает ссылку на какие-то дополнительные стековые фреймы? |
Автор: Rzonex 28.04.19, 21:14 |
Жаль Можно еще вопрос - как из стека верхнюю запись удалить? Можно засрать регистр сделав pop ESI например. А можно не засирая регистры ее удалить совсем? |
Автор: core-i7 29.04.19, 02:38 |
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> add esp,4 ; удалить один аргумент sub esp,4 ; зарезервировать dword в стеке |