Skip to main content

Bomb Lab: Phase 5

Course WorkBomb LabComputer Organization and ArchitectureAbout 1 minAbout 415 words

Assembly

00000000004015fc <phase_5>:
b0:
  4015fc:	53                   	push   %rbx
  4015fd:	48 89 fb             	mov    %rdi,%rbx
  401600:	e8 71 02 00 00       	callq  401876 <string_length>
  401605:	83 f8 06             	cmp    $0x6,%eax
  401608:	74 05                	je     40160f <phase_5+0x13>
  40160a:	e8 4d 05 00 00       	callq  401b5c <explode_bomb>
b1:
  40160f:	b8 00 00 00 00       	mov    $0x0,%eax
  401614:	ba 00 00 00 00       	mov    $0x0,%edx
b2:
  401619:	0f b6 34 03          	movzbl (%rbx,%rax,1),%esi
  40161d:	83 e6 0f             	and    $0xf,%esi
  401620:	48 8d 0d b9 1b 00 00 	lea    0x1bb9(%rip),%rcx        # 4031e0 <array.3354>
  401627:	03 14 b1             	add    (%rcx,%rsi,4),%edx
  40162a:	48 83 c0 01          	add    $0x1,%rax
  40162e:	48 83 f8 06          	cmp    $0x6,%rax
  401632:	75 e5                	jne    401619 <phase_5+0x1d>
  401634:	83 fa 40             	cmp    $0x40,%edx
  401637:	74 05                	je     40163e <phase_5+0x42>
  401639:	e8 1e 05 00 00       	callq  401b5c <explode_bomb>
b3:
  40163e:	5b                   	pop    %rbx
  40163f:	90                   	nop
  401640:	c3                   	retq

翻译为 C

void phase_5(char* rdi) {
b0:
  rbx = rdi;
  rax = string_length(rdi);
  if (rax == 6)  // 32-bit
    goto b1;
  explode_bomb();
b1:
  rax = 0;  // 32-bit
  rdx = 0;  // 32-bit
b2:
  rsi = *(rbx + rax);       // 32-bit
  rsi &= 0xf;               // 32-bit
  rcx = 0x4031e0;           // 4031e0 <array.3354>
  rdx += *(rcx + rsi * 4);  // 32-bit
  ++rax;
  if (rax != 0x6) goto b2;
  if (rdx == 0x40) goto b3;
  explode_bomb();
b3:
  return;
}

Hack

(gdb) x/16xw 0x4031e0
0x4031e0 <array.3354>:  0x00000002      0x0000000a      0x00000006      0x00000001
0x4031f0 <array.3354+16>:       0x0000000c      0x00000010      0x00000009      0x00000003
0x403200 <array.3354+32>:       0x00000004      0x00000007      0x0000000e      0x00000005
0x403210 <array.3354+48>:       0x0000000b      0x00000008      0x0000000f      0x0000000d

Optimize

void phase_5(char* rdi) {
  if (string_length(rdi) != 6) explode_bomb();
  int rdx = 0;
  for (int rax = 0; rax != 6; ++rax) {
    int rsi = rdi[rax] & 0xf;
    int* rcx = {
        0x00000002, 0x0000000a, 0x00000006, 0x00000001, 0x0000000c, 0x00000010,
        0x00000009, 0x00000003, 0x00000004, 0x00000007, 0x0000000e, 0x00000005,
        0x0000000b, 0x00000008, 0x0000000f, 0x0000000d,
    };
    rdx += rcx[rsi];
  }
  if (rdx != 0x40) explode_bomb();
  return;
}

Solution

构造长度为 6 的字符串, 使得最终 rdx == 0x40 即可. 例如

0x40 = 64 = 10 + 10 + 11 + 11 + 11 + 11

rdi 应满足

(rdi[0, 1] & 0xf) == 1
(rdi[2, 3, 4, 5] & 0xf) == 12

也即

(rdi[0, 1] % 16) == 1
(rdi[2, 3, 4, 5] % 16) == 12

不妨取

rdi[0, 1] = 'a' = 97
rdi[2, 3, 4, 5] = 'l' = 108

得到

aallll