组装-安全竞争

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

safekey 的模拟是在 Core Wars 8086 engine. The rules 内部完成的,如下所示,其中 safekey 是 war:

中的幸存者

The survivors cannot place a load on fixed addresses, because the game engine loads them every turn to a random address. The programs that are generated must be COM and not EXEs and contain only 8086 instructions.

Each survivor receives a set of its own complete registers (registers), which is not accessible to the other survivors. In addition, each survivor has a "personal" stack of 2048 bytes, which is also inaccessible to the other survivors.

Before running the first round of the game, the game engine initializes all the bytes in the arena to the value 0CCh (note: this byte value is an "unsupported" instruction - details below). The engine then loads each survivor to a random location in the arena memory, ie - copies the contents of the survivor file exactly as it is. The distance between two survivors, as well as the distance between the survivor and the edge of the arena, is guaranteed to be at least 1024 bytes. The code for each survivor has a maximum of 512 bytes.

Before the first round, the game engine initializes the registers (of each survivor) to the following values:

  • BX, CX, DX, SI, DI, BP - Reset.
  • Flags - Reset.
  • AX, IP - The position of the initial survivor, the random offset in the arena to which the survivor is loaded by the game engine.
  • CS, DS - The segment of the arena common to all survivors.
  • ES - A segment (segment) for the memory shared by survivors of the same group (see Advanced Techniques ).
  • SS - Beginning section of the personal stack of the survivor.
  • SP - Offset The start of the personal stack of the survivor.

At this point the game begins in rounds, with each round running the game engine running the next instruction of each survivor, until the end of the game: after 200,000 rounds, or when a single survivor remains in the arena. The order in which the survivors will play in each round is determined at the beginning of the game at random, and does not change during it.

A survivor is disqualified in the following cases:

  • Running an illegal instruction (example: byte 060h that does not translate into any assembly instruction).
  • Running an "unsupported" instruction by the game engine (example: "INT 021h"). The game engine prevents running instructions that try to initiate direct communication with the operating system or computer hardware. Attempt to access memory that is not within the realm of the arena, and not within the realm of the "personal" stack of the survivor.
  • Attacking other survivors is done by writing information about their code in the arena memory (in order to get them to perform one of the above three actions), and consequently to disqualify them. Earlier, therefore, one has to find where they are hiding :)

首先AX未知,计算无意义但是push ax;。稍后,从循环的第 2 遍开始,AX 被弹出但仍然未知且不变,因此您需要捕获 2 "memory var" 值之间的差异,它将是 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