80186 kode mesin + DOS, 91 byte
Versi teks:
hm j j PPjzjzjgaAAA JSJJ RU Sq ReAA JdJJJ RfiJElK JEiS GtI And she said But that s his
Versi teks, dengan tab (kode 9) diganti oleh 9
dan spasi (kode 32) diganti oleh *
:
hm9j9j9PPjzjzjgaAAA9JSJJ9RU9Sq9ReAA9JdJJJ9RfiJElK9JEiS*GtI*And*she*said***But*that*s*his***
Hexdump:
68 6D 09 6A 09 6A 09 50 50 6A 7A 6A 7A 6A 67 61
41 41 41 09 4A 53 4A 4A 09 52 55 09 53 71 09 52
65 41 41 09 4A 64 4A 4A 4A 09 52 66 69 4A 45 6C
4B 09 4A 45 69 53 20 47 74 49 20 41 6E 64 20 73
68 65 20 73 61 69 64 20 20 20 42 75 74 20 74 68
61 74 20 73 20 68 69 73 20 20 20
Kode mesin muncul dalam file dengan ekstensi .com
. Ketika saya menjalankannya, ia mencetak pesan yang diperlukan dan kemudian hang (mengeksekusi data acak).
Penjelasan tingkat tinggi tentang apa fungsinya:
- Menginisialisasi register dengan nilai konstan
- Mengganti spasi dalam pesan dengan simbol khusus yang diperlukan (
,'.$
)
- Menambal kode untuk menghasilkan
int 21
instruksi, yang mencetak pesan
- Panggilan DOS
Kode perakitan (dapat dikompilasi dengan tasm
):
my_bp equ 7ah
my_si equ 7ah
my_di equ 67h
my_msg equ 13bh
.model tiny
.code
.startup
.186
org 100h
push 96dh ; ax (ah = 0; al = don't care, but see below)
push 9 ; cx
push 9 ; dx
push ax ; bx = don't care
push ax ; don't care
push my_bp
push my_si
push my_di
popa
inc cx
inc cx
inc cx
or [bp+si+my_msg-my_bp-my_si+12], cx ; ,
dec dx
dec dx
or [bp+si+my_msg-my_bp-my_si+14], dx ; '
or [bp+di+my_msg-my_bp-my_di+23], dx ; '
or [bp+si+my_msg-my_bp-my_si+30], dx ; '
inc cx
inc cx
or [bp+si+my_msg-my_bp-my_si+29], cx ; .
dec dx
dec dx
dec dx
or [bp+si+my_msg-my_bp-my_si+31], dx ; $
; 0x2049 * 0x4b6c = 0x98301cc
; So this sets cx to 1cc (a temporary constant used to patch code)
imul cx, [bp+si+my_msg-my_bp-my_si-2], 4b6ch
; 0x1cc | 0x2049 = 0x21cd (the instruction which calls DOS int 21)
; Here ah = 9 ("print" mode)
or [bp+si+my_msg-my_bp-my_si-2], cx
; At address 101, there is the constant 96d, which was loaded into ax
; 0x96d * 0x7447 = 0x448013b
; So the following sets dx to 13b (adddress of the message)
imul dx, [bp+di+101h-my_bp-my_di], 7447h
int21:
dw 2049h
db 'And she said But that s his '
end
Ia menggunakan popa
instruksi untuk mem-popup semua register, karena reguler pop
tidak dapat mengisi semua register yang diperlukan (misalnya pop di
opcode terlarang).
Alamat byte yang akan ditambal berada dalam kisaran 0x100 ... 0x160. Untungnya, mereka dapat direpresentasikan sebagai jumlah 3 byte dengan nilai yang diizinkan:
- 0x7a dalam
bp
- 0x7a atau 0x67 dalam
si
ataudi
- Nilai segera
Penambalan byte dalam pesan berfungsi dengan melakukan logis OR
pada 0x20 (karakter spasi) dan konstanta kecil (4, 7, 12 atau 14). Konstanta kecil diperoleh dengan menginisialisasi cx
dan dx
ke 9 (karakter tab) dan melakukan INC
atau DEC
sesuai kebutuhan.
Menambal kode menggunakan IMUL
instruksi. Saya menemukan konstanta 16-bit yang diperlukan untuk berkembang biak menggunakan pencarian brute-force.
Akhirnya, alamat pesan (0x13b) diperoleh dengan perkalian. Untuk menghemat ruang, saya mengambil salah satu konstanta dari salah satu instruksi, yang berisi nilai langsung 0x96d
. Di sini 9
bagian memilih fungsi cetak DOS, dan 6d
bagian itu adalah parameter gratis. Ternyata itu 6d
adalah satu-satunya kemungkinan yang dapat memberikan 0x13b setelah perkalian.
Pembongkaran bagian kode:
06BA:0100 686D09 PUSH 096D
06BA:0103 6A09 PUSH +09
06BA:0105 6A09 PUSH +09
06BA:0107 50 PUSH AX
06BA:0108 50 PUSH AX
06BA:0109 6A7A PUSH +7A
06BA:010B 6A7A PUSH +7A
06BA:010D 6A67 PUSH +67
06BA:010F 61 POPA
06BA:0110 41 INC CX
06BA:0111 41 INC CX
06BA:0112 41 INC CX
06BA:0113 094A53 OR [BP+SI+53],CX
06BA:0116 4A DEC DX
06BA:0117 4A DEC DX
06BA:0118 095255 OR [BP+SI+55],DX
06BA:011B 095371 OR [BP+DI+71],DX
06BA:011E 095265 OR [BP+SI+65],DX
06BA:0121 41 INC CX
06BA:0122 41 INC CX
06BA:0123 094A64 OR [BP+SI+64],CX
06BA:0126 4A DEC DX
06BA:0127 4A DEC DX
06BA:0128 4A DEC DX
06BA:0129 095266 OR [BP+SI+66],DX
06BA:012C 694A456C4B IMUL CX,[BP+SI+45],4B6C
06BA:0131 094A45 OR [BP+SI+45],CX
06BA:0134 6953204774 IMUL DX,[BP+DI+20],7447
06BA:0139 CD21 INT 21 (after the code patches itself)
Fakta menyenangkan: Biasanya, saya akan menggunakan offset message
alih-alih kode-keras 13bh
, tetapi dalam kasus ini, karena pada saat penguraian alamatnya tidak diketahui, tasm menghasilkan offset langsung 16-bit, membuang 1 byte kode:
06BA:0131 098A4600 OR [BP+SI+0046],CX