计算机系统导论 Bomb Lab Phase 1~6 全解

ICS Bomb Lab——The Ultimate Companion

经验教训:

  • 不要尝试通过眼睛瞪来把结果瞪出来——不打草稿的话,难度太大了。
  • 不要瞎改内存地址来试图通过——不然会结算成爆炸。

提示:breakrundisassemblestepinexti

参考表:

  • b,w,l,q

  • jmp(页码+表格)

  • mov

    • movz
    • movs
  • 寄存器

解释:

  • callq
  • retq
  • push

main()

Dump of assembler code for function main:
   0x00000000000014c9 <+0>:	endbr64
   0x00000000000014cd <+4>:	push   %rbx
   0x00000000000014ce <+5>:	cmp    $0x1,%edi
   0x00000000000014d1 <+8>:	je     0x1524 <main+91>
   0x00000000000014d3 <+10>:	mov    %rsi,%rbx
   0x00000000000014d6 <+13>:	cmp    $0x2,%edi
   0x00000000000014d9 <+16>:	jne    0x1556 <main+141>
   0x00000000000014db <+18>:	mov    0x8(%rsi),%rdi
   0x00000000000014df <+22>:	lea    0x3250(%rip),%rsi        # 0x4736
   0x00000000000014e6 <+29>:	callq  0x1350 <fopen@plt>
   0x00000000000014eb <+34>:	mov    %rax,0x6f9e(%rip)        # 0x8490 <infile>
   0x00000000000014f2 <+41>:	test   %rax,%rax
   0x00000000000014f5 <+44>:	je     0x1534 <main+107>
   0x00000000000014f7 <+46>:	callq  0x1d3a <initialize_bomb>
   0x00000000000014fc <+51>:	mov    %rax,%rbx
   0x00000000000014ff <+54>:	cmpl   $0x2022fa11,(%rax)
   0x0000000000001505 <+60>:	je     0x1579 <main+176>
   0x0000000000001507 <+62>:	lea    0x2b7a(%rip),%rsi        # 0x4088
   0x000000000000150e <+69>:	mov    $0x1,%edi
   0x0000000000001513 <+74>:	mov    $0x0,%eax
   0x0000000000001518 <+79>:	callq  0x1340 <__printf_chk@plt>
   0x000000000000151d <+84>:	mov    $0x0,%eax
   0x0000000000001522 <+89>:	pop    %rbx
   0x0000000000001523 <+90>:	retq
   0x0000000000001524 <+91>:	mov    0x6f45(%rip),%rax        # 0x8470 <stdin@@GLIBC_2.2.5>
   0x000000000000152b <+98>:	mov    %rax,0x6f5e(%rip)        # 0x8490 <infile>
   0x0000000000001532 <+105>:	jmp    0x14f7 <main+46>
   0x0000000000001534 <+107>:	mov    0x8(%rbx),%rcx
   0x0000000000001538 <+111>:	mov    (%rbx),%rdx
   0x000000000000153b <+114>:	lea    0x2ac2(%rip),%rsi        # 0x4004
   0x0000000000001542 <+121>:	mov    $0x1,%edi
   0x0000000000001547 <+126>:	callq  0x1340 <__printf_chk@plt>
   0x000000000000154c <+131>:	mov    $0x8,%edi
   0x0000000000001551 <+136>:	callq  0x1370 <exit@plt>
   0x0000000000001556 <+141>:	mov    (%rsi),%rdx
   0x0000000000001559 <+144>:	lea    0x2ac1(%rip),%rsi        # 0x4021
   0x0000000000001560 <+151>:	mov    $0x1,%edi
   0x0000000000001565 <+156>:	mov    $0x0,%eax
   0x000000000000156a <+161>:	callq  0x1340 <__printf_chk@plt>
   0x000000000000156f <+166>:	mov    $0x8,%edi
   0x0000000000001574 <+171>:	callq  0x1370 <exit@plt>
   0x0000000000001579 <+176>:	lea    0x2b48(%rip),%rdi        # 0x40c8
   0x0000000000001580 <+183>:	callq  0x1260 <puts@plt>
   0x0000000000001585 <+188>:	lea    0x2b7c(%rip),%rdi        # 0x4108
   0x000000000000158c <+195>:	callq  0x1260 <puts@plt>
   0x0000000000001591 <+200>:	callq  0x21f3 <read_line>
   0x0000000000001596 <+205>:	mov    %rax,%rdi
   0x0000000000001599 <+208>:	callq  0x1778 <phase_1>
   0x000000000000159e <+213>:	mov    %rbx,%rdi
   0x00000000000015a1 <+216>:	callq  0x233e <phase_defused>
   0x00000000000015a6 <+221>:	lea    0x2b9b(%rip),%rdi        # 0x4148
   0x00000000000015ad <+228>:	callq  0x1260 <puts@plt>
   0x00000000000015b2 <+233>:	callq  0x21f3 <read_line>
   0x00000000000015b7 <+238>:	mov    %rax,%rdi
   0x00000000000015ba <+241>:	callq  0x179c <phase_2>
   0x00000000000015bf <+246>:	mov    %rbx,%rdi
   0x00000000000015c2 <+249>:	callq  0x233e <phase_defused>
   0x00000000000015c7 <+254>:	lea    0x2a6d(%rip),%rdi        # 0x403b
   0x00000000000015ce <+261>:	callq  0x1260 <puts@plt>
   0x00000000000015d3 <+266>:	callq  0x21f3 <read_line>
   0x00000000000015d8 <+271>:	mov    %rax,%rdi
   0x00000000000015db <+274>:	callq  0x180d <phase_3>
   0x00000000000015e0 <+279>:	mov    %rbx,%rdi
   0x00000000000015e3 <+282>:	callq  0x233e <phase_defused>
   0x00000000000015e8 <+287>:	lea    0x2a69(%rip),%rdi        # 0x4058
   0x00000000000015ef <+294>:	callq  0x1260 <puts@plt>
   0x00000000000015f4 <+299>:	callq  0x21f3 <read_line>
   0x00000000000015f9 <+304>:	mov    %rax,%rdi
   0x00000000000015fc <+307>:	callq  0x190a <phase_4>
   0x0000000000001601 <+312>:	mov    %rbx,%rdi
   0x0000000000001604 <+315>:	callq  0x233e <phase_defused>
   0x0000000000001609 <+320>:	lea    0x2b68(%rip),%rdi        # 0x4178
   0x0000000000001610 <+327>:	callq  0x1260 <puts@plt>
   0x0000000000001615 <+332>:	callq  0x21f3 <read_line>
   0x000000000000161a <+337>:	mov    %rax,%rdi
   0x000000000000161d <+340>:	callq  0x1988 <phase_5>
   0x0000000000001622 <+345>:	mov    %rbx,%rdi
   0x0000000000001625 <+348>:	callq  0x233e <phase_defused>
   0x000000000000162a <+353>:	lea    0x2a36(%rip),%rdi        # 0x4067
   0x0000000000001631 <+360>:	callq  0x1260 <puts@plt>
   0x0000000000001636 <+365>:	callq  0x21f3 <read_line>
   0x000000000000163b <+370>:	mov    %rax,%rdi
   0x000000000000163e <+373>:	callq  0x19d7 <phase_6>
   0x0000000000001643 <+378>:	mov    %rbx,%rdi
   0x0000000000001646 <+381>:	callq  0x233e <phase_defused>
   0x000000000000164b <+386>:	mov    %rbx,%rdi
   0x000000000000164e <+389>:	callq  0x1220 <free@plt>
   0x0000000000001653 <+394>:	jmpq   0x151d <main+84>
End of assembler dump.

Phase 1

void phase_1(char *s) {
  
}

Phase 2

void phase_2(char *s) {
  int a[6];
  read_six_numbers(s, a);
  if (a[0] != 1) explode_bomb();
  for (int i = 1; i <= 5; i++) {
    if (a[i] != 2*a[i-1]) explode_bomb();
  }
}
+4 +5 +9 +18 处理栈,放金丝雀值。
+23 %eax = 0
+25 +28 read_six_numbers(%rdi, %rsp)
+33 +37 若%rsp != 1,则跳到+46(炸)
+39 %ebx = 1

+44 跳到+61
+46 炸。

+51 跳到+39
+53 炸。
+58 %ebx++;

+61 若%ebx > 5,则跳到86
+64 jg 
+66 %rdx = %ebx;
+69 %eax = %rbx - 1;
+72 符号扩展 %rax
+74 %eax = *(%rsp + 4 * %rax);
+77 %eax *= 2;
+79 +82 if ( *(%rsp + 4 * %rdx) == %eax ) 跳到+58
+84 跳到+53(炸)。
+86 +91 +100 +102 验证金丝雀值,处理栈,返回。
+106 返回。
+4 +5 +9 +18 处理栈,放金丝雀值。
+23 %eax = 0
+25 +28 read_six_numbers(%rdi, a) // 把 %rsp 理解成 (int *)a。
+33 +37 若 *a != 1,则炸

for (int i = 1; i <= 5; i++) {
	if (a[i] != 2*a[i-1]) 炸;
}
for (int i = 1; i <= 5; i++) {
	if (a[i] != 2*a[i-1]) 炸;
}
0 1 3 6 10 15
i = 1
if (i > 5) break;

%rax = i
%rdx = i - 1
c = i
c += a[i-1]
if (c == a[i])

Phase 3

void phase_3(char *s) {
	int x, y, z;
	if (sscanf(s, "%d %d", &x, &y) <= 1) explode_bomb();
  switch (x) {
    case 0:
      z = 0xbc;
      break;
    case 1:
      z = 0x233;
      break;
    case 2:
      z = 0x159;
      break;
    case 3:
      z = 0x1b2;
      break;
    case 4:
      z = 0x282;
      break;
    case 5:
      z = 0x158;
      break;
    case 6:
      z = 0x17f;
      break;
    case 7:
      z = 0x222;
      break;
    default:
      explode_bomb();
  }
  if (z != y) explode_bomb();
}
Dump of assembler code for function phase_3:
   0x000000000000180d <+0>:	endbr64
   0x0000000000001811 <+4>:	sub    $0x18,%rsp
   0x0000000000001815 <+8>:	mov    %fs:0x28,%rax
   0x000000000000181e <+17>:	mov    %rax,0x8(%rsp)
   0x0000000000001823 <+22>:	xor    %eax,%eax
   %eax(返回值) = 0
   0x0000000000001825 <+24>:	lea    0x4(%rsp),%rcx
   %rcx(第四个参数) = %rsp(栈底地址) + 4
   0x000000000000182a <+29>:	mov    %rsp,%rdx
   %rdx(第三个参数) = %rsp(栈底地址)
   0x000000000000182d <+32>:	lea    0x2e64(%rip),%rsi        # 0x4698
   %rsi(第二个参数) = "%d %d"
   0x0000000000001834 <+39>:	callq  0x1330 <__isoc99_sscanf@plt>
   sscanf(%rdi, "%d %d", %rsp, %rsp + 4);
   0x0000000000001839 <+44>:	cmp    $0x1,%eax
   0x000000000000183c <+47>:	jle    0x1859 <phase_3+76>
   if (%rax <= 1) goto +76(炸);
   0x000000000000183e <+49>:	mov    (%rsp),%eax
   eax = *rsp;
   0x0000000000001841 <+52>:	cmp    $0x7,%eax
   0x0000000000001844 <+55>:	ja     0x18aa <phase_3+157>
   if ((unsigned)%eax > 7) goto +157(炸);
   这一步保证了 0 <= a <= 7
   0x0000000000001846 <+57>:	mov    %eax,%eax
   0x0000000000001848 <+59>:	lea    0x2ab1(%rip),%rdx        # 0x4300
   rdx = rip + 0x2ab1;
   0x000000000000184f <+66>:	movslq (%rdx,%rax,4),%rax
   // -10912	-10826	-10880	-10873  -10866	-10859	-10852	-10845
   rax = *(%rdx + 4*%rax) // a = d[a];
   0x0000000000001853 <+70>:	add    %rdx,%rax
   %rax += %rdx // a += d
   上面两条的意思是 a = d + d[a] 
   // 0x1860<+83> 0x18b6<+169> 0x1880<+115> 0x1887<+122> 0x188e<+129> 0x1895<+136> 0x189c<+153> 0x18a3<+150>
   0x0000000000001856 <+73>:	notrack jmpq *%rax
   0x0000000000001859 <+76>:	callq  0x20c0 <explode_bomb>
   0x000000000000185e <+81>:	jmp    0x183e <phase_3+49>
   case 0:
   0x0000000000001860 <+83>:	mov    $0xbc,%eax
     eax = 0xbc = 188;
   LABEL:
   0x0000000000001865 <+88>:	cmp    %eax,0x4(%rsp)
     if (eax != *(rsp + 4))
   0x0000000000001869 <+92>:	jne    0x18bd <phase_3+176>
   	   goto +176(爆炸);
   0x000000000000186b <+94>:	mov    0x8(%rsp),%rax
       rax = *(rsp + 8)
   0x0000000000001870 <+99>:	xor    %fs:0x28,%rax
   0x0000000000001879 <+108>:	jne    0x18c4 <phase_3+183>
   0x000000000000187b <+110>:	add    $0x18,%rsp
   0x000000000000187f <+114>:	retq
   case 2:
   0x0000000000001880 <+115>:	mov    $0x159,%eax
   0x0000000000001885 <+120>:	jmp    0x1865 <phase_3+88>
   case 3:
   0x0000000000001887 <+122>:	mov    $0x1b2,%eax
   0x000000000000188c <+127>:	jmp    0x1865 <phase_3+88>
   case 4:
   0x000000000000188e <+129>:	mov    $0x282,%eax
   0x0000000000001893 <+134>:	jmp    0x1865 <phase_3+88>
   case 5:
   0x0000000000001895 <+136>:	mov    $0x158,%eax
   0x000000000000189a <+141>:	jmp    0x1865 <phase_3+88>
   case 6:
   0x000000000000189c <+143>:	mov    $0x17f,%eax
   0x00000000000018a1 <+148>:	jmp    0x1865 <phase_3+88>
   case 7:
   0x00000000000018a3 <+150>:	mov    $0x222,%eax
   0x00000000000018a8 <+155>:	jmp    0x1865 <phase_3+88>
   0x00000000000018aa <+157>:	callq  0x20c0 <explode_bomb>
   0x00000000000018af <+162>:	mov    $0x0,%eax
   0x00000000000018b4 <+167>:	jmp    0x1865 <phase_3+88>
   case 1:
   0x00000000000018b6 <+169>:	mov    $0x233,%eax
   0x00000000000018bb <+174>:	jmp    0x1865 <phase_3+88>
   
   0x00000000000018bd <+176>:	callq  0x20c0 <explode_bomb>
   0x00000000000018c2 <+181>:	jmp    0x186b <phase_3+94>
   0x00000000000018c4 <+183>:	callq  0x1280 <__stack_chk_fail@plt>

Phase 4

func4

phase_4,知一定有esi == 0edx == 14

返回值为

|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|
|0|0|4|0|2|2|6|0|1|1| 5| 1| 3| 3| 7|
int func4(int i, int l, int r) {
	int m = (r - l) / 2 + l;
	if (i == m) return 0;
	if (i < m) return func4(i, l, m-1) * 2;
	if (i > m) return func4(i, m+1, r) * 2 + 1;
}
edx = 14; // r
esi = 0; // l
edi = *rsp;

func(i, l, r)

Dump of assembler code for function func4:
   0x00000000000018c9 <+0>:	endbr64
   0x00000000000018cd <+4>:	sub    $0x8,%rsp
   0x00000000000018d1 <+8>:	mov    %edx,%ecx
   ecx = edx(第三个参数); // l
   0x00000000000018d3 <+10>:	sub    %esi,%ecx
   ecx -= esi(第二个参数); // l - r
   0x00000000000018d5 <+12>:	mov    %ecx,%eax
   eax = ecx;
   0x00000000000018d7 <+14>:	shr    $0x1f,%eax
   eax >>= 31;
   0x00000000000018da <+17>:	add    %ecx,%eax
   eax += ecx;
   0x00000000000018dc <+19>:	sar    %eax
   eax >>= 1;
   以上语句相当于 eax = ecx / 2;(向零取整) // (l - r) / 2
   0x00000000000018de <+21>:	add    %esi,%eax
   eax += esi; // ()
   0x00000000000018e0 <+23>:	cmp    %edi,%eax
   0x00000000000018e2 <+25>:	jg     0x18f0 <func4+39>
   if (edi < eax) goto +39;
   0x00000000000018e4 <+27>:	jl     0x18fc <func4+51>
   if (edi > eax) goto +51;
   0x00000000000018e6 <+29>:	mov    $0x0,%eax
   0x00000000000018eb <+34>:	add    $0x8,%rsp
   0x00000000000018ef <+38>:	retq
   return 0;
   0x00000000000018f0 <+39>:	lea    -0x1(%rax),%edx
   edx = rax - 1;
   0x00000000000018f3 <+42>:	callq  0x18c9 <func4>
   func4()
   0x00000000000018f8 <+47>:	add    %eax,%eax
   eax += eax
   0x00000000000018fa <+49>:	jmp    0x18eb <func4+34>
   0x00000000000018fc <+51>:	lea    0x1(%rax),%esi
   esi = rax+1;
   0x00000000000018ff <+54>:	callq  0x18c9 <func4>
   0x0000000000001904 <+59>:	lea    0x1(%rax,%rax,1),%eax
   0x0000000000001908 <+63>:	jmp    0x18eb <func4+34>
End of assembler dump.

phase_4

void phase_4(char *s) {
	int x, y;
	if ((sscanf(s, "%d %d", &x, &y) != 2) || (x < 0) || (x > 14)) explode_bomb();
	if (func4(x, 0, 14) != 0 || y != 0) explode_bomb();
}
Dump of assembler code for function phase_4:
   0x000000000000190a <+0>:	endbr64
   0x000000000000190e <+4>:	sub    $0x18,%rsp
   0x0000000000001912 <+8>:	mov    %fs:0x28,%rax
   0x000000000000191b <+17>:	mov    %rax,0x8(%rsp)
   0x0000000000001920 <+22>:	xor    %eax,%eax
   eax = 0;
   0x0000000000001922 <+24>:	lea    0x4(%rsp),%rcx
   rcx = rsp+4;
   0x0000000000001927 <+29>:	mov    %rsp,%rdx
   rdx = rsp
   0x000000000000192a <+32>:	lea    0x2d67(%rip),%rsi        # 0x4698
   rsi = "%d %d"
   0x0000000000001931 <+39>:	callq  0x1330 <__isoc99_sscanf@plt>
   0x0000000000001936 <+44>:	cmp    $0x2,%eax
   0x0000000000001939 <+47>:	jne    0x1947 <phase_4+61>
   if (sscanf(rdi, "%d %d", rsp, rsp+4) != 2) explode_bomb();
   0x000000000000193b <+49>:	mov    (%rsp),%eax
   eax = *rsp; // b
   0x000000000000193e <+52>:	test   %eax,%eax
   0x0000000000001940 <+54>:	js     0x1947 <phase_4+61>
   if (eax < 0) explode_bomb();
   0x0000000000001942 <+56>:	cmp    $0xe,%eax
   0x0000000000001945 <+59>:	jle    0x194c <phase_4+66>
   0x0000000000001947 <+61>:	callq  0x20c0 <explode_bomb>
   if (eax > 14) explode_bomb();
   0x000000000000194c <+66>:	mov    $0xe,%edx
   edx = 14;
   0x0000000000001951 <+71>:	mov    $0x0,%esi
   esi = 0;
   0x0000000000001956 <+76>:	mov    (%rsp),%edi
   edi = *rsp; // b
   0x0000000000001959 <+79>:	callq  0x18c9 <func4>
   0x000000000000195e <+84>:	test   %eax,%eax
   0x0000000000001960 <+86>:	jne    0x1969 <phase_4+95>
   if (eax != 0) explode_bomb();
   0x0000000000001962 <+88>:	cmpl   $0x0,0x4(%rsp)
   0x0000000000001967 <+93>:	je     0x196e <phase_4+100>
   0x0000000000001969 <+95>:	callq  0x20c0 <explode_bomb>
   if (*(rsp + 4) != 0) explode_bomb();
   0x000000000000196e <+100>:	mov    0x8(%rsp),%rax
   0x0000000000001973 <+105>:	xor    %fs:0x28,%rax
   0x000000000000197c <+114>:	jne    0x1983 <phase_4+121>
   0x000000000000197e <+116>:	add    $0x18,%rsp
   0x0000000000001982 <+120>:	retq
   0x0000000000001983 <+121>:	callq  0x1280 <__stack_chk_fail@plt>
End of assembler dump.

Phase 4'

int func4(int n) {
	if (n == 0) return 0;
	if (n == 1) return 1;
	return 2*f(n-1) + f(n-2);
}
0 1 2 5 12 29

\[f_n = 2f_{n-1} + f_{n-2} \\ \]

+4 +5 +6 处理栈,略。
+10 %rax = 金丝雀值
+19 *(%rsp + 8) = %rax
+24 %eax = 0
+26 +31 +34 +41 sscanf(%rdi , "%d %d", %rsp, %rsp + 4); // n1 n2
+46 +49 +57 如果sscanf的返回值不为2就跳到+57,否则继续。
+51 (n1 == 5)就跳到+62,否则继续。
+57 炸了。
+62 %ebp = 0
+67 %ebx = 0

+72 +75 如果n1 == %ebx跳转到+91,否则继续。
+77 +79 +84 %ebp += func4(%ebx);
+86 %ebx ++;
+89 goto +72;

+91 +95 如果n2 != %ebp跳转到+120,否则继续。
+97 +102 +111 检测金丝雀值,略。
+113 +117 +118 处理栈。
+119 返回零。
+120 炸了。
5 20

Phase 5

const int a[16] = {2, 10, 6, 1, 12, 16, 9, 3, 4, 7, 14, 5, 11, 8, 15, 13};
void phase_5(char *s) {
  if (string_length(s) != 6) explode_bomb();
  int tmp = 0;
  for (int i = 0; i <= 5; ++i) {
    tmp += z[s[i]&15];
  }
  if (tmp != 0x38/*56*/) explode_bomb();
  // 56 = 10 + 10 + 10 + 10 + 10 + 6 "111112"
}
phase_5(char *s)

Dump of assembler code for function phase_5:
   0x0000000000001988 <+0>:	endbr64
   0x000000000000198c <+4>:	push   %rbx
   0x000000000000198d <+5>:	mov    %rdi,%rbx
   0x0000000000001990 <+8>:	callq  0x1cd1 <string_length>
   0x0000000000001995 <+13>:	cmp    $0x6,%eax
   0x0000000000001998 <+16>:	jne    0x19c2 <phase_5+58>
   if (string_length(s) != 6) explode_bomb();
   0x000000000000199a <+18>:	mov    $0x0,%ecx
   ecx = 0;
   0x000000000000199f <+23>:	mov    $0x0,%eax
   eax = 0;
   
   0x00000000000019a4 <+28>:	cmp    $0x5,%eax
   0x00000000000019a7 <+31>:	jg     0x19c9 <phase_5+65>
   if (eax > 5) goto +65;
   0x00000000000019a9 <+33>:	movslq %eax,%rdx
   0x00000000000019ac <+36>:	movzbl (%rbx,%rdx,1),%edx
   0x00000000000019b0 <+40>:	and    $0xf,%edx
   edx &= (*(eax+rbx))&15;
   0x00000000000019b3 <+43>:	lea    0x2966(%rip),%rsi        # 0x4320 <array.3497>
   // x/16dw 0x4320
   // 0x4320 <array.3497>: (int *){2, 10, 6, 1, 12, 16, 9, 3, 4, 7, 14, 5, 11, 8, 15, 13}
   0x00000000000019ba <+50>:	add    (%rsi,%rdx,4),%ecx
   ecx += <array.3497>[rdx]
   0x00000000000019bd <+53>:	add    $0x1,%eax
   eax += 1;
   0x00000000000019c0 <+56>:	jmp    0x19a4 <phase_5+28>
   goto +28;
   
   0x00000000000019c2 <+58>:	callq  0x20c0 <explode_bomb>
   0x00000000000019c7 <+63>:	jmp    0x199a <phase_5+18>
   
   0x00000000000019c9 <+65>:	cmp    $0x38,%ecx
   0x00000000000019cc <+68>:	jne    0x19d0 <phase_5+72>
   if (ecx != 0x38) explode_bomb();
   0x00000000000019ce <+70>:	pop    %rbx
   0x00000000000019cf <+71>:	retq
   0x00000000000019d0 <+72>:	callq  0x20c0 <explode_bomb>
   0x00000000000019d5 <+77>:	jmp    0x19ce <phase_5+70>
End of assembler dump.

Phase 6

void phase_6(char *s) {
  int a[6];
  read_six_numbers(s, a);
}
Dump of assembler code for function phase_6:
   0x00000000000019d7 <+0>:	endbr64
   0x00000000000019db <+4>:	push   %r12
   0x00000000000019dd <+6>:	push   %rbp
   0x00000000000019de <+7>:	push   %rbx
   0x00000000000019df <+8>:	sub    $0x60,%rsp
   0x00000000000019e3 <+12>:	mov    %fs:0x28,%rax
   0x00000000000019ec <+21>:	mov    %rax,0x58(%rsp)
   0x00000000000019f1 <+26>:	xor    %eax,%eax
   rax = 0;
   0x00000000000019f3 <+28>:	mov    %rsp,%rsi
   rsi = rsp;
   0x00000000000019f6 <+31>:	callq  0x21ae <read_six_numbers>
   read_six_numbers(s, rsi);
   0x00000000000019fb <+36>:	mov    $0x0,%ebp
   ebp = 0;
   0x0000000000001a00 <+41>:	jmp    0x1a29 <phase_6+82>
   
   0x0000000000001a02 <+43>:	callq  0x20c0 <explode_bomb>
   
   0x0000000000001a07 <+48>:	jmp    0x1a3c <phase_6+101>
   
   0x0000000000001a09 <+50>:	callq  0x20c0 <explode_bomb>
   
   0x0000000000001a0e <+55>:	add    $0x1,%ebx
   ebx += 1; // i
   
   0x0000000000001a11 <+58>:	cmp    $0x5,%ebx
   0x0000000000001a14 <+61>:	jg     0x1a26 <phase_6+79>
   if ((signed)ebx > 5) goto +79;
   0x0000000000001a16 <+63>:	movslq %ebp,%rax
   rax = ebp; // j
   0x0000000000001a19 <+66>:	movslq %ebx,%rdx
   rdx = ebx; // i
   0x0000000000001a1c <+69>:	mov    (%rsp,%rdx,4),%edi
   edi = ((int *)rsp)[rdx]; // a[i]
   0x0000000000001a1f <+72>:	cmp    %edi,(%rsp,%rax,4)
   0x0000000000001a22 <+75>:	jne    0x1a0e <phase_6+55>
   if (edi != ((int *)rsp)[rax]/*a[j]*/) goto +55;
   0x0000000000001a24 <+77>:	jmp    0x1a09 <phase_6+50>
   else explode_bomb();
   0x0000000000001a26 <+79>:	mov    %r12d,%ebp
   ebp = r12d;
   
   0x0000000000001a29 <+82>:	cmp    $0x5,%ebp
   0x0000000000001a2c <+85>:	jg     0x1a45 <phase_6+110>
   if (ebp > 5) goto +110;
   0x0000000000001a2e <+87>:	movslq %ebp,%rax
   eax = ebp;
   0x0000000000001a31 <+90>:	mov    (%rsp,%rax,4),%eax
   eax = ((int *)rsp)[rax];
   0x0000000000001a34 <+93>:	sub    $0x1,%eax
   eax -= 1;
   
   0x0000000000001a37 <+96>:	cmp    $0x5,%eax
   0x0000000000001a3a <+99>:	ja     0x1a02 <phase_6+43>
   if ((unsigned)eax > 5) explode_bomb();
   
   0x0000000000001a3c <+101>:	lea    0x1(%rbp),%r12d
   r12d = rbp + 1;
   0x0000000000001a40 <+105>:	mov    %r12d,%ebx
   ebx = r12d;
   0x0000000000001a43 <+108>:	jmp    0x1a11 <phase_6+58>
   goto +58;
   
   0x0000000000001a45 <+110>:	mov    $0x0,%eax
   eax = 0;
   
   0x0000000000001a4a <+115>:	jmp    0x1a5d <phase_6+134>
   0x0000000000001a4c <+117>:	movslq %eax,%rcx
   0x0000000000001a4f <+120>:	mov    $0x7,%edx
   0x0000000000001a54 <+125>:	sub    (%rsp,%rcx,4),%edx
   0x0000000000001a57 <+128>:	mov    %edx,(%rsp,%rcx,4)
   0x0000000000001a5a <+131>:	add    $0x1,%eax
   
   0x0000000000001a5d <+134>:	cmp    $0x5,%eax
   0x0000000000001a60 <+137>:	jle    0x1a4c <phase_6+117>
   0x0000000000001a62 <+139>:	mov    $0x0,%esi
   0x0000000000001a67 <+144>:	jmp    0x1a80 <phase_6+169>
   0x0000000000001a69 <+146>:	mov    0x8(%rdx),%rdx
   0x0000000000001a6d <+150>:	add    $0x1,%eax
   0x0000000000001a70 <+153>:	movslq %esi,%rcx
   0x0000000000001a73 <+156>:	cmp    %eax,(%rsp,%rcx,4)
   0x0000000000001a76 <+159>:	jg     0x1a69 <phase_6+146>
   0x0000000000001a78 <+161>:	mov    %rdx,0x20(%rsp,%rcx,8)
   0x0000000000001a7d <+166>:	add    $0x1,%esi
   
   0x0000000000001a80 <+169>:	cmp    $0x5,%esi
   0x0000000000001a83 <+172>:	jg     0x1a93 <phase_6+188>
   0x0000000000001a85 <+174>:	mov    $0x1,%eax
   0x0000000000001a8a <+179>:	lea    0x65bf(%rip),%rdx        # 0x8050 <node1>
   0x0000000000001a91 <+186>:	jmp    0x1a70 <phase_6+153>
   
   0x0000000000001a93 <+188>:	mov    0x20(%rsp),%rbx
   0x0000000000001a98 <+193>:	mov    %rbx,%rcx
   0x0000000000001a9b <+196>:	mov    $0x1,%eax
   0x0000000000001aa0 <+201>:	jmp    0x1ab4 <phase_6+221>
   0x0000000000001aa2 <+203>:	movslq %eax,%rdx
   0x0000000000001aa5 <+206>:	mov    0x20(%rsp,%rdx,8),%rdx
   0x0000000000001aaa <+211>:	mov    %rdx,0x8(%rcx)
   0x0000000000001aae <+215>:	add    $0x1,%eax
   0x0000000000001ab1 <+218>:	mov    %rdx,%rcx
   0x0000000000001ab4 <+221>:	cmp    $0x5,%eax
   0x0000000000001ab7 <+224>:	jle    0x1aa2 <phase_6+203>
   0x0000000000001ab9 <+226>:	movq   $0x0,0x8(%rcx)
   0x0000000000001ac1 <+234>:	mov    $0x0,%ebp
   0x0000000000001ac6 <+239>:	jmp    0x1acf <phase_6+248>
   0x0000000000001ac8 <+241>:	mov    0x8(%rbx),%rbx
   0x0000000000001acc <+245>:	add    $0x1,%ebp
   0x0000000000001acf <+248>:	cmp    $0x4,%ebp
   0x0000000000001ad2 <+251>:	jg     0x1ae5 <phase_6+270>
   0x0000000000001ad4 <+253>:	mov    0x8(%rbx),%rax
   0x0000000000001ad8 <+257>:	mov    (%rax),%eax
   0x0000000000001ada <+259>:	cmp    %eax,(%rbx)
   0x0000000000001adc <+261>:	jle    0x1ac8 <phase_6+241>
   0x0000000000001ade <+263>:	callq  0x20c0 <explode_bomb>
   0x0000000000001ae3 <+268>:	jmp    0x1ac8 <phase_6+241>
   0x0000000000001ae5 <+270>:	mov    0x58(%rsp),%rax
   0x0000000000001aea <+275>:	xor    %fs:0x28,%rax
   0x0000000000001af3 <+284>:	jne    0x1afe <phase_6+295>
   0x0000000000001af5 <+286>:	add    $0x60,%rsp
   0x0000000000001af9 <+290>:	pop    %rbx
   0x0000000000001afa <+291>:	pop    %rbp
   0x0000000000001afb <+292>:	pop    %r12
   0x0000000000001afd <+294>:	retq
   0x0000000000001afe <+295>:	callq  0x1280 <__stack_chk_fail@plt>
End of assembler dump.
void phase_6(char *s) {
  int a[6]; // a := rsp
  read_six_numbers(s, a);
  j = 0;
  goto L82;
L43:
  explode_bomb();
  goto L101;
L50:
  explode_bomb();
L55:
  i++; // i := ebx
L58:
  if (i > 5) goto L79;
  if (a[i] != a[j]) goto L55; // j := ebp
  else explode_bomb();
L79:
  j = k; // k := %r12d
L82:
  if (j > 5) goto L110;
  if (a[j]-1 > 5) goto L43; // explode_bomb();
  i = k = j+1;
  goto L58;
L110:
  eax = 0;
  goto L134;
L117:
  rcx = eax;
  edx = 7;
  edx -= a[rcx];
  a[rcx] = edx;
  eax++;
L134:
  if (eax <= 5) goto L117;
  esi = 0;
  goto L169;
L146:
  rdx = *(rdx+8);
  eax++;
L153:
  rcx = esi;
  if (a[rcx] > eax) goto L146; 
  *(rsp + 8*rcx + 20) = rdx;
  esi++;
L169:
  if (esi > 5) goto L188;
  eax = 1;
  rdx = 0x8050;
  goto L153;
L188:
  rbx = *(rsp + 20);
  rcx = rbx;
  eax = 1;
  goto L221;
L203:
  rdx = eax;
  rdx = *(rsp + 8*rdx + 20);
  *(rcx + 8) = rdx;
  eax++;
  rcx = rdx;
L221:
  if (eax <= 5) goto L203;
  *(rcx + 8) = 0;
  ebp = 0;
  goto L248;
L241:
  rbx = *(rbx + 8);
  ebp++;
L248:
  if (ebp > 4) goto L270;
  rax = *(rbx + 8);
  if ((*rbx) <= eax) goto L241;
L263:
  explode_bomb();
  goto L241;
L270:
  return;
}
struct node{
  int val, id;
  node * nxt;
}

int a[6]; // rsp
node *c[6]; // 0x20(%rsp)
for (int j/*ebp*/ = 0; j <= 5/*+82,+85*/; j++) {
  if (a[j] > 6 || a[j] <= 0) explode_bomb();
  // a[j] <- {1, 2, 3, 4, 5, 6}
  for (int i/*ebx*/ = j+1; i <= 5; ++i) {
    if (a[i] != a[j]) continue;
    else explode_bomb();
  }
}
  for (int i/*eax*/ = 0/*+110*/; i <= 5/*+134*/; ++i/*+131*/) {
    int j/*rcx*/ = i, k/*edx*/ = 7;
    a[j] = 7 - a[j]; // +120~+128
  }
  for (int i/*esi,+139*/ = 0; i <= 5/*+169*/; ++i) {
    for (int j/*eax*/ = 1, node *b/*rdx*/ = 0x8050/*+179*/; j < a[i]; j++) b = b->nxt;
    c[i] = b; // 换句话说,有c[i] = b + (a[i]-1);
  }
  node *i/*rbx*/ = c[0]; // +188
  node *j/*rcx*/ = i; // +193
  for (int k/*eax*/ = 1/*+196*/; k <= 5/*+221*/; ++k, j = l) { // 忽略第0个,也即第一个数此时应该是6,即原先为1。
    node *l = c[k];
    j->nxt = l; // +203~+218
    ++k;
  }
  j->nxt = 0; // +226
  for (int k/*ebp*/ = 0/*+234*/; k <= 4/*+248*/; i = *(i + 8), ++k/*245*/) {
  	if (i->val > i->nxt->val) explode_bomb(); // +263
    // 要求最后已经从小到大排好序了,顺序是node3, node2, node1, node4, node5
    // 也即此时的值是3, 6, 2, 1, 4, 5,也即原来是4, 1, 5, 6, 3, 2
  }
  // 答案应当是4, 1, 5, 6, 3, 2
// break *0x1a37
posted @ 2022-10-22 22:58  frank3215  阅读(699)  评论(0编辑  收藏  举报