Сейчас на форуме: tyns777, zombi-vadim (+3 невидимых) |
![]() |
eXeL@B —› Программирование —› SSE эмулятор |
Посл.ответ | Сообщение |
|
Создано: 17 марта 2008 11:42 · Поправил: cppasm · Личное сообщение · #1 Привет. Никто не видел в природе SSE эмулятора? А то тут Adobe устроил засаду, Adobe Bridge хочет SSE для работы. Притом не то что хочет, а даже не проверяет ничего, а так как у меня CPU SSE не поддерживает - он просто валится. В отладчике я посмотрел - конечно оптимизация супер, без SSE ну просто никак. 95% SSE кода это: movss xmm0,[mem1]
Ну вот собственно я и подумал, что если сэмулировать SSE, производительность будет приемлемая, тем более что Photoshop работает без проблем. Собственно почему тема в программировании? Ну я больше чем уверен что нет такого эмулятора, прийдётся писать :/ И есть пару вопросов: 1. Есть ли в адресном пространстве процесса ниже 2Gb адреса куда он не лезет? Т.е. ImageBase обычно 400000h, а что находится ниже? Просто надо где-то хранить для каждого процесса XMM регистры, и адресное пространство - самое подходящее место. Тогда не надо отслеживать переключение задач и отлавливать завершение процесса для освобождения памяти занимаемой виртуальными XMM регистрами. Вопрос есть ли какая-нибудь функция MemoryManager чтобы замапить страницу в адресное пространство процесса ниже 2Гб желательно с доступом только из Ring0, и по каким адресам лучше мапить? Руками не охота что-то таблицу страниц править... 2. Как из Ring0 проверить доступна ли память? Т.е. допустим в коде написана команда movss xmm0,[mem_addr] Я её буду эмулировать, и если прога бажная, mem_addr вообще говоря может быть недоступен. А BSOD ловить не охота... 3. Как перехватить CPUID чтобы прикинуться что есть поддержка SSE? Что-то кроме трассировки ничего в голову не приходит, но это убьёт производительность в разы. Ну это не обязательно, эмуляция преимущественно делается для наглых программ которые не проверяют наличие SSE. Хотя было бы полезно. ![]() |
|
Создано: 17 марта 2008 12:29 · Личное сообщение · #2 |
|
Создано: 17 марта 2008 12:31 · Личное сообщение · #3 |
|
Создано: 17 марта 2008 13:14 · Поправил: cppasm · Личное сообщение · #4 Rustem пишет: Ловить исключение при каждой команде ссе будет очень долго. Не так и долго, там не так много SSE кода. Я пробовал пропатчить прогу, заменив movss xmm0,[mem1]
на push [mem1]
, а остальные SSE команды просто занопить (их там не так много).
В принципе работает нормально, только из-за того что я заменил не все команды некоторые табы плохо отображаются. В общем со скоростью будет нормально. Rustem пишет: А для эмулятора самое удобное было бы загрузить свою длл и можешь хранить в ней любые значения любых регистров А как я в ней из Ring3 UD# буду перехватывать? Или при помощи SEH исключения ловить? И как подгрузить свою dll при старте процесса, в импорт добавить? nobodyzzz пишет: Скорее всего CPUID не юзаеться на прямую, а через IsProcessorFeaturePresent так что можно попробовать перехватывать её Наличие расширений та программа ради которой всё затеваю вообще не проверяет. Но хотелось бы сделать универсально... А IsProcessorFeaturePresent в любом случае в CPUID упрётся, только перехватить его не получается. ![]() |
|
Создано: 17 марта 2008 15:12 · Личное сообщение · #5 |
|
Создано: 17 марта 2008 15:16 · Личное сообщение · #6 |
|
Создано: 17 марта 2008 15:16 · Поправил: seeq · Личное сообщение · #7 |
|
Создано: 17 марта 2008 15:31 · Личное сообщение · #8 Для перехвата cpuid есть два способа: виртуализация и динамическая рекомпиляция кода. Могу выложить сорцы своей недописаной либы реализующей второй способ. Только разбираться с ними будете сами. ----- PGP key ![]() |
|
Создано: 17 марта 2008 15:32 · Поправил: cppasm · Личное сообщение · #9 Та фиг с ним с CPUID, хотя судя по мануалам её привелегированной сделать нельзя. Она вообще кроме UD# исключений не генерирует, а UD# только на 486 и нижу. seeq пишет: Намного легче пропатчить IsProcessorFeaturePresent и не париться. Ну не париться оно вообще легче ![]() А многие проги CPUID напрямую используют... Ну это ладно. Отговорили меня писать эмулятор, наверное буду просто прогу патчить и убирать неугодные команды... Хотя эмулятор было бы по-прикольней сделать. // ПС: отговорили в смысле оно нафиг никому не надо... ![]() |
|
Создано: 17 марта 2008 15:36 · Личное сообщение · #10 ntldr пишет: Для перехвата cpuid есть два способа: виртуализация и динамическая рекомпиляция кода. А можно идею динамическая рекомпиляции кода по-подробней? Просто я всё что придумал - это включить трассировку и ловить исключения с проверкой опкодов. Но это уронит производительность сильно. А виртуализация не годится, если на CPU SSE нет - то какая тут виртуализация... ![]() |
|
Создано: 17 марта 2008 15:44 · Личное сообщение · #11 cppasm пишет: А можно идею динамическая рекомпиляции кода по-подробней? Смысл идеи состоит в дизассемблировании и пересборке кода перед испольнением. Рекомпилированые учатски кода кешируются в памяти и используются повторно. Для трансляции адресов переходов используется хеш таблица рекомпилированых участком и jump cache хранящий адреса трансляции последних 256 джампов. Там еще много тонкостей, и немало проблем с самодифицирующимся кодом, динамически выделяемой памятью, и.т.д. Моя недоделаная реализация успешно работает с обычными прогами, и даже с некоторыми протекторами. Перехватывается любая произвольная команда, падение производительности 1.5-3 раза. По вышеописаному имхо будет трудно вьехать в особенности метода, ибо про это надо писать большую и подробную статью, на что у меня сейчас нет времени. Поэтому попробуйте разобраться с сорцами этой херни. ![]() ----- PGP key ![]() |
|
Создано: 17 марта 2008 16:25 · Личное сообщение · #12 |
|
Создано: 17 марта 2008 17:09 · Личное сообщение · #13 cppasm пишет: Так ты основного не написал - в какой момент происходит дизассемблирование и пересборка команды/команд? Базовый блок кода пересобирается перед его исполнением. Все выходы из блока при рекомпиляции заменяются на процедуры компилятора, и при их вызове происходит определение и рекомпиляция следующего блока. Никакая трассировка тут не нужна. ----- PGP key ![]() |
|
Создано: 17 марта 2008 18:41 · Личное сообщение · #14 |
|
Создано: 18 марта 2008 13:41 · Личное сообщение · #15 |
|
Создано: 18 марта 2008 15:35 · Личное сообщение · #16 Unmoored пишет: Извиняюсь за оффтопик, но что это у Вас за процессор такой без SSE? Это что ли ниже P3? Нет, не ниже Р3 - это просто процессор от AMD. А у AMD до AthlonXP SSE не было, у них своё расширение 3DNow! А в Adobe как я выяснил на это всё подзабили, и даже Photoshop который работает - 3DNow! не видит и не использует, использует только ММХ. ![]() |
|
Создано: 18 марта 2008 16:34 · Личное сообщение · #17 |
|
Создано: 18 марта 2008 18:24 · Поправил: cppasm · Личное сообщение · #18 за пару рублей это врядли ![]() ну и наф он мне нужен? покупать так уже двухъядерник какой-нить. кароче, всем кто собирается писать подобные советы - меня моя система вполне устраивает, и из-за одной проги я ничего покупать не буду. проще её просто снести и забыть. интересно эмулятор сделать. лучше скажите мне на каком IRQL выполняется обработчик исключения UD#, и на каком IRQL можно вызывать ZwGetContextThread/NtGetContextThread. Чего-то они сильно не документированы... ![]() |
|
Создано: 18 марта 2008 20:25 · Личное сообщение · #19 |
|
Создано: 19 марта 2008 11:15 · Поправил: cppasm · Личное сообщение · #20 Посмотрел VectoredHandler. А в чём его отличие от SEH? Я что-то не врубился. Насколько я понял в любом случае как с SEH так и с VectoredHandler надо модифицировать исполняемый файл. dll туда свою подгрузить или секцию приаттачить и EP сменить. А если сделать драйвер эмуляция будет работать для всех приложений. // Добавлено В принципе если делать через dll, то вроди нормально. Есть ли где-нибудь статья как подгрузить свою dll при запуске процесса? Т.е. чтобы моя dll сразу системным загрузчиком загружалась, желательно до остальных dll этого процесса. Её в импорт добавить надо или как? ![]() |
![]() |
eXeL@B —› Программирование —› SSE эмулятор |