🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
Помогите, плз, совладать с Turbo C++ (получить адрес метки)
Пишу на C++ программу, которая переводит микропроцессор (МП) из реального режима (real mode, R-mode) в защищённый (protected mode, P-mode).
Необходимо сформировать адрес возврата - адрес команды, которая получит управление после сброса МП.
имеется код вроде такого:
Код:
unsigned int ret_offset = 0; // Смещение точки возврата в реальный режим
int main() {
// нужно получить адрес возврата:
ret_offset = FP_OFF( &prot_exit ); // не работает. компилятор ругается, что получить адрес метки prot_exit невозможно
// вторая попытка получить адрес возврата
asm {
mov ret_offset, offset prot_exit // компилятор ругается: неизвестный идентификатор prot_exit
lea ret_offset, prot_exit // то же самое: неизвестный идентификатор prot_exit
}
< переход в защищённый режим >
prot_exit: // метка - наша точка возврата
< Действия, которые выполняются после перехода из защищённого
режима обратно в реальный - восстановление сегментных
регистров и т.д. >
return 0;
}
Короче говоря, после сброса МП, начинает выполняться та команда, адрес которой записан в памяти по адресу 40:67h. Мне нужно, чтобы по этому адресу находился адрес первой команды, расположенной после метки prot_exit, но я никак не могу получить её адрес.
В Turbo Pascal проблема решалась следующим образом:
Код:
label
prot_exit; // объявление метки
var
ret_offset: Word; // Смещение точки возврата
begin
{ получение адреса первой команды, которая идёт за меткой prot_exit }
{ компилятор прекрасно понимает идентификатор prot_exit внутри ассемблерной вставки }
asm
mov ret_offset, offset prot_exit
end;
< переход в защищённый режим >
prot_exit: // метка - наша точка возврата
< Действия, которые выполняются после перехода
из защищённого режима обратно в реальный - восстановление
сегментных регистров и т.д. >
end.
Не знаю даже, что и делать, откуда узнать адрес точки возврата.
В GCC неофициально есть оператор - &&ИДЕНТИФИКАТОР_МЕТКИ, который позволяет получить адрес, но Turbo C++, увы, такого не умеет.
Можно, конечно, написать новую функцию, перенести в неё весь код по восстановлению регистров и т.д., а затем указать её адрес в качестве адреса возврата... Но куда вернётся управление после завершения этой функции? Ведь всё равно понадобится получить адрес возврата .
Думал, что можно при помощи ассемблерной вставки получить содержимое регистра IP и занести его значение в переменную ret_offset, но компилятор ругается - "неизвестный идентификатор - IP" (видимо, таким образом Turbo C++ запрещает программисту привязывать свой код к значению IP).
Подскажите, пожалуйста, как можно узнать адрес какой-либо команды, расположенной в определённой части функции Main.
Буду признателен за любую помощь по данному вопросу.
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
Я не специалист по данному вопросу, но интернеты говорят, что вся беда в том, что Borland'ский компилятор не умеет делать ссылку на метку, которая позже по коду.
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
Проверял - Turbo C++ не может получить адрес метки даже объявленой ранее .
Ну а как бы можно было бы провернуть этот фокус без меток? В смысле, чтобы управление по выходе из защищённого режима вернулось в функцию Main? А то пока что на ум приходит только один вариант - написать основной модуль на ассемблере, все сложные функции - на С, и скомпилить их вместе. Но хотелось бы по возможности этого избежать.
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
unsigned int ret_offset = 0; // Смещение точки возврата в реальный режим
int main() {
goto start;
goto prot_exit;
start:
// нужно получить адрес возврата:
ret_offset = FP_OFF( (unsigned int) main + 2 ); // адрес "goto prot_exit;"
< переход в защищённый режим >
prot_exit: // метка - наша точка возврата
< Действия, которые выполняются после перехода из защищённого
режима обратно в реальный - восстановление сегментных
регистров и т.д. >
return 0;
}
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
unsigned int ret_offset = 0; // Смещение точки возврата в реальный режим
int main() {
goto start;
goto prot_exit;
start:
// нужно получить адрес возврата:
ret_offset = FP_OFF( [COLOR="Red"][B](unsigned int) main[/B][/COLOR] + 2 ); // адрес "goto prot_exit;"
< переход в защищённый режим >
prot_exit: // метка - наша точка возврата
< Действия, которые выполняются после перехода из защищённого
режима обратно в реальный - восстановление сегментных
регистров и т.д. >
return 0;
}
Э-э-э... Думаешь выделенное красным - хорошая идея?
Вообще у ТС-а неправильная концепция. Он хочешь симитировать возврат из подпрограммы для банального безусловного перехода. Такой финт ушами конечно существует - но нахуа окромя шеллкода и эксплойта на переполнение стека?
Вместо извращений - просто нужна грамотная архитектура программы.
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
1) первый вариант - оформить переход в защищенный режим как функцию, из тела функции прочитать адрес возврата на вершине стека и скорректировать стек так чтобы сымитировать возврат из функции по сути его не делая. В итоге имеем адрес возврата и продолжаем делать свои дела внутри функции...
2) второй вариант - перед адресом возврата делаем ASM вставку в стиле
Код:
asm {
dw 0C0FEh
}
// тут код адрес которого мы ищем
Берем указатель на main и ищем по байтам нужную сигнатюру, инкрементим указатель на длину сигнатюры и получаем адрес возврата.
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
1 - Подобными вопросами я не занимался. Но есть подозрения что рантайм будет не сильно в удовольствии если вдруг внутри него процессор перейдет в защищенный режим, хотя может в далекие времена доса это было и нормуль.
2 - По поводу проблемы - считай секцию кода, найди в ней мейн, в мейне поищи точку выхода (например можно использовать функцию маркер, которая будет вызываться только раз в точке выхода, нифига не делать (главное шоб аптимизатор ее тока не прихлопнул) дальше в коде мэйна ищещ переход на эту функцию и устанавливаешь по ней код возврата, ну или на инструкцию сразу за ней.
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
1) первый вариант - оформить переход в защищенный режим как функцию, из тела функции прочитать адрес возврата на вершине стека и скорректировать стек так чтобы сымитировать возврат из функции по сути его не делая. В итоге имеем адрес возврата и продолжаем делать свои дела внутри функции...
Первый вариант гениален! А я вот до него не додумался! Действительно, переход в защищённый режим можно оформить в виде функции (назовём её, скажем, init_prot), в самом начале которой можно прочитать из стека адрес возврата в main, занести его в 40:67h, и со спокойной душой переводить МП в защищённый режим. При сбросе МП выполнение программы перейдёт к следующей команде после вызова функции init_prot.
Очень элегантное решение, спасибо огромное .
Можно, конечно, и маркер оставить в main, а потом отдельной функцией его найти и получить смещение следующей команды, но первый вариант значительно проще и изящнее
Спасибо всем огромнейшее за помощь! Впереди ещё много работы - организачия перехода в защищённый режим, установка вентилей прерываний и исключений, а застопорился на получении адреса возврата, и никуда не мог сдвинуться с места.
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
Я так понимаю, ты изобретаешь машину времени, которая наконец позволит перенестись тебе из прошлого в настоящее и забыть о всех этих глупостях, которыми ты занимаешься. Верно?
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
Я так понимаю, ты изобретаешь машину времени, которая наконец позволит перенестись тебе из прошлого в настоящее и забыть о всех этих глупостях, которыми ты занимаешься. Верно?
🟢 06:39 Відбій тривоги в м. Харків та Харківська територіальна громада.Слідкуйте за подальшими повідомленнями.#м_Харків_та_Харківська_територіальна_громада
Если ему действительно интересно - то пусть для начала пошарится например на васм.ру. Там есть неплохие переводы "для чайников" про реальный/защищенный режимы, в том числе и с примерами как надо делать.