Опасность использования RW-секции.

Тема в разделе "WASM.WIN32", создана пользователем FireHacker, 8 мар 2008.

  1. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Я до сих пор не понимаю как такое возможно, типо эвристик показал что это секция кода с правом на запись, и кричим на это. Имхо бред.
     
  2. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Booster
    Не всякий эвристик закричит, это верно. А вот узнать, какая эта секция (код или данные) и узнать права на запись труда не составит. Или это тоже бред?
     
  3. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    Все не читал, но [надо было читать)))]

    later:
    прочитал:) а адреса экспортируемых функций изменить на фейк, который сделает свое дело, а затем отредактирует IAT родителя?

    з.ы. есть варианты извратнее? :lol:
     
  4. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    из третьего кольца поменять атрибуты можно только вызовом системной функции ОС
    аналогичной функцией можно узнать текущие атрибуты доступа к странице
     
  5. FireHacker

    FireHacker Владислав Петровский

    Публикаций:
    0
    Регистрация:
    13 авг 2007
    Сообщения:
    10
    Адрес:
    Казахстан. Петропавловск
    a1ss
    Не пойдёт. Сторонний код может сохранить себе где-то указатель на функцию (в ESI, скажем) c целью оптимизации, а потом несколько раз вызывать. И что толку в этом случае, что мы поменяли адреса в IAT.
     
  6. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    FireHacker
    Jmp w,[adrfun]

    Конечно это медленнее чем просто JMP, но быстрее чем с флагом.
     
  7. FireHacker

    FireHacker Владислав Петровский

    Публикаций:
    0
    Регистрация:
    13 авг 2007
    Сообщения:
    10
    Адрес:
    Казахстан. Петропавловск
    Что это? jmp с двумя операндами?? Таких команд нет.
     
  8. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    мда, согласен.. По теме аверы редко палят такие вещи, но я бы не стал писать в секцию кода, т.к. это плохо с точки той же оптимизации, поэтому менять аттрибуты страницы нах надо. ИМХО юзой флаг.
     
  9. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    rei3er
    Кто ж про этим спорит. Я про то, что сама идея этого мягко говоря сомнительна. Можно такое сделать, но обойти, поменять права в обход тоже можно. Лично для меня секции отличаются не семантикой, а атрибутами. И говорить о том что вот такая-то секция с такими-то признаками только для того-то не правильно.
    Я пакеры не люблю, но если аверы начнут кричать что это потенциально опасное ПО, это уже смахивает на параною.
     
  10. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    А вот с точки зрения ОС правильно. Здесь уже говорили, что секции кода обычно не свопится. При попытке записи сработает Copy On Write.
     
  11. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    valterg
    Что ты говоришь :) Два косвенных перехода подряд (call в exe + jmp в dll) это неявная, но гарантированная потеря 1-2 тактов и 2-4 микроопераций на стадии декодирования (или TC-fetch в P4). А проверка флага с прыжком на инициализацию это всего одна лишния микрооперация по сравнению с jmp [mem] и 0-1 такта на исполнение, которые можно просто не заметить на фоне пролога функции
    Код (Text):
    1.   cmp [flag],0
    2.   jz do_init
    3. do_ret:
    4.   ;тело функции
    5.   ret
    6. do_init:
    7.   call init
    8.   jmp do_ret
    PS: ИМХО - проблема с быстродействием явно надуманная, видимо автору просто хочется поизвращаться ;)
     
  12. FireHacker

    FireHacker Владислав Петровский

    Публикаций:
    0
    Регистрация:
    13 авг 2007
    Сообщения:
    10
    Адрес:
    Казахстан. Петропавловск
    leo
    Тут есть несколько проблем.
    1) Каким образом код, который ты привёл для примера (который после метки do_init) узнает, что сделав инициализацию, ему нужно сделать jmp именно на do_ret ?


    Мне видится только следующий вариант:
    Код (Text):
    1. Interceptor_for_function_A:
    2.      cmp [flag], 0
    3.      jne Real_A
    4.      call Initializer
    5.      jmp Real_A
    6.  
    7. Interceptor_for_function_B:
    8.      cmp [flag], 0
    9.      jne Real_B
    10.      call Initializer
    11.      jmp Real_B
    12. Interceptor_for_function_C:
    13.      cmp [flag], 0
    14.      jne Real_C
    15.      call Initializer
    16.      jmp Real_C
    17.  
    18. Initializer:
    19.    ; Тут мы делаем инициализацию
    20.    retn 0       ; И возвращаемся в интерцептор
    21.  
    22. Real_A:
    23.   ; ...
    24.   ; ...
    25.   retn 4
    26. Real_B:
    27.   ; ...
    28.   ; ...
    29.   retn 8
    30. Real_C:
    31.   ; ...
    32.   ; ...
    33.   retn 0
    Много код, и как-то не очень красиво.
    2) Такой подход требует релоков на каждый cmp [flag], 0. Т.е. я конечно могу их добавить, но это может оказаться очень проблематично (если в секции релоков не хватит места, то очевидно, её придётся расширять, а если после неё что-то идёт, то придётся её ещё и физически переносить). Хотя VB добавляет секцию релоков последней. Да и я могу "забронировать" в ней несколько "мест", добавив в VB-код пустышки, требующие релоков.

    3) Такой подход требует места в секции данных (под флаг). И тут начинается самое весёлое. VB делает бинарники так, что секция данных, как правило, забита полностью. Т.е. все имеющиеся данные (там, GUID-ы, структуры, необходимые для корректного функционирования библы и т.д) помещаются в начало секции данных. При этом в таблице секций поле PhysicalSize устанавливается равным размеру этих самых имеющихся данных (назовём их 'инициализированными'), округлённый вверх до FileAlign. VirtualSize же оказывается большим, чем PhysicalSize, - таким подходом образуется область неинициализированных данных (которую VB использует под глобальные переменные и локальные статические переменные простых функций). Т.е. физически секцию данных пришлосбь бы расширять до размера Ceil(VirtualSize + 4, FileAlign).
    Расширять пришлось бы, естественно, ручками.
    Способ заставить VB зарезервировать для меня некоторое место в секции кода я нашёл, а вот в секции данных - нет. (Придумывая на ходу - хотя, возможно эта проблема решается напихиванием строковых констант в код, и функции-пустышки, которая бы их все использовала (в противном случае VB не будет их помещать в секцию данных)).

    Вобщем, 1 пункт - код не кажется мне идеальным. 2, 3 - нежелание писать код, необходимый для всех этих махинаций.

    Настолько ли способ с флагом быстрее моего, что на него не жалко потратить столько усилий?

    Иногда действительно хочется именно поизвращаться, но в данном случае хочется всего-лишь сделать оптимальное (быстрейшее и при том компектнейшее) решение. В противовес - способ с динамическим кодом уже давно написан и будет жалко убирать его и писать часть проекта по новой схеме.
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    FireHacker
    Ладно, ты прав. Раз тебе нужно влезть в готовую длл, да еще с вб-прабамбасами, да и код уже написан - юзай изменение кода.
    Насчет аверов думаю опасения напрасны, если производить запись обычными mov\movs, а не WriteProcessMemory. Как верно заметил Booster никакой разумный авер не может перехватить исполнение инструкции mov, он только может анализировать твой код на потенциальную опасность, да перехватывать вызовы апи