Выполнение кода на стеке.

Тема в разделе "WASM.BEGINNERS", создана пользователем REx07, 27 июн 2010.

  1. REx07

    REx07 New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2010
    Сообщения:
    5
    Суть проблемы: есть код который пишет другой программист, код этот нужно зашифровать в бинарнике, а расшифровку организовать во время выполнения в стеке. Ради бога, не спрашивайте зачем это нужно, просто так нужно)) (это один из способов защиты от отладки). А сама проблема вот в чем, когда мы из секции кода копируем его(код) на стек то, т.к. call'ы в скопированном коде могут быть near(E8, т.е. адрес указан не абсолютный, а относительно адреса самой инструкции call) и соответственно адреса коллов начинают указывать в неправильное место. Как с этим можно справиться? Я думаю о варианте заставить компилятор генерить все call'ы как far(FF15), либо искать инструкции E8 и править их адреса на нужные, но как их можно отличить от других данных/команд я хз. Может немного сумбурно, но суть вроде понятна. Ниже пример:

    Код (Text):
    1. int main()
    2. {
    3.     char Tmp[500];
    4.     void* start;
    5.     int len;
    6.  
    7.  
    8.     // получаем размер и адрес кода между метками
    9.     __asm {
    10.         pushad
    11.         mov ebx, lab_1
    12.         mov start, ebx
    13.         mov eax, lab_2     
    14.         sub eax, lab_1
    15.         mov len, eax
    16.         popad
    17.     }
    18.  
    19.     memcpy(Tmp, start, len);
    20.    
    21.     // расшифровываем код в Tmp (как, пофиг)
    22.  
    23.     goto lab_2;
    24.  
    25. lab_1:
    26.     // код написаный другим человеком который должен выполняться на стеке. Может быть что угодно например
    27.     std::cin >> a;
    28.     std::cout << a << std::endl;
    29. lab_2:
    30.  
    31.     // передаем управление коду в буфере
    32.     __asm{
    33.         lea ecx,Tmp
    34.         call $ + 5
    35.         pop eax    
    36.         add eax,7
    37.         push eax
    38.         jmp ecx
    39.     }
    40.  
    41.     return 0;
    42. }
     
  2. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    REx07
    вам уже говорили в конфе, что вы занимаетесь бредом %)
     
  3. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    разве стек исполняется?
     
  4. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
  5. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    FLASH300
    DEP не позволит исполнять код на стеке
     
  6. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
    код должен быть специально написан для стека по другому не как :)
     
  7. FLASH300

    FLASH300 New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2008
    Сообщения:
    72
    DEP нельзя отключить ?
     
  8. Flint_ta

    Flint_ta New Member

    Публикаций:
    0
    Регистрация:
    25 май 2008
    Сообщения:
    312
    Это должно отключить DEP

    Код (Text):
    1. .code
    2.  
    3. start:
    4.  
    5. mov dword ptr ds:[xxx], 2
    6.  
    7. push 4
    8. push offset xxx
    9. push 22h
    10. push -1
    11. call NtSetInformationProcess
     
  9. kweed

    kweed New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    81
    суть то в том что-бы перенести код в другое место, а не втом что-бы исполнить его именно на стеке:
     
  10. kweed

    kweed New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    81
    дизассемблер длин (помоему это так называется) + ищем E8 в первом байте инструкций (всех, или только которые по 5 байт)... такая вобщем идея
     
  11. izl3sa

    izl3sa New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2010
    Сообщения:
    164
    Адрес:
    Spb
    не лучше ли сразу писать базонезависимый код?

    Код (Text):
    1. либо искать инструкции E8 и править их адреса на нужные, но как их можно отличить от других данных/команд я хз.
    Дизассеблером пройтись, добавляя дельту к смещениям, не забывая про jxx и тд. Но релочить так свой же код имхо несколько не правильно =\
     
  12. REx07

    REx07 New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2010
    Сообщения:
    5
    В общем я как раз и думал о дизассемблере и корректировке адреса на вычисленную дельту. Хотя целый дизассемблер это весьма долго. Про дизассемблер длин тоже думал, вот только как его заюзать в данном случае дошло только сейчас. Спасибо всем за ответы. Может есть еще какие-либо идеи?
    p.s. DEP больше маркетинг чем защита. Подробности http://www.insidepro.com/kk/063/063r.shtml
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    REx07
    Это морфинг.
     
  14. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    REx07
    фигней вы страдаете...
     
  15. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    чем компилилось/линкилось? если есть релоки, то ищите их на ваш код/данные и релочьте их куда угодно. дизасм менее надежен.
    для пик-кода надо будет писать все или на асме или компилить спец-компилером.
    кстати, чтото мой склероз подсказывает, что в гцц была опция -fPIC. может, стоит попробовать ваш код под перемещение компилить с ей?
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    qqwe
    Может использовать поиск по терминам "пермутация" и "морфинг". Тогда поймёте что дизасм не менее надёжен.
     
  17. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    Clerk
    ну а объем кода идущий на дизасм и разбор всех возможных вариантов переходов и доступа к переменным и объем кода идущий на прохождение по списку из 10тка релоков?

    кроме того, как вы надежно и просто разберете нечто вроде

    mov eax,[ebp + 8]
    ;.. некоторые преобразования над eax
    jmp eax ; или [eax]

    похожий код мсвс часто делает на оптимизации свитчей.
    или

    ; вычисления и push адрес перехода
    ; код
    ; опять код
    ret ; переход

    такое тоже бывает.

    кроме того, сколько дизасм будет расковыривать все цепочки библиотечных вызовов, что навпихает С++ (если писано на нем) на каждом шагу?

    в то же время, релоки компилер и линкер все равно сгенерируют.
     
  18. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    qqwe
    У вас в оси есть экзешник содержащий релоки ?
    Не нужны никакие релоки, если компилируемый код готовится к мутации, он пишется особым образом, при котором в этом коде нет данных и абсолютных ветвлений.
     
  19. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    Clerk
    вопрос звучал так
    те осевые ехешники тут ни при чем. а любой объектник содержит релоки на все абсолютные адреса.
    можно и так. только это ведь уже затруднительно сделать даже на Цэ (хотя и возможно). те объем и сложность такого кода при средних трудозатратах будет очень ограничена.
    а чем вам релоки так не нравятся? они ведь занимают совсем немного места и могут кодироваться как угодно.
    и при этом здорово упрощают работу
     
  20. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    qqwe
    Мне они нравятся, значительно упрощают инфект, так что хватает базового дизасма и столь глубоко, что вы и под дизасмом внедрённый код врятле найдёте ;)
    Более того вы сказали:
    Если есть сурцы, то мутация превращается из пермутации в обфускацию. Задачи пермутации - интеграция в бинарный код. Задачи мутации - изменение графа, который заранее описан(как бинарный упрощённый так и в сурцах, может быть морфинг в исходном коде), в вашем случае это позволяют исполнить фиксапы. Частный случай морфинга - перенос кода в памяти, тоесть изменение базы загрузки без изменения графа. Универсальный двиг содержит полноценный дизасм. Мутатор своего кода содержит только дизасм длин и базовый дизассемблер, который различает только ветвления, этого достаточно для пересборки бинарного кода.