+ Reply to Thread
Results 1 to 16 of 16

Thread: Нестандартный PE

  1. #1
    keyst0rke's Avatar

    Default Нестандартный PE

    Небольшая заметка о создании специфичного PE файла
    Может быть она будет кому-то полезной ;)

    Нулевая точка вода в приложениях Win32.


    Нестандартный PE заголовок может спасти наше приложение от инструментов анализа приложений, которые проверяют корректность заголовка. Как известно точка входа — это адрес, куда загрузчик, после загрузки приложения в память, передаёт управление. Точка входа расчитывается как сумма базы загрузки и смещения точки входа. В заголовке файла поле ImageBase обозначает именно базу загрузки приложения, а поле AddressOfEntryPoint — смещение точки входа.
    База загрузки начинается с DOS-заголовка, который с свою очередь начинается с MZ-сигнатуры «MZ», в байтовом представлении она выглядит как 4D 5A.



    DOS-заголовок под отладчиком


    Если смещение точки входа равно нулю, следовательно исполнение программы начнётся с байтов 4D 5A, в IA32 эти байты трактуются как:


    DEC EBP
    POP EDX
    Следовательно, чтобы восстаносить конекст исполнения следует увеличить EBP на единицу и восстановить исходное состояние стека. Для этого сразу после этих значений добавим:


    INC EBP
    PUSH EDX


    И прыжок на оригинальную точку входа.
    Получилось что-то вроде этого:

    Модифицированный DOS-заголовок


    Осталось только поправить поле AddressOfEntryPoint:



    Модификация AddresOfEntryPoint


    Теперь можете проверить, если вы работаете под вайном, то ничерта не получится, потому что вайн отказывается запускать подобные приложения. Так что, если вы пользователь Linux, то вам, как и мне, придётся запускать всё под виртуальной машиной ;)
    Кстати, Ollydbg запущенная под Linux не работает с файлом, однако, она же, запущенная под Windows, начала отлаживать программу — чудеса XD


    Пустая таблица импорта


    Есть ещё один трюк, он довольно популярный и очень эффективный в борьбе с поведенческим анализом программы — это нативная подгрузка библиотек и вызов функций из них. Как можно обойтись без функций вовсе? Это небольшой хак. В адресное пространство программы всегда подгружена библиотека kernel32.dll, даже если она не указана в таблице импорта, её адрес можно найти просканировав память. Сделать это очень просто:

    search_kernel: ; eax = Адрес внутри kernel32
    dec eax ; Уменьшение адреса
    mov bx, word[eax] ; Помещение 2-ух байтов в bx
    cmp bx, 'MZ' ; Сравнение с MZ-сигнатурой
    jnz search_kernel ; Если в bx не сигнатура, то повтор


    Для того, чтобы сократить колличество итераций, можно заранее обнулить AL либо весь AX целиком. Дело в том, что байтов, состовляющих сигнатуру MZ не встречается более нигде в kernel32.dll. А да, кстати, это делать нужно на точке входа, либо сохранять состояние EAX на точке входа и класть его перед этим кодом, так как на точке входа в EAX уже лежит адрес, который распологается где-то внутри kernel32.dll, ведь CreateProcess вызывается для создания вашего приложения и тем самым получается невольно подгруженным в ваше адресное пространство.
    Если у вас, каким-то образом не получается сохранить начальное значение EAX, либо сразу исполнить этот код на точке входа, можно взять адрес из стека, подходят ведь все адреса, лежащие внутри kernel32, а в стеке, в начале исполнения программы как раз лежит адрес выхода из программы, перейдя по которому мы попадём внутрь kernel32. Поэтому передав адрес, лежащий в стеке, мы получим тот же самый результат.
    Дальше — больше, чтобы вызвать нужную функцию в библиотеке, нужно найти её виртуальный адрес. Он хранится в таблице директории экспорта в таблице адресов, которая параллельна таблице имён функций и таблице ординалов. То есть, другими словами, чтобы найти адрес функции в памяти нужно:
    1. Прибавить к базе считанное значение по адресу [Base_PE+3Ch]
    2. Прибавить к получившемуся адресу значение [PE_Header+78h]


    Теперь мы находимся в директории экспорта, чтобы найти нужную функцию, нужно считать две таблицы — таблицу адресов и таблицу имён. Указатель на первую находится по смещению 1Ch, на вторую — 20h.
    Однако, некоторые экспортируемые функции могут не иметь имени, а их адреса могут быть в таблице адресов, это следует учитывать. Исходный код примера Слишком велик, для публикации в этой статье. Вызвать функцию из библиотеки, которая не загружена в память нельзя, для этого необходимо загрузить её в память, использую LoadLibrary. Чтобы бастро найти функцию по её имени, можно использовать функцию GetProcAddress. Так же, вместо использования имени функции, можно использовать хеш от имени, это дасть б`ольшую защищённость.

  2. 3 пользователя(ей) сказали cпасибо:
    Dark Koder (05-05-2014) Graxcon (05-05-2014) ximera (05-05-2014)
  3. #2
    JKornev's Avatar

    Default Re: Нестандартный PE

    Ну ... есть немного замечаний

    Во-первых помоему трюк с NULL-EP работать не будет на системах с DEP, так как секция заголовков загружается в память с правами readonly. Потом что косается борьбы с поведенческим анализом не понятно как вообще это повлияет на него, если имеется в виду защита данных импорта от антивируса, то это скорее относится к эвристике. Алгоритм поиска Kernel32 ужасен, утверждение:
    MZ не встречается более нигде в kernel32.dll
    неверно, обычно вытащить адрес любой библиотеки достаточно просто через PEB\TEB и распарсив LDR_MODULE. Даже если брать этот алгоритм за основу он как минимум должен учитывать то что сигнатура MZ расположена в начале страницы, тоесть выравнивание 0x1000.
    Он хранится в таблице директории экспорта в таблице адресов, которая параллельна таблице имён функций и таблице ординалов
    Если я не ошибаюсь то таблица виртуальных адресов не параллельна таблицам имён и ординалов, ординал это индекс в таблице адресов.

  4. Пользователь сказал cпасибо:
    ximera (05-05-2014)
  5. #3
    500mhz's Avatar

    Default Re: Нестандартный PE

    Внесу свои 5 копеек )
    После создания процесса на стеке лежит адрес возврата в кернел32, поэтому
    pop esi <---- адрес где то в кернеле
    выравниваем esi на 64к значение и сверяем с MZ
    если нет то отнимаем от esi 64к и снова сверяем

    Все бинарники грузятся в винде с выравниванием на 64к поэтому нет смысла побайтово парсить память на MZ

  6. 3 пользователя(ей) сказали cпасибо:
    Dark Koder (05-05-2014) keyst0rke (05-05-2014) ximera (05-05-2014)
  7. #4
    keyst0rke's Avatar

    Default Re: Нестандартный PE

    JKornev
    Видел семпл, который использовал память под свои заголовки, по ходу исполнения впихивая туда куски кода и исполняя их, поэтому думаю, что использовать заголовки для исполнения норм.
    С выравниваением - да, согласен, спасибо, возьму на заметку. С PEB/TEB получается морока с версиями NT и вообще не стабильно получается, а вот просто сканить память - всё норм.
    Импорт на поведенческий анализ не влияет, не то написал, импорт влияет на статический анализ.
    Делай то, что должен. Дальше будь, что будет.
    (с) Дед

  8. #5
    JKornev's Avatar

    Default Re: Нестандартный PE

    Когда исполняемый код помещается в секцию заголовков, секцие выделяются права RWE, в случае вашего трюка секции права на RWE не выделяются, т.к. по стандарту загрузчик проецирует заголовок с правами R. Для того чтобы ваш трюк работал везде, нужно либо использовать TLS callback и из него давать права RWE, либо возможно есть какие-то хаки для загрузчика, которых может и не существовать вообще. Я сделал так как у вас написано у меня не работает смотрите аттач.

    С PEB/TEB получается морока с версиями NT и вообще не стабильно получается, а вот просто сканить память - всё норм.
    Код парсинга PEB\TEB работает как на XP так и на 8.1, в чём именно может выражатся нестабильность или неприменимость?
    Attached Files

  9. #6
    500mhz's Avatar

    Default Re: Нестандартный PE

    Ваще не вопрос, лень кодить пример, но FSG код распаковщика в РЕ заголовок пихает.HELLO.ZIP

  10. #7
    keyst0rke's Avatar

    Default Re: Нестандартный PE

    У меня всё работает, см - http://rghost.net/54963960
    Про Нахождение kernel32.dll. Через PEB в XP находится kernelbase.dll, а в смёрке kernel32.dll, вот вам и проблема.

    Делай то, что должен. Дальше будь, что будет.
    (с) Дед

  11. #8
    JKornev's Avatar

    Default Re: Нестандартный PE

    Я же писал выше что оно не будет работать именно с DEP

    http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
    IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
    The image is compatible with data execution prevention (DEP).
    В вашем примере этот флаг не установлен, поэтому оно и исполняет код в секции заголовка

  12. #9
    JKornev's Avatar

    Default Re: Нестандартный PE

    Про Нахождение kernel32.dll. Через PEB в XP находится kernelbase.dll, а в смёрке kernel32.dll, вот вам и проблема.
    Наоборот в 7ке первым в списке идёт kernelbase а в XP kernel32, т.к. если я не ошибаюсь в XP не используется kernelbase(покрайней мере я пока не встречал такого). Но это не проблема, LDR_MODULE это двусвязный список, вчём проблема понему пройтись?

    Вот исходный код из моей статьи про шеллкоды, который демонстрирует обход списка LDR_MODULE и изьятия из него базового адреса любого модуля

  13. #10
    keyst0rke's Avatar

    Default Re: Нестандартный PE

    Ну.. может быть, никогда не сталкивался с DEP, отсюда и неопытность в этом вопросе
    Делай то, что должен. Дальше будь, что будет.
    (с) Дед

  14. #11
    JKornev's Avatar

    Default Re: Нестандартный PE

    P.S. в моем примере структура называется не LDR_MODULE а LDR_DATA_TABLE_ENTRY

  15. #12
    keyst0rke's Avatar

    Default Re: Нестандартный PE

    Да уж, неплохо. Разобрался, чото наглупил :)
    Делай то, что должен. Дальше будь, что будет.
    (с) Дед

  16. #13
    Mosc's Avatar

    Default Re: Нестандартный PE


  17. 2 пользователя(ей) сказали cпасибо:
    keyst0rke (23-05-2014) ximera (19-05-2014)
  18. #14

    Exclamation Re: Нестандартный PE

    Кто там про адрес говорил ?

    Code:

    push eax // EAX = BaseThreadInitThunk
    sub eax , 0x4DE0A // EAX = EAX - BaseThreadInitThunk
    sub eax , 0x1000 // EAX = DOS
    mov ecx , eax
    pop eax





    или проще, на 7 x32 норм работает



    :D
    Last edited by _or_75; 13-03-2015 at 16:11.

  19. #15
    JKornev's Avatar

    Default Re: Нестандартный PE

    это непереносимый код
    High tech, low life

  20. #16

    Default Re: Нестандартный PE

    Quote Originally Posted by JKornev View Post
    это непереносимый код
    Я знаю ), но хоть какой то

+ Reply to Thread

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
All times are GMT. The time now is 01:30
vBulletin® Copyright ©2000 - 2018
www.reverse4you.org