TSR без использования прерываний DOS

Тема в разделе "WASM.ASSEMBLER", создана пользователем lukash, 16 сен 2006.

  1. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Как правильно сделать процедуру резидентной без использования прерываний ДОС, а только с помощью функций БИОСа?
    Нужно чтобы код, получивший управление из БИОСа, перехватил прерывание и оставил в памяти процедуру обработки.
    Можно ли сделать такое, если вручную записать процедуру в один из зарезервированных участков памяти БИОСом и затем на него ссылаться?
    Заранее благодарен.
     
  2. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Совсем-совсем ничего?
    Если Reserved for IBM(0040:0090-0040:00EF), то значит ли ето то, что тудо можно вносить изменения?
    Если нет, то подскажите в какой участок памяти не лезет ДОС И Винда, и чтоб гдето в начале был.
    Если, к примеру есть строка db, то как записать ее содержимое в память?
    Сейчас записываю так:

    mov ax,0040h
    mov es,ax
    mov di,0090h

    mov ax,9c50h ;pushf push ax
    mov es:[di],ax
    ........
     
  3. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    lukash
    Нет. (0040:0000-0040:00FF), Это не зарезервированная область. А область используемая БИОСом для хронения его переменных. И судя по Ральфу Брауну почти вся забита.

    Можешь разместить свой код по адрессу
    FFFF:0010-FFFF:FFFF
    Только учти надо разрешить линию A20. И еще в этом месте уже может кто-то сидеть.
     
  4. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Спасибо, сейчас попробую.
     
  5. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Открываю A20 так:

    in al, 92h
    and al, not 2
    out 92h, al

    и так:

    mov al, 0D1h
    out 64h, al
    mov al, 0DFh
    out 60h, al

    дальше кроме адресов все по старому, и опять виснем…
    Проверю правильность того, что я в память записываю
     
  6. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    А чем Вам не нравицца стандартный алгоритм "отрезания" памяти у boot-вирусов:

    Код (Text):
    1.         dec   word ptr ds:[0413h]
    2.         mov   ax,word ptr ds:[0413h]
    3.         shl   ax,6              ; Decrease DOS memory by 1 Kbyte(1024 Bytes)
    4.         mov   es,ax             ; es = segment of "hidden" memory
     
  7. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Chingachguk
    Спасибо за помощь, но можно немного подробнее о коде или может есть ссылка на эту тему?
    Зачем уменьшать на единицу ds:[0413h], и почему es будет равным shl ax,6?
    Если программа запускается не из под ДОСа, то разве ето будет работать?
     
  8. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    lukash

    Ну хотя бы в книге Коваля "Как написать компьютерный вирус" или как-то так... Да и практически любой материал на тему boot-вирусов.
     
  9. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Chingachguk

    Почитал Вашу статью про boot-вирус. Вроде как разобрался с приведенным Вами кодом. Подскажите, если не трудно, на какие моменты следует обратить особое внимание при написании антивируса для boot-вирусов. Извиняюсь за вопрос не по теме. Спасибо.
     
  10. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    lukash

    Так вроде бы это давно уже пройденная тема ;) Практически каждый антивирус давно имеет фичи на эту тему и книжек тоже много, Касперский там...

    Тут многое зависит от того, что считать boot-вирусом. Если мы примем, что он должен функционировать _независимо_ от OS, то он "имеет право" работать только с функциями BIOS или работать вручную с портами ввода-вывода. Обычно проверяют перехвачено ли int 13h. Однако не все так просто - есть к примеру идея перехвата int 76h (INT 76 C - IRQ14 - HARD DISK CONTROLLER OPERATION COMPLETE (AT and later)). Формально int 13h свободен, но при завершении записи на дискету срабатывает триггер. Красиво. К тому само детектирование перехвата - довольно зыбкая весчь - есть техники сплайсинга (внедрение в код самого обработчика переходника на тело вируса).

    Работа напрямую с портами сложнее, обычно так не делают - но был же PM Wanderer by P.Demenuk. Конечно, такой код не пойдет даже с обычным DOS-extender'ом, но сама идея.

    Также обычно boot-вирус ловят так же как и обычный - поиском в памяти. Та же идея что я привел - элементарно проверяется проверкой ячейки [413h]. Также были идеи многоступечатой инсталляции, когда вирус переносит далее свое тело отрезая у DOS кусок памяти в ее таблицах.

    Хотя учитывая современные разработки SMM написать прозрачного резидента под _любой_ осью - возможно не такая уж недостижимая задача,,,

    Словом, есть хорошая литература по этому поводу, все в одном посте никто не напишет :derisive:
     
  11. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Сделал все как посоветовали, и, по-моему, все должно работать. Но все почему-то зависает. Я думаю, что во время прыжка на старый обработчик, но никак не могу найти ошибку. Смещения процедуры int_09 смотрел в TD, и получается 010dh, но когда отлаживаю программу в том же TD, копирования начинается со смещения cs:[si + 010b], потому приходиться добавлять двойку: mov bl, byte ptr cs:[si + org_p+2]. Из-за чего это? И еще, в TD программа отлаживается без всяких зависаний.
    Код (Text):
    1. CSEG segment
    2. Assume cs:CSEG
    3.  
    4. org 100h
    5.  
    6. begin:
    7.  
    8. lea ax,main
    9. jmp ax
    10.  
    11. o_int dw ?
    12. s_int dw ?
    13. prg_lenght dw ?
    14. org_p dw ?
    15. ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    16.  
    17. int_09 proc far         ;процедура
    18.                             ;обработки int 09h                      
    19. pushf                      
    20. push ax
    21. push dx
    22. push di
    23. push es
    24. push ds
    25.  
    26. mov ax,0B800h
    27. mov es,ax
    28. mov di,10                 ;вывод "рожицы"  
    29.                               ;в видеобуфер
    30. mov ah,31
    31. mov al,1
    32. mov es:[di],ax
    33.  
    34. pop ds
    35. pop es
    36. pop di
    37. pop dx
    38. pop ax
    39. popf
    40.  
    41. jmp dword ptr cs:[o_int]    ;вызов старой процедуры
    42.                                     ;по моему виснет здесь
    43. int_09 ENDP
    44.  
    45. ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    46.  
    47. RES_END:
    48.  
    49. main:
    50.  
    51. push ax
    52. push bx
    53. push dx
    54. push es
    55.  
    56. mov ax,3509h
    57. int 21h
    58. mov o_int,bx
    59. mov s_int,es
    60.  
    61. ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    62.  
    63. push cs                
    64. pop ds          
    65.  
    66. mov org_p,010dh         ;смещение начала проц. обработки
    67. mov prg_lenght,20h      ;длина процедуры
    68.  
    69.  sub word ptr ds:[0413h],2        
    70.  mov ax,ds:[0413h]                    
    71.  mov cl,6                                                        
    72.  shl ax,cl              
    73.  mov es,ax              ;копирование процедуры в память                  
    74.  xor si,si                 ;начиная с es:0000
    75.  mov cx,prg_lenght      
    76.  
    77. prg_copy:
    78.                 mov bl, byte ptr cs:[si+org_p+2]              
    79.                 mov byte ptr es:[si],bl
    80.                 inc si                
    81. loop cs:prg_copy      
    82.  
    83. ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    84.  
    85. ;lea dx,int_09
    86. push es
    87. pop ds              ;процедура по адресу es:0000
    88. mov dx,0000h    
    89. mov ax,2509h
    90. int 21h
    91.  
    92. pop es
    93. pop dx
    94. pop bx
    95. pop ax
    96.  
    97. int 20h
    98.  
    99. ;LEA DX,RES_END
    100. ;INT 27H
    101.  
    102. CSEG ends
    103. end begin
    За часто возможно глупые вопросы просьба сильно не пинать, так как в 11 классе мы это не разбираем:)
     
  12. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Основная проблема вот в этой команде:

    jmp dword ptr cs:[o_int] ;вызов старой процедуры

    Я написал немного проще твой код:

    Код (Text):
    1. .286
    2. CSEG segment
    3. Assume cs:CSEG
    4.  
    5. org 100h
    6.  
    7. begin:
    8.  
    9. jmp short main
    10.  
    11. @@ResidentalCode:
    12.  
    13. ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    14.  
    15. int_09 proc far ; процедура обработки int 09h
    16.  
    17. pushf                      
    18. pusha
    19. push es
    20. push ds
    21.  
    22. push 0B800h
    23. pop  es
    24. mov ah,31
    25. ; mov al,1 ; Almost random symbol (incomming AL)
    26. mov es:[10],ax
    27.  
    28. pop ds
    29. pop es
    30. popa
    31. popf
    32.  
    33. db 0EAh ; jmp far
    34. o_int dw ?
    35. s_int dw ?
    36.  
    37. ; Attention! You use next command in other memory block,
    38. ; but offset ("o_int") is still the same.
    39. ; jmp dword ptr cs:[o_int]    ;вызов старой процедуры
    40. ;                                    ;по моему виснет здесь
    41.  
    42. int_09 ENDP
    43.  
    44. ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    45.  
    46. RES_END:
    47.  
    48. prg_lenght EQU RES_END - @@ResidentalCode
    49.  
    50. main:
    51.  
    52. mov ax,3509h
    53. int 21h
    54. mov o_int,bx
    55. mov s_int,es
    56.  
    57. ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    58.  
    59.  push 0
    60.  pop  es
    61.  sub  word ptr es:[0413h],2 ; beware - you have to use 0000:0413h!
    62.  mov  ax,es:[0413h]                    
    63.  mov  cl,6                                                        
    64.  shl  ax,cl              
    65.  mov  es,ax ; копирование процедуры в память начиная с es:0000
    66.  xor  si,si
    67.  mov  cx,prg_lenght      
    68.  
    69. prg_copy:
    70.                 mov  bl,byte ptr cs:@@ResidentalCode[si]              
    71.                 mov  byte ptr es:[si],bl
    72.                 inc  si                
    73. loop cs:prg_copy      
    74.  
    75. ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    76.  
    77. ;lea dx,int_09
    78. push es
    79. pop ds              ;процедура по адресу es:0000
    80. mov dx,0000h+(offset int_09 - offset @@ResidentalCode)
    81. mov ax,2509h
    82. int 21h
    83.  
    84. ;; @@Wait: jmp @@Wait
    85.  
    86.   ret
    87.  
    88. ;LEA DX,RES_END
    89. ;INT 27H
    90.  
    91. CSEG ends
    92. end begin
     
  13. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Chingachguk
    Огромное Вам спасибо! Во всем разобрался. Теперь все работает, и так, как этот код не должен содержать никаких прерываний ДОСа, я немного модифицировал его.
    Старый код сохранения старого вектора и установки нового вектора поменял на:

    Код (Text):
    1. cli
    2. mov ax,0h
    3. mov es,ax
    4. mov dx,es:[9h*4]
    5. mov bx,es:[9h*4+2]
    6. mov s_int,bx
    7. mov o_int,dx
    8. sti
    и соответственно:

    Код (Text):
    1. cli
    2. push es
    3. pop ds    
    4. mov ax,0h
    5. mov es,ax
    6. mov dx,0000h+(offset int_09 - offset @@ResidentalCode)
    7. mov es:[9h*4],dx
    8. mov es:[9h*4+2],ds
    9. sti
     
  14. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    lukash

    Не за что. Есть такое опасение что если выделять так себе кусок памяти ИЗ DOS УЖЕ, то это не будет работать (проверка - загрузить прогу которая по размеру может использовать всю память - затрет-не затрет). Т.е. есть подозрение что DOS читает это число ОДИН РАЗ ПРИ ИНСТАЛЛЯЦИИ, поэтому так можно делать только ДО DOS.
     
  15. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    С этим тоже разобрался. Так, например, при запуске программы из ДОС она сначала запускается нормально, а потом виснет при команде DIR например. Но так, как этот код будет запускаться до ДОС, то думаю никаких проблем возникнуть не должно.
     
  16. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Chingachguk
    Вот опять вопрос появился...
    Почему сразу после запуска из ПЗУ код корректно работает (обработчик получает управление), а после того как загрузится ДОС, в мой обработчик управление не передается. В книге Коваля "Как написать компьютерный вирус" эта проблема рассматривалась (int 16 вместо int 9), но 16 обработчик управления также не получает.
    Объясни пожалуйста.
     
  17. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    > а после того как загрузится ДОС

    Именно обычный DOS? Просто если это XP, то там понятно что вообще ничего не останется, если win98 - то там хитро.

    Нужно анализировать ... Кажется, в книге Коваля написано как "перепрыгнуть" с одного вектора на другой (допустим, ждешь на векторе int 8 пока DOS (или расширитель? Еще кто?) не переставит int 16h на себя?

    "Академическим" подходом был бы мониторинг вектора int 16h. Ты же научился делать DRx - точки останова? Можно попытаться:

    - Перехватить на себя int 16h;
    - Установить DRx на доступ к вектору int 16h (те к памяти в 0000:16h*4);
    - В обработчике исключения (int 1h) выводить адрес кода, который пытается модифицировать int 16h - также выводить байты (штук 8) кода, которые это делают.

    Так можно понять кто и почему так делает.

    Опять все же можно попытаться "сидеть" на нескольких векторах (допустим, int 10h & int 16h) и постоянно проверять - не переставил ли кто int 16h.

    По-моему, я где-то читал что какой-то вирус так и делал. После перестановки вектора анализируется где сидит новый обработчик - в досе или еще где.

    Возможно, это делает keyrus (русификатор) :derisive:
     
  18. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Chingachguk
    Интересно…
    Вот что пишет Коваль:

    Но этот способ не задействовали, потому что было непонятно, как определить момент подмены обработчика. А если этот момент находить с помощью DRx?
    Попробую сделать вот что:

    1.Перехватить int 16h;
    2.Установить DRx на доступ к вектору int 16h
    3.В обработчике int 1h каждый раз устанавливать свой обработчик int 16h

    Если это не будет работать, то буду использовать несколько векторов, чтоб отследить этот момент.

    А при загрузке DOS/Windows 98 DRx не трогает?
     
  19. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Он (Коваль) вроде бы писал, что перехват int 16h (из загрузочного кода) остается на всем "пути" загрузки win98 (или нет?), поэтому странно что у тебя его кто-то сносит. А DRx по идее никто не трогает, но вот обработчик int 1h при переходе в PM нужно будет тоже поддерживать ... это уже сложнее.
     
  20. lukash

    lukash New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2006
    Сообщения:
    142
    Сделал вторым способом. Но он не работает:dntknw:. Там 16h обработчик следит за 9h. По-моему, в 16h обработчике не правильно ставится 9h вектор. А как его правильно поставить?

    Тут небольшая ошибка – 16 вектор не изменяется, это я немного неправильно проверял.