【问题标题】:Bomb lab phase 5 - 6 char string, movzbl load, and $0xf, %ecx, and index an array with that?Bomb lab phase 5 - 6 char string, movzbl load, and $0xf, %ecx, and index a array with that?
【发布时间】:2015-06-15 02:04:26
【问题描述】:

好的,这是非常受欢迎的炸弹实验室,我目前处于第 5 阶段,我只停留在两条线上。这是汇编代码:

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.

当我通过反编译器运行它时,这是一个准系统外观:

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)];

更具体地说是第一个。第二行 &s 第一行的值 15 这基本上给出了 ecx 的最后 4 位,但是将字符串(param1)与循环计数器(eax_1)相加有什么作用?这也是将字符串中的每个字符转换为数字的行吗?任何帮助将不胜感激!

【问题讨论】:

标签: assembly x86 reverse-engineering


【解决方案1】:

用循环计数器 (eax_1) 添加字符串 (param1) 有什么作用?

这只是数组索引。它为您提供适当字符的地址。 ecx = *(unsigned char*)(param1 + eax_1) 基本上就是ecx = param1[eax_1]

正如您所说,代码循环遍历所有 6 个字母,保留 ascii 代码的低 4 位,并使用它来索引硬编码的查找表。将从所述查找表中选择的值相加,这就是您的结果,它必须是 0x42

【讨论】:

  • 啊,我明白了,为什么当我运行“kkkkkk”时它给了我 30 而不是 66?如果我算了算,不应该只是 11 + 11 + 11... 6 次,因为 k 的二进制以 1011 结束,即 11。
  • 哦,等等,我想我误解了,你的意思是它们在 array.3142 中有自己的 ascii 代码,这意味着它们有自己的字母数值?
  • 除了在很长的时间内找到这些键之外,您能告诉我它们在汇编语言中存储表格的位置吗^.^
  • 嘿,我把它化解了!像往常一样感谢 Jester 的帮助,但您能否告诉我在汇编代码中的哪里可以找到他们的表格,以备将来通知。
  • 因为你有add 0x804a4a0(,%ecx,4),%edx,所以表格的地址是0x804a4a0,长度为16。所以你应该可以使用x/16 0x804a4a0打印它。
猜你喜欢
  • 2017-12-07
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
相关资源
最近更新 更多