─[CPU EXTENDER]─────────────────────────────────────────────────[UAZZ KLINGUN]─
описание cpu extender'а
Итак, что это такое и для чего он нужен. При написании сей приблуды было
поставлено несколько задач:
- Упростить написание некоторые частоупотребимых операций, используемых в
вирях (например чтение/запись файла, передвижение по нему и т.д.). Раньше
ведь как надо было? поместить handle в bx, ds:dx поставить на буфер и т.д.
С использованием Extender'a жизнь упрощается (звучит почти как реклама
Win95/98/00). Теперь можно в программе просто записать _read ax,4000,cs,si
(где в ax расположился handle, в cs:si указатель на код, и 4000 - р-р чи-
таемого блока. Точно такими же свойствами обладают и все остальные опера-
ции, поддерживаемые Extender`ом. Причем, почти все (за исключением одной)
операции работают в резидентных приложениях :).
- Затруднить работу дизасемблерам и эвристикам. Теперь в вире практически не
будут встречаться прямые вызовы многих операций. По листингу вообще зат-
руднительно будет понять смысл написанного. Эвристики скорее всего также
заткнуться (но не эмуляторы). Правда, счастье вечным не будет (пока у них
не появиться данный код).
- Затруднить работу отладчиков реального режима. Для этой цели проходят че-
рез вызов int 3h (что это такое, думаю, объяснять не надо :)). Правда,
всвязи с решением работать через это прерывание, у меня случился спор с
одним человеком на тему того, может ли то, что представлено ниже, назы-
ваться CPU Extender'ом. Он мотивировал это тем, что Extender должен дейс-
твовать через прерывание Invalid Opcode (т.е. через int 6h). Ну ладно, это
к делу не относится, но в принципе вы можете сами выбирать, на какой int
это дело повесить.
как все это должно работать?
Теперь краткое описание того, как все это работает (должно работать) Нача-
ло программы должно выглядеть примерно так:
include extend.asm
begin:
mov ax,2503h
push cs
pop ds
mov dx,offset int_03h ;Наименование процедуры обработки
int 21h
_init ;Для доступа к файловым опрациям
Ну вот и все, теперь можете использовать Extender на полную катушку. Для
того, чтобы его использовать, необходимо знать синтаксис вызова макросов. Для
тех, кому будет лень копаться в исходнике и кто хочет его просто использо-
вать, я привожу требуемую информацию. Замечание: все параметры (кроме imm)
передаются через регистры.
_random r16 ; Заносит случайное значение в указанный
; регистр (кроме ss и ip). Оччень
; интересный эффект даст _random cs :))
_move ss16,so16,ds16,do16,imm16 ; Перемещает блок размером imm16
; с места указанного в регистрах
; ss16:so16 на место ds16:do16
; Пример _move cs,dx,cs,si,100h
; С cs:di в cs:si
_set_vect imm8,s16,o16 ; Установить вектор номер imm8
; Процедура обработки в s16:o16
_get_vect imm8,r16,r16 ; Аналогично, только получить адрес
; обработчика
_open_file s16,o16,imm8,h16 ; Открытие файла, имя файла в s16:o16
; Режим доступа в imm8
; возвращает handle в h16 (при неудачном
; открытии handle=0
_close_file r16 ; Закрытие файла с указанным handlom
_seek h16,imm8,l16,h16,l16,h16; перемещение по файлу h16, режим
; перемещения (от начала, от конца, от
; текущей позиции) - imm8
; младшая:старшая части смещения,
; возвращаются также младшая:старшая
; части смещения
_read h16,imm16,s16,o16 ; Чтение из файла h16 imm16 байт в буфер
; s16:016
_write h16,imm16,s16,o16 ; Тоже самое, только запись
_disable_timer ; Запрещает прерывания от таймера
_enable_timer ; разрешает прерывания от таймера
_xor s16,o16,c16,imm16 ; Хорит код начиная с s16:o16 количеством
; с16 с ключом imm16
_init ; без параметров (использование см. пример)
Итак, описание приведено. В файле extend.asm содержится исходный код суб-
жа, в файле ext.asm - мааленький примерчик. Все остальное зависит от вас.
────[EXT.ASM]────────[START]───────────────────────────────────────────────────
c_seg segment public
assume cs:c_seg
include extend.asm
beg:
push cs
pop ds
mov dx,offset int_03h ;Обязательно произвести усановку 3-го инта
mov ax,2503h ;на процедуру int_03h
int 21h
_init
mov ax,1234h
mov bx,4321h
_random ax
_random bx
mov dx,offset txt
mov ah,9
int 21h
mov ax,dx
add ax,100h
_move cs,dx,cs,ax,len
mov dx,ax
mov ah,9
int 21h
mov ax,4c00h
int 21h
txt db 'Это просто тест',10,13,'$'
len equ $-offset txt
c_seg ends
end beg
────[EXT.ASM]────────[EOF]─────────────────────────────────────────────────────
────[EXTEND.ASM]─────[START]───────────────────────────────────────────────────
;CPU Extender (c)Uazz Klingun (по мотивам John Darland'a)
;Version 0.0.1
;For 16-bit registers only
.286
_ext macro
db 0cch,90h
;db 0cdh,60h,90h
endm
opEcs equ 18
opEax equ 14
opEbx equ 12
opEcx equ 10
opEdx equ 8
opEsi equ 6
opEdi equ 4
opEds equ 2
opEes equ 0
opRandom equ 01h ;_random r16
opMove equ 02h ;_move r16,r16,r16,r16,imm16
opSet_vect equ 03h ;_set_vect imm8,r16,r16
opGet_vect equ 04h ;_get_vect imm8,r16,r16
opOpen_file equ 05h ;_open_file r16,r16,r16
opClose_file equ 06h ;_close_file r16
opSeek equ 07h ;_seek r16,imm8,r16,r16,r16,r16
opRead equ 08h ;_read r16,imm16,r16,r16
opWrite equ 09h ;_write r16,imm16,r16,r16
opDis_timer equ 0ah ;_disable_timer
opEnb_timer equ 0bh ;_enable_timer
opXor equ 0ch ;_xor r16,r16,r16,imm16
opInit_21h equ 0fh ;_init
_reg macro r1
ifidn <r1>, <ax>
db opEax
endif
ifidn <r1>, <bx>
db opEbx
endif
ifidn <r1>, <cx>
db opEcx
endif
ifidn <r1>, <dx>
db opEdx
endif
ifidn <r1>, <si>
db opEsi
endif
ifidn <r1>, <di>
db opEdi
endif
ifidn <r1>, <ds>
db opEds
endif
ifidn <r1>, <es>
db opEes
endif
ifidn <r1>, <cs>
db opEcs
endif
endm
_random macro r16
_ext
db opRandom
_reg r16
endm
_move macro r1,r2,r3,r4,i1 ;ds:si,es:di,cx(imm16)
_ext
db opMove
_reg r1
_reg r2
_reg r3
_reg r4
dw i1
endm
_set_vect macro i1,r1,r2 ;Number of vector,seg,ofs
_ext
db opSet_vect
db i1
_reg r1 ;seg
_reg r2 ;ofs
endm
_get_vect macro i1,r1,r2
_ext
db opGet_vect
db i1
_reg r1
_reg r2
endm
_open_file macro r1,r2,i1,r3 ;ds:dx,imm8,bx ;Any registers in this content
_ext ; ^^^^ - mode
db opOpen_file
_reg r1
_reg r2
db i1
_reg r3
endm
_close_file macro r1 ;bx
_ext
db opClose_file
_reg r1
endm
_seek macro r1,i1,r2,r3,r4,r5 ;bx,al,dx(lo),cx(hi)
_ext ;return (lo) (hi)
db opSeek
_reg r1
db i1
_reg r2
_reg r3
_reg r4
_reg r5
endm
_read macro r1,i1,r2,r3 ;bx,count,ds:dx
_ext
db opRead
_reg r1
dw i1
_reg r2
_reg r3
endm
_write macro r1,i1,r2,r3
_ext
db opWrite ;bx,count,ds:dx
_reg r1
dw i1
_reg r2
_reg r3
endm
_disable_timer macro
_ext
db opDis_timer
endm
_enable_timer macro
_ext
db opEnb_timer
endm
_xor macro r1,r2,r3,i1 ;ds:si,cx,cheap
_ext
db opXor
_reg r1
_reg r2
_reg r3
dw i1
endm
_init macro
_ext
db opInit_21h
endm
_es equ 0
_ds equ 2
_di equ 4
_si equ 6
_dx equ 8
_cx equ 10
_bx equ 12
_ax equ 14
_ip equ 16
_cs equ 18
_flags equ 20
int_03h proc
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp
mov bp,sp
add bp,2
mov bx,ss:[bp+_cs]
mov es,bx
mov bx,ss:[bp+_ip]
cmp byte ptr es:[bx],90h
je @0
jmp Not_Our_Call
@0:
inc bx
inc bx ; bx теперь указывает на 1-й параметр
mov al,byte ptr es:[bx-1]
cmp al,opRandom
jne @1
call random
jmp @f
@1:
cmp al,opMove
jne @2
call move
jmp @f
@2:
cmp al,opSet_vect
jne @3
call set_vect
jmp @f
@3:
cmp al,opGet_vect
jne @4
call get_vect
jmp @f
@4:
cmp al,opOpen_file
jne @5
call open_file
jmp @f
@5:
cmp al,opClose_file
jne @6
call close_file
jmp @f
@6:
cmp al,opSeek
jne @7
call seek
jmp @f
@7:
cmp al,opRead
jne @8
call read
jmp @f
@8:
cmp al,opWrite
jne @9
call write
jmp @f
@9:
cmp al,opDis_timer
jne @a
call dis_timer
jmp @f
@a:
cmp al,opEnb_timer
jne @b
call enb_timer
jmp @f
@b:
cmp al,opXor
jne @e
call @xor
jmp @f
@e:
cmp al,opInit_21h
jne @f
call init
@f:
Not_Our_Call:
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
int_03h endp
__1 proc near ;В cx возвращает содержимое регистра
push ax
xor ax,ax
mov al,byte ptr es:[bx]
add bp,ax
mov cx,word ptr ss:[bp]
sub bp,ax
inc bx
pop ax
ret
__1 endp
__2 proc near ;На входе сx - число,которое необходимо записать
push ax
xor ax,ax
mov al,byte ptr es:[bx]
add bp,ax
mov word ptr ss:[bp],cx
sub bp,ax
inc bx
pop ax
ret
__2 endp
__3 proc near ;Вызов 21-го инта
push bp
sh1:
call $+3
pop bp
sub bp,3
pushf
call dword ptr cs:[bp][offset int_21h-offset sh1]
pop bp
ret
__3 endp
random proc near
in al,40h
xchg ah,al
in al,40h
mov dl,byte ptr es:[bx]
xor dh,dh
add bp,dx
mov word ptr ss:[bp],ax
sub bp,dx
add word ptr ss:[bp+_ip],1+2
ret
random endp
move proc near ;ds:si,es:di,cx(imm)
call __1
mov ds,cx
call __1
mov si,cx
call __1
mov es,cx
call __1
mov di,cx
mov cx,word ptr es:[bx]
rep movsb
add word ptr ss:[bp+_ip],6+2
ret
move endp
set_vect proc near ;imm8,ds:dx
xor ax,ax
mov ds,ax
mov dl,byte ptr es:[bx]
shl dl,2
mov si,dx
call __1
mov word ptr ds:[si+1],cx
call __1
mov word ptr ds:[si],cx
add word ptr ss:[bp+_ip],3+2
ret
set_vect endp
get_vect proc near ;imm8,ds:dx
xor ax,ax
mov ds,ax
mov dl,byte ptr es:[bx]
shl dl,2
mov si,dx
mov cx,word ptr ds:[si+1]
call __2
mov cx,word ptr ds:[si]
call __2
add word ptr ss:[bp+_ip],3+2
ret
get_vect endp
open_file proc near ;ds:dx,imm8,bx Только для _существующих_ файлов!
call __1 ;Перед вызовом _ЛЮБОЙ_ функции работы с файлом
mov ds,cx ;должна вызываться функция _init (один раз
call __1 ;на всю программу)
mov dx,cx
mov al,byte ptr es:[bx]
inc bx
mov ah,3dh
call __3
jnc ok1
xor bx,bx
ok1:
mov cx,bx
call __2
add word ptr ss:[bp+_ip],4+2
ret
open_file endp
close_file proc near
call __1
mov bx,cx
mov ah,3eh
call __3
add word ptr ss:[bp+_ip],1+2
ret
close_file endp
seek proc near ;bx,al,dx,cx,(lo),(hi)
call __1 ; ^^-imm (mode 00/01/02)
push cx
mov al,byte ptr es:[bx]
mov ah,42h
push ax
inc bx
call __1
push cx
call __1
pop dx
pop ax
pop bx
call __3
mov cx,ax
call __2
mov cx,dx
call __2
add word ptr ss:[bp+_ip],6+2
ret
seek endp
read proc near ;bx,count,ds:dx
call __1
mov ax,cx
mov cx,word ptr es:[bx]
inc bx
inc bx
push cx
call __1
mov ds,cx
call __1
mov dx,cx
pop cx
mov bx,ax
mov ah,3fh
call __3
add word ptr ss:[bp+_ip],5+2
ret
read endp
write proc near ;bx,count,ds:dx
call __1
mov ax,cx
mov cx,word ptr es:[bx]
inc bx
inc bx
push cx
call __1
mov ds,cx
call __1
mov dx,cx
pop cx
mov bx,ax
mov ah,40h
call __3
add word ptr ss:[bp+_ip],5+2
ret
write endp
dis_timer proc near
in al,21h
or al,1
out 21h,al
add word ptr ss:[bp+_ip],0+2
ret
dis_timer endp
enb_timer proc near
in al,21h
and al,0feh
out 21h,al
add word ptr ss:[bp+_ip],0+2
ret
enb_timer endp
@xor proc near ;ds:si,cx,cheap
call __1
mov ds,cx
call __1
mov si,cx
call __1
mov ax,word ptr es:[bx]
ag1:
xor word ptr ds:[si],ax
inc si
inc si
loop ag1
add word ptr ss:[bp+_ip],5+2
ret
@xor endp
init proc near
mov ax,3521h
int 21h
push bp
sh2:
call $+3
pop bp
sub bp,3
mov word ptr cs:[bp][offset int_21h-offset sh2],bx
mov word ptr cs:[bp][offset int_21h-offset sh2+2],es
pop bp
add word ptr ss:[bp+_ip],0+2
ret
init endp
int_21h dw ?
dw ?
────[EXTEND.ASM]─────[EOF]─────────────────────────────────────────────────────
(c) Uazz KlinGun, soldier of Misdirected Youth