Само модифицирующийся код.

Тема в разделе "WASM.BEGINNERS", создана пользователем Otebebe, 15 май 2007.

  1. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Otebebe
    То есть ты таким способом хочешь резидентную прогу сделать? После вызова функции завершения в PSP может оказаться что угодно. Или ты хочешь сделать TSR без PSP?
     
  2. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Для защиты конечно. Для чего ж еще. В дизасме ты такой код уже не посмотришь (плагинами иды прошу не упрекать). Самомодификация - это то же самое шифрование. Только не в цикле меняется целый блок кода, а "вручную" каждая инструкция.
     
  3. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Vov4ick
    Пока сделал следующее:
    a)процедуру таймера (примерно через секунду бросает в видеобуффер символ единицы) описал через DB в segment data (так как гружу по смещению 80H то все смещения в коде естественно пересчитать легко)
    б) при старте осн.прг сохраняю вектор старого обработчика
    в) забрасываю DS:SI в PSP:0080H
    г) устанавливаю новый вектор на PSP:0080H
    д)....(ну жду AH=01H int21H cимвол,пока BIOS арбайтен.) из основной.

    Теперь думаю о инициализации вектора из PSP и из PSP же завершить "программу-папу"
    место то еще есть. :) Но пока отложил и буду изучать cтруктуру TSR.
     
  4. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    А почему нельзя написать обычного резидента?
     
  5. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Так не умею пока :)
     
  6. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    А, ну это временно :derisive: Если есть вопросы, задавай.
     
  7. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Вот вам рабочий резидент!
    Это нужная понимаешь вещь.
    Можно управлять громкостью SB16 из под DOS.
    Было такое время когда ВИНДЫ мы не могли поставить на свое железо.
    Компилилось каким-то ТАСМОМ. 3-й что-ли. Ну давно это ...

    Код (Text):
    1.     .286        ;режим МП 80286
    2.     .model tiny ;незнаю зачем, но эти строки тут нужны
    3.     .code       ;для COM файлов
    4.     org 100h    ;обязательно для COM файлов
    5. prg:    jmp ini
    6.  
    7. newint9 proc far
    8.     push ax
    9.     in al,60h
    10.         cmp al,54h      ;активация по ALT+Print Screen .ТОЧНО не помню давно это было попробуй F12
    11.     pop ax
    12.     je do_pop
    13.     jmp cs:vector
    14.     endp           
    15.    
    16. do_pop:
    17.     pusha
    18.     in al,61h
    19.     mov ah,al
    20.     or al,80h
    21.     out 61h,al
    22.     xchg ah,al
    23.     out 61h,al
    24.     mov al,20h 
    25.     out 20h,al
    26.  
    27.     mov ah,0bh
    28.     mov bx,001fh
    29.     int 10h
    30.  
    31. Voice   equ 04h
    32. Mic equ 0Ah
    33. Volume  equ 22h
    34. FM  equ 26h
    35. CD  equ 28h
    36. Line    equ 2eh
    37. start:
    38.         mov ah,10h
    39.         int 16h
    40.         mov bl,FM
    41.         cmp al,'f'
    42.         jz Down
    43.         cmp al,'F'
    44.         jz Up
    45.         mov bl,Voice
    46.         cmp al,'w'
    47.         jz Down
    48.         cmp al,'W'
    49.         jz Up
    50.         mov bl,Line
    51.         cmp al,'l'
    52.         jz Down
    53.         cmp al,'L'
    54.         jz Up
    55.         mov bl,Volume
    56.         cmp al,'v'
    57.         jz Down
    58.         cmp al,'V'
    59.         jz Up
    60.         mov bl,CD
    61.         cmp al,'c'
    62.         jz Down
    63.         cmp al,'C'
    64.         jz Up
    65.         mov bl,Mic
    66.         cmp al,'m'
    67.         jz Down
    68.         cmp al,'M'
    69.         jz Up
    70.  
    71. exit:           cmp al,'q'      ;выход по q
    72.         jnz start
    73.  
    74.         mov ah,0bh
    75.         mov bx,0000h
    76.         int 10h
    77. eexit:      popa
    78.         iret
    79.  
    80. Up:     call PUp
    81.         jmp exit
    82. Down:       call PDown
    83.         jmp exit
    84.  
    85. PDown       proc
    86.         push ax
    87.         mov al,bl
    88.         call MixPort
    89.         call MixDataIn
    90.         sub al,022h
    91.         jc zero
    92. rzero:      call MixDataOut
    93.         pop ax
    94.         ret
    95. PDown       endp
    96. zero:       mov al,00h
    97.         jmp rzero  
    98. PUp     proc
    99.         push ax
    100.         mov al,bl
    101.         call MixPort
    102.         call MixDataIn
    103.         add al,011h
    104.         jc full
    105. rfull:      call MixDataOut
    106.         pop ax
    107.         ret
    108. PUp     endp
    109. full:       mov al,0ffh
    110.         jmp rfull
    111.  
    112. MixPort     proc
    113.         mov dx,224h
    114.         out dx,al
    115.         ret
    116. MixPort     endp
    117.  
    118. MixDataOut  proc
    119.         mov dx,225h
    120.         out dx,al
    121.         ret
    122. MixDataOut  endp
    123.  
    124. MixDataIn   proc
    125.         mov dx,225h
    126.         in al,dx
    127.         ret
    128. MixDataIn   endp
    129.  
    130. vector      dd ?
    131. endd:
    132. ini:
    133.     push cs     ;запись во все сегментные регистры
    134.     push cs     ;одного значения.
    135.     pop ds      ;только для COM файлов
    136.     pop es      ; cs=dc=es
    137.     lea dx, message
    138.     mov ah,09h
    139.     int 21h
    140.    
    141.         mov ax,3509h                    ;перехват int9
    142.     int 21h
    143.     mov word ptr vector [2],es
    144.     mov word ptr vector [0],bx
    145.  
    146.     push ds
    147.     mov ax,cs
    148.     mov ds,ax
    149.     mov dx, offset newint9
    150.     mov ax,2509h
    151.     int 21h
    152.     pop ds
    153.     mov dx, offset endd
    154.         int 27h         ;функция завершения программы,отаться резедентной
    155. message db 13,10
    156.         db 'драйвер микшера установлен',13,10,'$'
    157.     end prg
     
  8. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Ну примеров можно много привести... Типовой резидент. Правда нет проверки на повторный запуск и памяти много кушает.
    ЗЫ Активируется по printscreen, альтом в нём и не пахнет.
     
  9. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Vov4ick и S_Alex
    Спасибо.
    P.S 54H='T' (ASCII)
     
  10. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Otebebe 54h - это скан-код, а не символ :) Их возвращает клавиатура.
     
  11. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    leo

    Угу, а также автоматическое отслеживание записи в код, поэтому старые фокусы с предвыборкой как на 486 давно не прокатывают. - Иструкции сеарилизации позволяют модифицировать код даже на Core 2 Duo.

    Otebebe
    Нет код который приведен мной не модифицирует сам код, а лишь пишет впеременную в кодовом сегменте приусловии что es=cs, сама фишка - чтобы самомодифицирующийся код мог работать необходимо посе модификации исполнить любую инструкцию сеарилизации процессора. Т.е. все вышеприведенные примеры не используют иструкции сеарилизации, и работа модифицированного кода может оказаться непредсказуемой, тем более на многоядерных процессорах.
     
  12. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    PROFi
    Про сериализацию пока...:-(.
    Но ЕS=CS понял.
    Вот построил... "колхозно-обфускаторную без джампово-поп модификацию" :)
    ;ЕXIT в DOS
    Код (Text):
    1. push CS
    2. mov AX,CS         ;"привязываемся" к некоторой базе
    3. xor BX,BX
    4. K0:
    5. inc AX
    6. cmp AX,42A7H
    7. jne K0
    8. K1:
    9. shr AH,01H         ;AX=21A7H
    10. add AL,26H         ;AX=21CDH
    11. xchg AX,BX         ;BX=21CDH AX=0000H
    12. add AH,26H         ;AX=2600H
    13. shl AX,01          ;AX=4C00H BX=21CDH
    14. pop ES             ;ES=CS
    15. push AX
    16. push BX            
    17. sar BX,08H
    18. mov AH,BH          ;AX=0000H BX=0021H
    19. pop ES:[BX]
    20. pop AX
    21.  
    22. CS:0021 <----cюда строим 0CD21H
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    PROFi
    Повторяю, современные процессоры устроены намного сложнее i4086 поэтому они сами отслеживают модификацию кода и при необходимости сбрасывают не только конвеер, но и T-кэш в P4 и служебную инфу преддекодера длин в L1\L2 AMD К7,К8. Поэтому требование обязательной сериализации рулит только для древних процев, а в современных манулах Intel и AMD ты такого требования не найдешь
     
  14. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Otebebe Честно говоря не понял смысла кода :dntknw:
     
  15. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    Vov4ick
    В чем смысл ?
    Смотрите какие уже видели приемы самомодификации:
    a) xor-подход.Инструкция "Б"готовится через преобразование байт-строки представляющей команду "А".
    "A"-в коде есть,но не выполняется.Обфускация.
    б) DS:SI-->ES:lol: I."Забрасывание кода".Несколько возможностей.Например с замещением кода.
    Или с дополнением.Видимо лучший подход в модификации.
    в) сall/jmp через регистр/mem. Пока у меня нет комментариев.
    г) "меточный мув".(Применен в статье "Заклинание кода").Во многом похож на a)
    д)В примере же с CS=ES:[BX] BX-можно рассматривать как параметр.Который...грубо...представляет
    длину инструкций.Это позволяет _достраивать_ код ....в общем не знаю как сказать точнее...:)
     
  16. sxd

    sxd Виталий

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    56
    Адрес:
    Москва
    Самомодификация на стеке/куче.

    Код (Text):
    1. // определяем размер самомодифицирующейся функции
    2. Idefine SELFSIZE  ((int) x_self_mod_end - (int) x_self_mod_code)
    3.  
    4. // начало самомодифицирующейся функции
    5. // спецификатор naked, поддерживаемый компилятором MS VC, указывает компилятору
    6. // на необходимость создания чистой ассемблерной функции, то есть такой функции.
    7. // куда компилятор не внедряет никакой посторонней отсебятины
    8.  
    9. __declspecC naked ) int x_selfjnod_code(int a. int b )
    10. {
    11. _asm
    12. {
    13. begin_sm:                                 ; начало самомодифицирующегося кода
    14. mov eax. [esp+4]                       ; получаем первый аргумент        >
    15. call get_eip                               ; определяем свое текущее положение в памяти
    16. get_eip:
    17. add eax, [esp + 8 + 4]                ; складываем/вычитаем из первого аргумента второй pop edx                                    ; в edx адрес начала инструкции add eax. ...
    18. хог byte ptr [edx],28h                 ; меняем add на sub и наоборот ret                                           ; возвращаемся в материнскую функцию
    19. }
    20.  
    21. } x_self_mod_end()
    22. {                   /* конец самомодифицирующейся функции */ }
    23. mainO
    24. {
    25. int a:
    26. int (__cdecl *se1f_mod_code)(int a. int b);
    27.  
    28. // раскомментируйте следующую строку, чтобы убедиться, что непосредственная
    29. // самомодификация под Windows невозможна (система выплюнет исключение)
    30. // self_rrod_code(4,2):
    31. // выделяем память из кучи (в куче модификация кода разрешена)
    32. // с таким же успехом мы могли бы выделить память из стека:
    33. // se1fjiiod_code[SELF_SIZE];
    34. self_mod_code = (int (_cdecl*)(int. int)) malloc(SELF_SIZE);
    35.  
    36. // копируем самомодифицирующийся код в стек/кучу
    37. memcpy(self_mod_code. x_self_mod_code, SELF_SIZE):
    38.  
    39. // вызываем самомодифицирующуюся процедуру 10 раз
    40. for (а - 1:а< 10;а++) printf("*02X ", self_mod_code(4.2)); printf("\n");
    41. }
     
  17. sxd

    sxd Виталий

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    56
    Адрес:
    Москва
    Или вот ещё...

    Код (Text):
    1. #define CRYPT_LEN ((int)crypt_end - (int)for_crypt)
    2.  
    3. // маркер начала
    4. mark_begin()
    5. {
    6. _asm _emit 'K' _asm _emit 'P' _asm _emit 'N' _asm _erait 'C'
    7. }
    8.  
    9. // зашифрованная функция
    10. for_crypt(int a. int b)
    11. {
    12. return a + b;
    13. }
    14.  
    15. crypt_end(){}
    16.  
    17. // маркер конца
    18. mark_end ()
    19. {
    20. _asm _emit 'K' _asm _emit '?' _asm _emit 'N' _asm _emit 'C'
    21. }
    22.  
    23. // расшифровщик
    24. crypt_it(unsigned char *p, int c)
    25. {
    26. int a;    
    27. for (a - 0; a < c; a++) *p++ *- 0x66;
    28. }
    29.  
    30. main()
    31. {
    32. // расшифровываем защитную функцию
    33. crypt_it((unsigned char*) for_crypt, CRYPT_LEN);
    34.  
    35. // вызываем защитную функцию
    36. printf ("%02Xh\n",forcrypt(0x69, 0x66));
    37.  
    38. // зашифровываем опять
    39. crypt_it((unsigned char*) for crypt, CRYPT_LEN);
    40. }
     
  18. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    sxd
    Не понимаю я по вашему :)
    символы ('К','P',...) какие-то получаются(выводятся) из входного(выходного) потока ?
    И с помощью них происходит шифровка/де-шифрование...А чего шифруют, и на выходе код или что ?
    Код (Text):
    1. {
    2. begin_sm:                                 ; начало самомодифицирующегося кода
    3. mov eax. [esp+4]                       ; получаем первый аргумент        >
    4. call get_eip                               ; определяем свое текущее положение в памяти
    5. get_eip:
    6. add eax, [esp + 8 + 4]                ; складываем/вычитаем из первого аргумента второй pop edx                                    ; в edx адрес начала инструкции add eax. ...
    7. хог byte ptr [edx],28h                 ; меняем add на sub и наоборот ret                                           ; возвращаемся в материнскую функцию
    8. }
    Складываем EAX с чем-то из стэка(адрес возврата ? )и... ничего про ЕDX нигде не написано....
    Т.е имеем специальным образом заполненные EAX(размер этой функции использующей хor-модифицирование ?) и некий байт, косвенно адресуемый через ЕDX...
    И что будет дальше ? Сорри :dntknw:
     
  19. Otebebe

    Otebebe New Member

    Публикаций:
    0
    Регистрация:
    3 апр 2006
    Сообщения:
    91
    ; "ленточный экзекьютор" ??? :)
    ; Программу можно представить как конгломерат подпрограмм.
    ;
    ; Например "программу"
    ; mov AX,4C00H
    ; mov BX,0EE00H
    ; можно представить в виде
    ; toAX proc
    ; mov AX,4C00H
    ; ret
    ; toAX endp
    ; toBX proc
    ; mov BX,0EE00H
    ; ret
    ; toBX endp
    ; main proc
    ; call toAX
    ; call toBX
    ; main endp
    ; Место возврата (для ret) можно подготовить предварительным push'ем в самой подпрограмме
    ; Тогда
    ; а) сам oп.код ret'a 0C3H можно использовать как маркер
    ; б) все подпрограммы выполнять в одном фиксированном месте
    ; Пусть данные и код лежат в виде:
    ; .......C3.............C3..C3......C3..... ("лента")
    ; доставляя такие куски(....C3) в сегмент кода и передавая на них управление
    ; получим программу.
    Код (Text):
    1. ;Хэлло Ворлд! TASM 2.0
    2. .286
    3. text   segment 'code'
    4. assume CS:text,DS:data
    5. main proc
    6. mov AX,data
    7. mov DS,AX
    8. cld
    9. xor SI,SI
    10. xor DI,DI
    11. PREPARE:
    12. lodsb
    13. mov byte ptr CS:[DI+0014H],AL
    14. inc DI
    15. cmp AL,0C3H
    16. jne PREPARE
    17. ;CS:0014H
    18. main endp
    19. text ends
    20. data segment
    21. DB 0EBH,0FH,48H,65H,6CH,6CH,6FH,20H,77H,6FH,72H,6CH,64H,21H,0DH,0AH,24H,1EH,0EH,1FH
    22. DB 0B8H,00H,09H,0BAH,16H,00H,0CDH,21H,1FH,68H,08H,00H,0C3H,0B8H,00H,4CH,0CDH,21H,0C3H
    23. data ends
    24. stack  segment  para stack 'STACK'
    25.        db  80H dup (?)
    26. stack  ends
    27.      end main
     
  20. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    Otebebe, только надо следить чтоб c3 не встретилась в какойто другой команде типа mov,eax,0c3h... идея веселоя, но толку мало. любую программу делят на подпрограммы, а то что ты их извращенно запускаешь. это не есть самомодифицирующийся код, это просто другой подход к использованию подпрограмм:)
    но в развитие данного я б сделал так:
    каждую подпрограмму разбиваем на кучу мелких подпрограмм.
    убераем повторяющиеся подпрограммы
    нумеруем их.
    строим таблицу для каждой подпрограммы, получится типа
    db 10,01,02,08
    где
    10: push ebp
    mov ebp,esp
    01,02: какието действия подпрограммы
    08: leave
    retn