0

我参加了名为'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 - 同一组的幸存者共享的内存段(见高级技术)。
  • SS - 幸存者个人堆栈的开始部分。
  • SP - 偏移 幸存者个人堆栈的开始。

此时游戏以回合开始,每一回合运行游戏引擎运行每个幸存者的下一条指令,直到游戏结束:在 200,000 回合之后,或者当一个幸存者留在竞技场时。幸存者在每一轮中的出场顺序是在游戏开始时随机确定的,在游戏中不会改变。

在以下情况下,幸存者将被取消资格:

  • 运行非法指令(例如:字节 060h,它不会翻译成任何汇编指令)。
  • 游戏引擎运行“不支持”指令(例如:“INT 021h”)。游戏引擎会阻止试图启动与操作系统或计算机硬件的直接通信的运行指令。尝试访问不在竞技场范围内的内存,也不在幸存者的“个人”堆栈范围内。
  • 攻击其他幸存者是通过在竞技场内存中写入有关他们的代码的信息来完成的(为了让他们执行上述三个动作之一),从而取消他们的资格。因此,早些时候,人们必须找到他们藏身的地方:)
4

2 回答 2

4

首先 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
于 2016-11-05T14:14:29.607 回答
0
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  
于 2018-12-11T19:32:34.967 回答