炸弹实验室阶段 5 - 6 字符字符串、movzbl 加载和 $0xf、%ecx,并用它索引数组?
Bomb lab phase 5 - 6 char string, movzbl load, and $0xf, %ecx, and index an array with that?
好吧,这是非常受欢迎的炸弹实验室,我目前处于第 5 阶段,而且我只停留在两条线上。这是汇编代码:
Dump of assembler code for function phase_5:
0x08048e29 <+0>: push %ebx
0x08048e2a <+1>: sub [=10=]x18,%esp
0x08048e2d <+4>: mov 0x20(%esp),%ebx
0x08048e31 <+8>: mov %ebx,(%esp)
0x08048e34 <+11>: call 0x804908b <string_length>
0x08048e39 <+16>: cmp [=10=]x6,%eax
0x08048e3c <+19>: je 0x8048e43 <phase_5+26>
0x08048e3e <+21>: call 0x80493a5 <explode_bomb>
0x08048e43 <+26>: mov [=10=]x0,%edx
0x08048e48 <+31>: mov [=10=]x0,%eax
0x08048e4d <+36>: movzbl (%ebx,%eax,1),%ecx
0x08048e51 <+40>: and [=10=]xf,%ecx
0x08048e54 <+43>: add 0x804a4a0(,%ecx,4),%edx
0x08048e5b <+50>: add [=10=]x1,%eax
0x08048e5e <+53>: cmp [=10=]x6,%eax
0x08048e61 <+56>: jne 0x8048e4d <phase_5+36>
=> 0x08048e63 <+58>: cmp [=10=]x42,%edx
0x08048e66 <+61>: je 0x8048e6d <phase_5+68>
0x08048e68 <+63>: call 0x80493a5 <explode_bomb>
0x08048e6d <+68>: add [=10=]x18,%esp
0x08048e70 <+71>: pop %ebx
0x08048e71 <+72>: ret
---Type <return> to continue, or q <return> to quit---
End of assembler dump.
这是我通过反编译器 运行 时的准系统外观:
void phase_5(__size8 *param1) {
__size32 eax; // r24
int eax_1; // r24{48}
unsigned int ecx; // r25
__size32 edx; // r26
eax = string_length(param1);
if (eax != 6) {
explode_bomb();
}
edx = 0;
eax = 0;
do {
eax_1 = eax;
ecx = *(unsigned char*)(param1 + eax_1);
edx += array.3142[(ecx & 0xf)];
eax = eax_1 + 1;
} while (eax_1 + 1 != 6);
if (edx != 66) {
explode_bomb();
}
return;
}
所以这个阶段的大致概要是输入的字符串需要是6个字符,然后它会经过一个do while循环,在这个循环中它把字符串通过它的算法把它变成一个数字,然后比较它是否最后是66。我的问题是这两行是做什么的:
ecx = (unsigned char)(param1 + eax_1);
edx += array.3142[(ecx & 0xf)];
更具体地说是第一个。第二行将第一行的值设为 15,这实际上给出了 ecx 的最后 4 位,但是将字符串 (param1) 与循环计数器 (eax_1) 相加有什么作用?这也是将字符串中的每个字符转换为数字的行吗?任何帮助将不胜感激!
what does adding the string (param1) with the loop counter (eax_1) do?
那只是数组索引。它为您提供了适当字符的地址。 ecx = *(unsigned char*)(param1 + eax_1)
基本上是 ecx = param1[eax_1]
.
正如您所说,代码循环遍历所有 6 个字母,保留 ascii 代码的低 4 位并使用它来索引硬编码查找 table。从所述查找 table 中选择的值相加,这就是你的结果,必须是 0x42
.
好吧,这是非常受欢迎的炸弹实验室,我目前处于第 5 阶段,而且我只停留在两条线上。这是汇编代码:
Dump of assembler code for function phase_5:
0x08048e29 <+0>: push %ebx
0x08048e2a <+1>: sub [=10=]x18,%esp
0x08048e2d <+4>: mov 0x20(%esp),%ebx
0x08048e31 <+8>: mov %ebx,(%esp)
0x08048e34 <+11>: call 0x804908b <string_length>
0x08048e39 <+16>: cmp [=10=]x6,%eax
0x08048e3c <+19>: je 0x8048e43 <phase_5+26>
0x08048e3e <+21>: call 0x80493a5 <explode_bomb>
0x08048e43 <+26>: mov [=10=]x0,%edx
0x08048e48 <+31>: mov [=10=]x0,%eax
0x08048e4d <+36>: movzbl (%ebx,%eax,1),%ecx
0x08048e51 <+40>: and [=10=]xf,%ecx
0x08048e54 <+43>: add 0x804a4a0(,%ecx,4),%edx
0x08048e5b <+50>: add [=10=]x1,%eax
0x08048e5e <+53>: cmp [=10=]x6,%eax
0x08048e61 <+56>: jne 0x8048e4d <phase_5+36>
=> 0x08048e63 <+58>: cmp [=10=]x42,%edx
0x08048e66 <+61>: je 0x8048e6d <phase_5+68>
0x08048e68 <+63>: call 0x80493a5 <explode_bomb>
0x08048e6d <+68>: add [=10=]x18,%esp
0x08048e70 <+71>: pop %ebx
0x08048e71 <+72>: ret
---Type <return> to continue, or q <return> to quit---
End of assembler dump.
这是我通过反编译器 运行 时的准系统外观:
void phase_5(__size8 *param1) {
__size32 eax; // r24
int eax_1; // r24{48}
unsigned int ecx; // r25
__size32 edx; // r26
eax = string_length(param1);
if (eax != 6) {
explode_bomb();
}
edx = 0;
eax = 0;
do {
eax_1 = eax;
ecx = *(unsigned char*)(param1 + eax_1);
edx += array.3142[(ecx & 0xf)];
eax = eax_1 + 1;
} while (eax_1 + 1 != 6);
if (edx != 66) {
explode_bomb();
}
return;
}
所以这个阶段的大致概要是输入的字符串需要是6个字符,然后它会经过一个do while循环,在这个循环中它把字符串通过它的算法把它变成一个数字,然后比较它是否最后是66。我的问题是这两行是做什么的:
ecx = (unsigned char)(param1 + eax_1); edx += array.3142[(ecx & 0xf)];
更具体地说是第一个。第二行将第一行的值设为 15,这实际上给出了 ecx 的最后 4 位,但是将字符串 (param1) 与循环计数器 (eax_1) 相加有什么作用?这也是将字符串中的每个字符转换为数字的行吗?任何帮助将不胜感激!
what does adding the string (param1) with the loop counter (eax_1) do?
那只是数组索引。它为您提供了适当字符的地址。 ecx = *(unsigned char*)(param1 + eax_1)
基本上是 ecx = param1[eax_1]
.
正如您所说,代码循环遍历所有 6 个字母,保留 ascii 代码的低 4 位并使用它来索引硬编码查找 table。从所述查找 table 中选择的值相加,这就是你的结果,必须是 0x42
.