CALL (FF/2) Под x64

Тема в разделе "WASM.X64", создана пользователем Fukki, 17 янв 2011.

  1. Fukki

    Fukki New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2011
    Сообщения:
    5
    Здравствуйте. Пишу сюда, тк столкнулся с такой проблемой: При установке хука на FreeHeap под 64bit получаю эксепшн.
    При отладке выяснилось следующее: Опкод FFh 15h содержит относительный адрес, а не абсолютный, как в x86-32:

    Опкод 32:
    Код (Text):
    1. 0x75B50000         ff 15 ec 05 d5 75
    Студия интерпретирует как:
    Код (Text):
    1. 0x75B50000         call dword ptr ds:[75D505ECh])
    Адрес абсолютный, по нему действительно можно найти __imp__RtlFreeHeap

    Опкод 64:
    Код (Text):
    1. 0x000007FFFFB90004        ff 15 26 a0 07 00
    Студия интерпретирует как:
    Код (Text):
    1. 0x000007FFFFB90004        call qword ptr [7FFFFC0A030h] ; 7FFFFC0A030h == 0x000007FFFFB90004 + 0x6 + 0x7A026
    Адрес относительный и соответственно, при создании трамплина, мы должны учитывать дельту м-ду оригинальной функцией и трамплином.

    Однако открываю "Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2a", page 188:
    ----------------------------------------------------------------------------------------------------------------
    Opcode | Instruction | Op/En | 64-bit Mode | Compat/ Leg Mode | Description
    ----------------------------------------------------------------------------------------------------------------
    FF /2 CALL r/m32 B N.E. Valid Call near, absolute indirect, address given in r/m32.
    FF /2 CALL r/m64 B Valid N.E. Call near, absolute indirect, address given in r/m64.

    Укажите, пожалуйста, на ошибку в моих рассуждениях/дыру в знаниях.

    Brest regards, Fukki.
     
  2. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Есть много способов, чтобы обойти это ограничение.

    Например вместо call, использовать последовательность инструкций
    любой_оффсет - это уже абсолютный 8-байтный аддресс.
     
  3. Fukki

    Fukki New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2011
    Сообщения:
    5
    Я может немного неясно выразился, но у меня не стоит вопроса в том, чтобы совершить прыжок по 64-битному RVA.
    Вопрос в следующем: в документации ясно сказано, что прыжок должен быть относительный, а мои глаза и дизассемблер говорят обратное. Ведь не может же быть ошибки, а значит я не прав, непонятно лишь где.
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    r/m64 значит что в регистре/по адресу лежит абсолютный адрес прыжка.
    однако сам адрес, по которому лежит этот абсолютный адрес для перехода является относительным.
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Мне кажется, что в обоих случаях речь про адрес, где лежит адрес, в сравнении с аргументом опкода.
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    какая разница про что?
    если разобрать механизм, то будет видно что имело в виду intel, когда писали "absolute indirect"
     
  7. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Это только если у тебя дельта в 4 байтах уместится.
     
  8. Fukki

    Fukki New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2011
    Сообщения:
    5
    Допустим, что так. Тогда что с r/m32, ведь следуя вашей логике, это относительный адрес, по которому лежит абсолютный, только уже размером в dword, а не qword. Хотя, в приведенном мною примере под x32, за опкодом следует само Значение прыжка, а не адрес, где оно содержится.

    И еще, если вы правы, то пройдя по RIP + 0x6 + 0x7A026 (опкод: ff 15 ec 05 d5 75) я должен извлечь оттуда абсолютный адрес __imp__RtlFreeHeap, но там находится сама функция а не ее RVA.

    Создается впечатление, что мы говорим о разных вещах.. может FF 15 это вовсе не FF/2 r/m32(64) ?? :P

    Я выделяю память под трамплин в том же сегменте, так что уместится.
     
  9. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    > Тогда что с r/m32
    r/m32 - абсолютная адресация.
    в этом одно из отличий 64-битного режима.
    > но там находится сама функция а не ее RVA.
    > call qword ptr [7FFFFC0A030h]
    малость не соответствует.
     
  10. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.617
    Адрес:
    Russia
    слышал звон на rdsn что непосредственная адресация в х64 приказала долго жить и необходимо городить фиктивное базирование (по базе 0)
     
  11. Fukki

    Fukki New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2011
    Сообщения:
    5
    >r/m64 значит что в регистре/по адресу лежит абсолютный адрес прыжка.
    Только что специально зашел под отладчиком посмотреть а так ли. Итак, процесс 64бит, отладчик ВС, Идем по HeapFree:

    Код (Text):
    1. HeapFree:
    2. 0000000077692C70  sub         rsp,28h
    3. 0000000077692C74  call        qword ptr [__imp_RtlFreeHeap (7770CCA0h)] ; ff 15 26 a0 07 00
    4. 0000000077692C7A  movzx       eax,al
    5. 0000000077692C7D  add         rsp,28h
    6. 0000000077692C81  ret
    Т.о., исходя из выше сказанного, по адресу 0000000077692C7A + 0x7a026 должен находится абсолютный адрес __imp_RtlFreeHeap. Идем туда:
    Код (Text):
    1. __imp_RtlFreeHeap:
    2. 000000007770CCA0  rcr         byte ptr [rsi+rcx*4],1                       ; d0 1c 8e 77 00 00 00 00
    3. 000000007770CCA3  ja          __imp_RtlFreeHeap+5 (7770CCA5h)
    4. 000000007770CCA5  add         byte ptr [rax],al
    5. 000000007770CCA7  add         byte ptr [rax+778CB5h],dh
    6. 000000007770CCAD  add         byte ptr [rax],al
    Как видно, в операнде находится не адрес с RVA функции, а само смещение на нее (относительное).

    PS: Спасибо, что пытаетесь помочь.
     
  12. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    Fukki
    Другими словами если в ModRM задает адрес ячейки, то он будет вычисляться относительно RIP следующей команды (в аргументе хранится относительный адрес). В тоже время значение в этой ячейке (на примере с CALL [...]) будет представлять из себя абсолютный адрес.
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Fukki
    А вот и не видно. Чем Вам 778E1CD0, находящийся по адресу 7770CCA0, — не адрес функции? (кстати в операнде находится относительное смещение области памяти, содержащей не RVA, а VA функции)
     
  14. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    > Т.о., исходя из выше сказанного, по адресу 0000000077692C7A + 0x7a026 должен находится абсолютный адрес __imp_RtlFreeHeap. Идем туда:
    угу, я его и вижу, например.
    ну да, как я и писал в одном из ранних постов.
     
  15. Fukki

    Fukki New Member

    Публикаций:
    0
    Регистрация:
    17 янв 2011
    Сообщения:
    5
    Спасибо, разобрался.