проблемы с перехватом

Тема в разделе "LANGS.C", создана пользователем XshStasX, 12 янв 2010.

  1. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    делаю перехват на основе перезаписи начальных байт.
    проблема в том что когда я передаю управление на
    функ подобного вида:
    void a(){
    MessageBox(0,"Hook","",0);
    };

    то изменяются все регистры что как раз и очень плохо, для того чтоб такого не было
    делал так:
    __asm{
    pusha //все регистры в стек
    call a
    popa //все регистры из него
    };
    но все равно регистры не правильно востанавливаются.
    такое чувство как будто а() портит стек( хотя не должна.
    весь исходных код прикреплять к теме, мож кто подскажет в чем проблема
     
  2. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    и еще как заставить компилятор в такую процедуру
    void(){
    };
    не вставлять лишний асм. код который изменяет регистры
    вот так ее генирирует с++ 6.0
    Код (Text):
    1. push ebp
    2. mov ebp,esp
    3. sub esp,40
    4. push ebx
    5. push esi
    6. push edi
    7. lea edi,[ebp-40];
    8. mov ecx,10h
    9. mov eax,0ccccccccch
    10. rep stos dword ptr [edi]
    11. pop edi
    12. pop esi
    13. pop ebx
    14. mov esp,ebp
    15. pop ebp
    16. ret
    зачем это :
    Код (Text):
    1. sub esp,40
    2. lea edi,[ebp-40];
    3. mov ecx,10h
    4. mov eax,0ccccccccch
    5. rep stos dword ptr [edi]
    не понимаю.
    как сделать чтоб код процедур генировался как в Дельфи 7.0 (по умолчанию) ??
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Во-первых, собирай Release, а не Debug сборку.
    Чтобы совсем убрать пролог/эпилог,используй __declspec(naked).
    (в этом случае возникнет проблема с локальными переменными. если тебе все же нужны локальные переменные, а так же нужен свой пролог, то нужно делать примерно так:
    Код (Text):
    1. __declspec(naked) void _stdcall someFunction (int arg1)
    2. {
    3.   int local;
    4.   __asm
    5.   {
    6.     push ebp
    7.     mov ebp, esp
    8.     sub esp, __LOCAL_SIZE ; предопределенная константа содержит размер локальных переменых текущей функции
    9.   }
    10.   local = arg1;
    11.   printf("hello: %d\n", local);
    12.   __asm
    13.   {
    14.     leave
    15.     retn 4
    16.   }
    17. }
    Так же обрати внимание на соответствие конвенций вызова (stdcall, cdecl, fastcall): в этом может быть причина порчи стека.
     
  4. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Протрассируй вызов WriteFile в отладчике и увидишь, что ты копируешь некоторый call, который использует относительную адресацию и становится невалидным в новом месте. Используй только 5-байтовый джамп. То, что ты показал во втором посте -- бывает только в отладочной версии. Собирай релиз =)
     
  5. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    я копирую не call а кусок кода в середине где нет относительной адресации.
     
  6. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    вопрос если я перехват делаю так:
    1) ищу в перехватываемой функ. свободных 10байт(инструкций без относительных адресаций)
    2)сохраняю в буфер 10байт( перехватываемая функ.)
    3)далее на первые 5байт пишем call для нашей функ а на следующии 5байт джамп на буфер а в конце буфера джамп на на перехватываемую функ.

    какие недостатки этого метода, и в каких случаях от него может валится вся перехватываемая функ.
     
  7. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    В случае, когда в 10 байтах не помещается целое число инструкций, что и происходит у меня на машине с твоим кодом.
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Нужен дизассемблер длин.
    Целое число инструкций, длина которых >=5, копируется во временный буфер, при необходимости фиксапится (если там попались jxx), завершается jmp'ом на продолжение. а вместо этих инструкций пишется 5 байтовый джамп на хук.
    чтобы вызвать из хука оригинальную функцию, нужно передать управление во временный буффер
     
  9. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    хм а разве одни и теже инструкции на разных машинах разные по размеру ???
    у меня в том месте 4 mov находиться.
     
  10. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Код функций разный. У меня, соответственно 2 пуша и колл
     
  11. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    а у тебя не хр sp 2 ??
    не подскажешь какие есть функ условной адресации кроме call , jmp?
    если делать программу которая делает перехват по такому методу надо учитовать модель процессора для под счета размера операндов команд?
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Опкоды одинаковые на всех процессорах, поддерживающих IA-32.
     
  13. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    тоесть на процесорах с такой виндой как и у меня будет работать мой перехват если он работает у меня. да ?
     
  14. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    все равно не понимаю если функ/ которая получает управление при перехвате вот такая:

    Код (Text):
    1. void __declspec (naked) mess(){
    2.  __asm{
    3.   pusha
    4.  
    5.    popa
    6.   ret
    7. }
    8. }
    все хорошо.
    а вот если так сделать;
    Код (Text):
    1. void __declspec (naked) mess(){
    2.  __asm{
    3.   pusha
    4.    popa
    5.   ret
    6. } }
    7.  
    8. void a(){
    9.  MessageBox(0,"","",0);
    10.  return;
    11. }
    то падает перехват так как popa востанавливает совсем другие данные
     
  15. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    ошибся в #14 там вот так
    void __declspec (naked) mess(){
    __asm{
    pusha
    call a
    popa
    ret
    } }

    то падает перехват так как функ. востанавливает совсем другие данные
     
  16. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    ps. модераторам дайте возможности редактировать свой пост или возможность его удаления.
     
  17. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    XshStasX
    Ес-но палает, т.к. ты заменяешь вызов ф-и WriteFile c 5-ю параметрами на вызов своей mess() без параметров, что приводит к нарушению стека после ret. Замени на ret 5*4 и будет тебе счастие ;)
     
  18. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    1) Для отладки используй Release и хороший дебаггер (Олю здесь всегда советуют)
    - тогда можно увидеть чем отличается вызов "call a" от "a();" а они отличаются, как уже говорили прологом/эпилогом, которые определяются конвенциями (stdcall, cdecl, fastcall)

    2) Возможно, Great имел ввиду, что __declspec (naked) надо писать при объявлении функции a()...?
     
  19. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    нет падает не из-за этого.
    я перед вызвом ставил pusha . после прочитав manual от Intel. понял что надо pushad.
    а то что один параметр у функ. которою я вызываю значения почти не имеет.
    так как после своего завершения она поставит обратно значение стека. а popad в остановить все регистры.
     
  20. XshStasX

    XshStasX New Member

    Публикаций:
    0
    Регистрация:
    9 авг 2008
    Сообщения:
    991
    и еще если не сложно ответьте на #13 пост