SSE эмулятор

Тема в разделе "WASM.NT.KERNEL", создана пользователем cppasm, 17 мар 2008.

  1. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Не, по-моему гораздо более напряжный метод чем через драйвер.
    Драйвер выполняется в крнтексте потока, и это многое упрощает.
    А так ну внедрил ты dll, поймал исключение - дальше надо узнавать от какого потока ты его получил, потому что для каждого потока свои xmm регстры и т.д.

    Нашёл ZwGetThreadContext и NtGetThreadContext.
    Вопрос - на каком IRQL их можно использовать (т.е. можно ли вызывать из обработчика исключения).
     
  2. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    cppasm
    случаем Bochs не эмулирует SSEx,
     
  3. Joes

    Joes New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2008
    Сообщения:
    98
    cppasm
    Не вижу разницы - хоть драйвер и работает в контексте текущего потока, тебе все равно надо хранить в памяти отдельный набор регистров для каждого потока в котором работаешь.
    Разница только в ring0/ring3.

    Просто, понимаешь, вариант с CALL всегда будет быстрее чем ловить каждый раз exception и обрабатывать его. Оно ж отжирает кучу тактов проца.

    Кстати, да, а какой нить DosEmu не содержит уже готового эмулятора?
     
  4. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Bochs эмулирует SSE, но он не динамический эмулятор.
    Т.е. эмулирует тупо весь код - это очень медленно.
    Разница в том, что так я ничего не проверяя буду записывать/читать виртуальные xmm регистры из контекста потока и всё.
    А так мне надо будет проверять в каком потоке произошло исключение, и сохранять регистры в зависимости от текущего потока в ту или иную область памяти.
    Хотя можно точно так же в контекст писать...
    В общем за исключением того что надо узнать в каком потоке произошло исключение - разница не большая.
    Просто ещё dll инжектить каждому процессу для которого это надо будет, а так один драйвер на всех :)
     
  5. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    а в твоем способе исключение разве не генерируется? ;)
     
  6. Joes

    Joes New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2008
    Сообщения:
    98
    Только один раз :derisive:
     
  7. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    и там только один
    разница в том, где будет идти обработка
    теоретически твой вариант будет как минимум не быстрее
     
  8. Joes

    Joes New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2008
    Сообщения:
    98
    Каким таким образом?
    Он же в r0 ловит exception, его обрабатывает (эмулируя инструкцию) и меняя EIP возвращает управление. Или я чего то не понял?
    Тут тоже самое, только в r3 но с заменой опкода sse на CALL <наш обработчик>. В смысле первое попадание на SSE код даст exception, но потом exception'ов в данном месте уже не будет.
    Будем спорить что CALL быстрее exception или даже обычного r3->r0->r3 перехода? :)

    Кстати, рулить доступ к памяти из r3 для SSE инструкций проще чем из r0. Один из плюсов, так сказать.

    Я все к чему - если там не убер хацкерская программа и от себя crc не считает, r3 будет шустрее. Хотя да, возни с inject больше.
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Joes
    теперь понятно
     
  10. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Проблема только в том - что это практически ОЧЕНЬ трудно реализуемо.
    Как например заменить на call команду xorps xmm0,xmm0 (3 байта).
    call туда просто не влезет.
    подскажите пожалуйста где есть более-менее детальное описание ZwGetContextThread/NtGetContextThread.
     
  11. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    cppasm
    у неббета в пдф
     
  12. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Нашёл, спасибо.
     
  13. Joes

    Joes New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2008
    Сообщения:
    98
    cppasm
    Угу, я писал что не всегда получится заменить на call.

    В обычном случае, без замены, будут ловиться exception'ы. Уже в exception будет идти эмуляция.
    Если можно заменить на CALL, заменяется на CALL и генерится stub который вызывает конкретную функцию эмуляции для конкретного опкода.
    При правильном проектировании это можно совместить, в плане общий эмулятор и разные точки входа (через exception или через stub).

    Вобщем, это просто мои 5 копеек. Я бы делал такое в r3 и всего то. Вроде подход называется динамической трансляцией.
     
  14. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Ну у меня тоже мысли есть в R3 сделать.
    Вопрос как именно. Можно VEH - но это WinXP и выше.
    А SEH насколько я понял надо для каждого потока устанавливать (если нет - поправьте).
    Т.е. надо ставить хук на CreateThread или что-то такое. Не охота...
    Наверное буду всё-таки через VEH делать.
    А как по-проще заставить виндовый загрузчик загрузить при запуске процесса мою dll (желательно до остальных).
    Думаю скинуть dll в папку с приложением и добавить в импорт - или так не пойдёт?
     
  15. Rustem

    Rustem New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2004
    Сообщения:
    429
    Адрес:
    Russia
    ключ реестра App_InitDlls.
    И длл будет грузится во все гуевые приложения
     
  16. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Мне не надо так радикально :)
    С загрузкой dll вроди разобрался - добавил в импорт.
    Теперь главное чтобы dll которые подгружаются раньше в своей DllMain не пользовали SSE.
     
  17. Joes

    Joes New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2008
    Сообщения:
    98
    Хукай KiUserExceptionDispatcher.
    Оно NT-only, но глобальное - 100% получишь exception до любого программного кода.
     
  18. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Сделал пока с AddVectoredExceptionHandler.
    Вопрос - чем можно заменить VEH чтобы работало под Win2k?
    Есть мысли сделать через SEH, но поскольку установка идёт в DllMain - в стеке фрейм создавать мне не подходит.
    Вопрос:
    1. можно ли создать SEH фрэйм в куче?
    2. SEH для каждого потока отдельно ставить надо?
    3. VEH вроди для процесса ставиться и ловит исключения всех потоков, или нет?
     
  19. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    В XP SP2 (вроде) нельзя - софтварный DEP рулит

    Внутрипоточный SEH ес-но. Для всего приложения см. SetUnhandledExceptionFilter
     
  20. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    О, SetUnhandledExceptionFilter как раз то что надо.
    Теперь конкретный вопрос (вроди уже последний).
    Вот код либы:

    Код (Text):
    1. BOOL WINAPI DllMain(HANDLE hinstDLL,DWORD dwReason,LPVOID lpvReserved)
    2. {
    3.     switch(dwReason)
    4.     {
    5.         case DLL_PROCESS_ATTACH:
    6.             MessageBox(0,"DLL: PROCESS_ATTACH","Msg",MB_OK | MB_ICONINFORMATION);
    7.             BackupHandler=SetUnhandledExceptionFilter(ExceptionHandler);
    8.             break;
    9.         case DLL_THREAD_ATTACH:
    10.             MessageBox(0,"DLL: THREAD_ATTACH","Msg",MB_OK | MB_ICONINFORMATION);
    11.             break;
    12.         case DLL_THREAD_DETACH:
    13.             MessageBox(0,"DLL: THREAD_DETACH","Msg",MB_OK | MB_ICONINFORMATION);
    14.             break;
    15.         case DLL_PROCESS_DETACH:
    16.             MessageBox(0,"DLL: PROCESS_DETACH","Msg",MB_OK | MB_ICONINFORMATION);
    17.             SetUnhandledExceptionFilter(BackupHandler);
    18.             break;
    19.         default:
    20.             MessageBox(0,"DLL: Unknown reason","Msg",MB_OK | MB_ICONINFORMATION);
    21.     }
    22.     return TRUE;
    23. }
    Добавил её в импорт процесса, запускаю - получаю:
    DLL: PROCESS_ATTACH
    DLL: THREAD_ATTACH
    DLL: THREAD_ATTACH
    DLL: THREAD_ATTACH
    DLL: PROCESS_DETACH

    Вопрос - почему несоответствие ATTACH/DETACH?
    THREAD_DETACH вызывается только при завершении потока если процесс продолжает работать?
    Т.е. то что выше было получено при завершении всего процесса.
    И при создании основного потока процесса не приходит THREAD_ATTACH - это нормально?