Assembly 轰炸实验室阶段5-6字符字符串、movzbl加载和$0xf、%ecx,并用它索引数组?
好的,这是一个非常受欢迎的炸弹实验室,我现在在第五阶段,我只停留在两条线上。以下是汇编代码:Assembly 轰炸实验室阶段5-6字符字符串、movzbl加载和$0xf、%ecx,并用它索引数组?,assembly,x86,reverse-engineering,Assembly,X86,Reverse Engineering,好的,这是一个非常受欢迎的炸弹实验室,我现在在第五阶段,我只停留在两条线上。以下是汇编代码: Dump of assembler code for function phase_5: 0x08048e29 <+0>: push %ebx 0x08048e2a <+1>: sub $0x18,%esp 0x08048e2d <+4>: mov 0x20(%esp),%ebx 0x08048e31 <+8>: m
Dump of assembler code for function phase_5:
0x08048e29 <+0>: push %ebx
0x08048e2a <+1>: sub $0x18,%esp
0x08048e2d <+4>: mov 0x20(%esp),%ebx
0x08048e31 <+8>: mov %ebx,(%esp)
0x08048e34 <+11>: call 0x804908b <string_length>
0x08048e39 <+16>: cmp $0x6,%eax
0x08048e3c <+19>: je 0x8048e43 <phase_5+26>
0x08048e3e <+21>: call 0x80493a5 <explode_bomb>
0x08048e43 <+26>: mov $0x0,%edx
0x08048e48 <+31>: mov $0x0,%eax
0x08048e4d <+36>: movzbl (%ebx,%eax,1),%ecx
0x08048e51 <+40>: and $0xf,%ecx
0x08048e54 <+43>: add 0x804a4a0(,%ecx,4),%edx
0x08048e5b <+50>: add $0x1,%eax
0x08048e5e <+53>: cmp $0x6,%eax
0x08048e61 <+56>: jne 0x8048e4d <phase_5+36>
=> 0x08048e63 <+58>: cmp $0x42,%edx
0x08048e66 <+61>: je 0x8048e6d <phase_5+68>
0x08048e68 <+63>: call 0x80493a5 <explode_bomb>
0x08048e6d <+68>: add $0x18,%esp
0x08048e70 <+71>: pop %ebx
0x08048e71 <+72>: ret
---Type <return> to continue, or q <return> to quit---
End of assembler dump.
这一阶段的大致内容是,字符串输入必须是6个字符,然后它通过一个do while循环,在这个循环中,它通过它的算法将字符串转换成一个数字,然后比较最后的66。我的问题是这两条线是做什么的:
ecx=(无符号字符)(param1+eax_1);
edx+=array.3142[(ecx&0xf)]
更具体地说是第一个。第二行&s第一行的值为15,这基本上给出了ecx的最后4位,但是将字符串(param1)与循环计数器(eax_1)相加做什么呢?这也是将字符串中的每个字符转换为数字的行吗?任何帮助都将不胜感激
将字符串(param1)与循环计数器(eax_1)相加做什么
这只是数组索引。它将为您提供相应字符的地址ecx=*(无符号字符*)(param1+eax_1)
基本上是ecx=param1[eax_1]
正如您所说,该代码在所有6个字母之间循环,保持ascii代码的低位4位,并使用该位索引硬编码的查找表。从所述查找表中选择的值被求和,这是您的结果,必须是
0x42
啊,我明白了,那么为什么当我运行“kkkk”时,它给我的是30而不是66?如果我算出来的话,是不是应该是11+11+11。。。自从k的二进制数以1011结尾(11)以来已经6次了。哦,等等,我想我误解了,你的意思是他们在数组中有自己的ascii码。3142,这意味着它们有自己的字母数值?除了长时间寻找这些键之外,你能告诉我它们在汇编语言中存储表的位置吗^^嘿,我把它拆了!像往常一样,谢谢Jester的帮助,但您能否告诉我在汇编代码中的何处可以找到他们的表以备将来注意。由于您已添加了0x804a4a0(,%ecx,4),%edx该表位于地址0x804a4a0
,长度为16。因此,您应该能够使用x/16 0x804a4a0
打印它。还有一个很好的描述,就是如何挑选字符串。
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;
}