最后一部分的目标是要在反汇编代码中找到密码,然后在程序运行时输入它以解除炸弹。反汇编代码展示了一个名为“test”函数,它有一个长长的switch语句,取决于一个偏移量,使用这个偏移量对指针数组进行索引以选择正确的分支。每个分支都包含一些关于输入的条件和验证代码。最终我们需要找到一个入口点,其中包含输入密码后炸弹被解除的情况。
以下是汇编代码,在函数“phase_6”中的“test”是重点:
0x400f5d : mov 0x18(%rsp),%eax
0x400f61 : mov (%rax,%rdx,4),%eax
0x400f64 : add %eax,%ecx
0x400f66 : add $0x1,%edx
0x400f69 : cmp $0x5,%edx
0x400f6c : jle 0x400f5d
0x400f6e : cmp $0x37353530,%ecx
0x400f74 : je 0x400f7b
0x400f76 : callq 0x40143a
0x400f7b : add $0x28,%rsp
0x400f7f : retq
接下来,我们可以使用反汇编工具查看“test”函数中每个分支的条件并逐个验证它们,直到我们发现了正确的偏移量。
int test(int *a, int n) {
int i = 0, ret = 0; // i是偏移量,ret是密码
switch(n) {
case 0: ret = 0x24c6a7b1; break;
case 1: ret = 0x6ca91067; break;
case 2: ret = 0xda652d9; break;
case 3: ret = 0x4d810e8c; break;
case 4: ret = 0x139c4602; break;
case 5: ret = 0x3d4afeb4; break;
default: ret = 0xdeadbeef; break;
}
while (i < n) {
if (a[i] <= a[i + 1]) {
ret += a[i];
} else {
ret -= a[i];
}
i++;
}
return ret;
}
void phase_6() {
char *input = read_line();
int arr[6];
int i, num;
for (i = 0; i < 6; i++) {
if (sscanf(input, "%d", &num) <= 0) break;
arr[i] = num;
while