Mã máy 80186 + DOS, 91 byte
Phiên bản văn bản:
hm j j PPjzjzjgaAAA JSJJ RU Sq ReAA JdJJJ RfiJElK JEiS GtI And she said But that s his
Phiên bản văn bản, với các tab (mã 9) được thay thế bằng 9
và khoảng trắng (mã 32) được thay thế bằng *
:
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
Mã máy xuất hiện trong một tệp có phần mở rộng .com
. Khi tôi chạy nó, nó sẽ in thông báo cần thiết và sau đó bị treo (thực thi dữ liệu ngẫu nhiên).
Giải thích cấp cao về những gì nó làm:
- Khởi tạo các thanh ghi với các giá trị không đổi
- Thay thế khoảng trắng trong tin nhắn bằng các ký hiệu đặc biệt cần thiết (
,'.$
)
- Vá mã để tạo
int 21
hướng dẫn, in thông báo
- Gọi cho DOS
Mã hội (có thể được biên dịch với 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
Nó sử dụng popa
hướng dẫn để bật tất cả các thanh ghi, bởi vì thông thường pop
không thể điền vào tất cả các thanh ghi cần thiết (ví dụ như pop di
một opcode bị cấm).
Địa chỉ của các byte cần vá nằm trong phạm vi 0x100 ... 0x160. May mắn thay, chúng có thể được biểu diễn dưới dạng tổng của 3 byte với các giá trị được phép:
- 0x7a trong
bp
- 0x7a hoặc 0x67 trong
si
hoặcdi
- Giá trị trước mắt
Việc vá các byte trong thông điệp hoạt động bằng cách thực hiện logic OR
trên 0x20 (ký tự khoảng trắng) và một hằng số nhỏ (4, 7, 12 hoặc 14). Hằng số nhỏ có được bằng cách khởi tạo cx
và dx
đến 9 (ký tự tab) và thực hiện INC
hoặc DEC
khi cần thiết.
Vá mã sử dụng IMUL
hướng dẫn. Tôi tìm thấy các hằng số 16 bit cần thiết để nhân lên bằng cách sử dụng tìm kiếm brute-force.
Cuối cùng, địa chỉ của tin nhắn (0x13b) có được bằng cách nhân. Để tiết kiệm không gian, tôi lấy một trong các hằng số từ một trong các hướng dẫn, trong đó có giá trị ngay lập tức 0x96d
. Ở đây 9
phần chọn chức năng in DOS và 6d
phần này là tham số miễn phí. Hóa ra đó 6d
là khả năng duy nhất có thể cho 0x13b sau khi nhân.
Tháo gỡ phần mã:
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)
Sự thật thú vị: Thông thường, tôi sẽ sử dụng offset message
thay vì mã hóa cứng 13bh
, nhưng trong trường hợp này, vì tại thời điểm phân tích địa chỉ của nó không xác định, tasm tạo ra bù 16 bit ngay lập tức, lãng phí 1 byte mã:
06BA:0131 098A4600 OR [BP+SI+0046],CX