[英]Assembly - safe competition
我參加了名為“Code guru - Extreme”的比賽。在這個比賽中,8086 組合中有保險箱和鑰匙。保險箱和鑰匙有聯合數據段,你需要制作一個打破保險箱的鑰匙。 安全示例:
L:
mov ax, [1234]
cmp ax, 5678
jne L
打破保險箱的鑰匙示例
L:
mov ax, 5678
mov [1234], ax
jne L
現在我有了一個無法打破的保險箱
and al, 0FEh
push ax
clc
mul ax
xor ax, dx
or al, 1
loc_10A:
sub [0A2h], ax
pop ax
push ax
jnz loc_10A
這種保險箱和鑰匙的模擬是在Core Wars 8086 引擎內完成的。 規則如下,其中安全和鑰匙都是戰爭中的幸存者:
幸存者不能在固定地址上加載,因為游戲引擎每回合都會將它們加載到一個隨機地址。 生成的程序必須是 COM 而不是 EXE,並且只包含 8086 條指令。
每個幸存者收到一組自己的完整寄存器(寄存器),其他幸存者無法訪問。 此外,每個幸存者都有一個 2048 字節的“個人”堆棧,其他幸存者也無法訪問。
在運行第一輪游戲之前,游戲引擎將競技場中的所有字節初始化為值 0CCh(注意:此字節值是“不支持”的指令 - 詳情如下)。 然后引擎將每個幸存者加載到競技場內存中的隨機位置,即 - 完全按原樣復制幸存者文件的內容。 兩個幸存者之間的距離,以及幸存者與競技場邊緣的距離,保證至少為 1024 字節。 每個幸存者的代碼最多有 512 個字節。
在第一輪之前,游戲引擎將(每個幸存者的)寄存器初始化為以下值:
- BX、CX、DX、SI、DI、BP - 重置。
- 標志 - 重置。
- AX, IP - 初始幸存者的位置,游戲引擎將幸存者加載到的競技場中的隨機偏移量。
- CS, DS - 所有幸存者共有的競技場部分。
- ES - 一個段(segment),用於由同一組的幸存者共享的內存(參見高級技術)。
- SS - 幸存者個人堆棧的開始部分。
- SP - Offset 幸存者個人堆棧的開始。
此時游戲以回合開始,每回合運行游戲引擎,運行每個幸存者的下一條指令,直到游戲結束:200,000 回合后,或者當一個幸存者留在競技場時。 幸存者在每一輪的比賽順序是在游戲開始時隨機確定的,在游戲中不會改變。
在以下情況下,幸存者將被取消資格:
- 運行非法指令(例如:未轉換為任何匯編指令的字節 060h)。
- 由游戲引擎運行“不受支持”的指令(例如:“INT 021h”)。 游戲引擎會阻止運行指令,嘗試啟動與操作系統或計算機硬件的直接通信。 嘗試訪問不在競技場范圍內的內存,也不在幸存者的“個人”堆棧范圍內。
- 攻擊其他幸存者是通過在競技場內存中寫入關於他們的代碼的信息來完成的(為了讓他們執行上述三個動作之一),並因此取消他們的資格。 因此,早些時候,人們必須找到他們藏身的地方:)
首先AX是未知數,計算無意義但push ax;
. 稍后,從循環的第二遍開始,AX 被彈出但保持未知且不變,因此您需要捕捉 2 個“內存變量”值之間的差異,它將是 AX 值。 類似的東西:
mov cx, 0ah;
delay:
nop;
loop delay;
l2:
mov ax, [0A2h];
mov bx, [0A2h];
sub ax, bx
jz l2;
mov [0A2h], ax;
jmp l2
l:
mov bx, 0a2h
mov dx, 0xffff
mov word [bx], dx
nop
nop
mov ax, word [bx]
sub dx, ax
mov word [bx], dx
mov dx, 0xffff
jmp l
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.