CSAPP bomb lab3
Phase_3
0000000000400f43 <phase_3>:
// arg1=input
400f43: 48 83 ec 18 sub $0x18,%rsp
400f47: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx
400f4c: 48 8d 54 24 08 lea 0x8(%rsp),%rdx
400f51: be cf 25 40 00 mov $0x4025cf,%esi
400f56: b8 00 00 00 00 mov $0x0,%eax
400f5b: e8 90 fc ff ff callq 400bf0 <__isoc99_sscanf@plt>
400f60: 83 f8 01 cmp $0x1,%eax
400f63: 7f 05 jg 400f6a <phase_3+0x27>
400f65: e8 d0 04 00 00 callq 40143a <explode_bomb>
400f6a: 83 7c 24 08 07 cmpl $0x7.0x8(%rsp)
400f6f: 77 3c ja 400fad <phase_3+0x6a>
400f71: 8b 44 24 08 mov 0x8(%rsp),%eax
400f75: ff 24 c5 70 24 40 00 jmpq *0x402470(,%rax,8)
400f7c: b8 cf 00 00 00 mov $0xcf,%eax
400f81: eb 3b jmp 400fbe <phase_3+0x7b>
400f83: b8 c3 02 00 00 mov $0x2c3,%eax
400f88: eb 34 jmp 400fbe <phase_3+0x7b>
400f8a: b8 00 01 00 00 mov $0x100,%eax
400f8f: eb 2d jmp 400fbe <phase_3+0x7b>
400f91: b8 85 01 00 00 mov $0x185,%eax
400f96: eb 26 jmp 400fbe <phase_3+0x7b>
400f98: b8 ce 00 00 00 mov $0xce,%eax
400f9d: eb 1f jmp 400fbe <phase_3+0x7b>
400f9f: b8 aa 02 00 00 mov $0x2aa,%eax
400fa4: eb 18 jmp 400fbe <phase_3+0x7b>
400fa6: b8 47 01 00 00 mov $0x147,%eax
400fab: eb 11 jmp 400fbe <phase_3+0x7b>
400fad: e8 88 04 00 00 callq 40143a <explode_bomb>
400fb2: b8 00 00 00 00 mov $0x0,%eax
400fb7: eb 05 jmp 400fbe <phase_3+0x7b>
400fb9: b8 37 01 00 00 mov $0x137,%eax
400fbe: 3b 44 24 0c cmp 0xc(%rsp),%eax
400fc2: 74 05 je 400fc9 <phase_3+0x86>
400fc4: e8 71 04 00 00 callq 40143a <explode_bomb>
400fc9: 48 83 c4 18 add $0x18,%rsp
400fcd: c3 retq
Copy the code
inphase_3
Is also calledsscanf
The second argument, Rsi, is given before the call0x4025cf
GDB is usedx/1s 0x4025cf
To:"% d % d"
, indicating that the input is two ints.Then write the third and fourth parameters, RDX, RCX,rcx=rsp+0xc
.rdx=rsp+0x8
, RDX and RCX are actually an array, let:rdx<=>&a[0],rcx<=>&a[1]
Sscanf (char *input,”%d %d”,&a[0],&a[1]);
If the return value of sscanf is <=1, it explodes directly (make sure that the input is in the correct format first). If (a[0]<0 or a[0]>7); (Ensure 0 =< a[0] <=7)
This is followed by an important command:jmpq *0x402470(,%rax,8)
, because rax=a[0], it indicates to jump to the address (code) stored in address (0x402470+a[0]*8). X /8gx 0x402470This is a jump table indexed by RDX. The eight addresses written in the figure are all available in the phase_3 code segment. The index A [0] of the switch can be 0, 1, 2, 3, 4, 5, 6, 7 and default.
void phase_3(char *input)
{
int a[2];
if ( sscanf(input,"%d %d",&a[0],&a[1]) != 2)
bomb();
switch (a[0]) {case 0: goto 0x400f7c; break;
case 1: goto 0x400fb9; break;
case 2: goto 0x400f83; break;
case 3: goto 0x400f8a; break;
case 4: goto 0x400f91; break;
case 5: goto 0x400f98; break;
case 6: goto 0x400f9f; break;
case 7: goto 0x400fa6; break;
default: bomb(); }}Copy the code
Take a[0]=0 as an example, the actual code stored in 0x402470 corresponds to the actual code address of 400f7C:
400f7c: b8 cf 00 00 00 mov $0xcf,%eax
// eax=0xcf
400fbe: 3b 44 24 0c cmp 0xc(%rsp),%eax
400fc2: 74 05 je 400fc9 <phase_3+0x86>
// if (eax==a[1])-> successful! So a[1]=0xcf =
400fc4: e8 71 04 00 00 callq 40143a <explode_bomb>
400fc9: 48 83 c4 18 add $0x18,%rsp
// Similarly, a[0] can take 7 other numbers, which also have corresponding a[1] to make the level pass.
Copy the code
So one of the answers is: “0 207”