【问题标题】:Arrays in x86-64x86-64 中的数组
【发布时间】:2020-07-23 14:44:55
【问题描述】:

好的,我对这里发生的事情有一个不错的了解。我输入 6 个 char 字符,它假设等于 $0x3a,即 58。因此,数组遍历每个字符并使用 $0xf 执行 & ,即 15。然后我没有得到的是它在第 39 行所做的事情。例如,如果我输入 b 然后对其执行 & 0xf ,它变为 2,在 39 行之后, %ecx 变为 6,我不知道该计算是如何完成的。我认为第 39 行是 x + 4y,所以 %rsi + (%rdx * 4)。有人知道第 39 行到底发生了什么吗?

Dump of assembler code for function phase_5:
0x000055555555547d <+0>:     push   %rbx
0x000055555555547e <+1>:     mov    %rdi,%rbx
0x0000555555555481 <+4>:     callq  0x5555555556fe <string_length>
0x0000555555555486 <+9>:     cmp    $0x6,%eax
0x0000555555555489 <+12>:    jne    0x5555555554bc <phase_5+63>
0x000055555555548b <+14>:    mov    %rbx,%rax
0x000055555555548e <+17>:    lea    0x6(%rbx),%rdi
0x0000555555555492 <+21>:    mov    $0x0,%ecx
0x0000555555555497 <+26>:    lea    0x1622(%rip),%rsi        # 0x555555556ac0 <array.3416>
0x000055555555549e <+33>:    movzbl (%rax),%edx
0x00005555555554a1 <+36>:    and    $0xf,%edx
0x00005555555554a4 <+39>:    add    (%rsi,%rdx,4),%ecx
0x00005555555554a7 <+42>:    add    $0x1,%rax
0x00005555555554ab <+46>:    cmp    %rdi,%rax
0x00005555555554ae <+49>:    jne    0x55555555549e <phase_5+33>
0x00005555555554b0 <+51>:    cmp    $0x3a,%ecx
0x00005555555554b3 <+54>:    je     0x5555555554ba <phase_5+61>
0x00005555555554b5 <+56>:    callq  0x555555555a14 <explode_bomb>
0x00005555555554ba <+61>:    pop    %rbx
0x00005555555554bb <+62>:    retq
0x00005555555554bc <+63>:    callq  0x555555555a14 <explode_bomb>
0x00005555555554c1 <+68>:    jmp    0x55555555548b <phase_5+14>

【问题讨论】:

  • add (%rsi,%rdx,4),%ecx 在 AT&T 语法中的意思是 add ecx, [rsi+rdx*4] 在 Intel 语法中。这直接转化为类似 C 的语法 ecx += *(rsi+rdx*4);。这能让你更好地理解它吗?
  • 它仍然不符合我的计算。当我输入 bceijl 作为我的字符串时,只有当我觉得这个数字应该更大时,我才会得到 55?我需要 58
  • 是的,我们正在使用 gdb
  • 我想你忘记了rsi 指向array.3416,而且你似乎没有检查它的内容。
  • 更正确地说,它有一个索引(一维数组),有 16 个可能的索引值:0 .. 15。“与运算”取输入字符的最右边的十六进制数字(ASCII代码:@=0, A=1, B=2, ..., O=15, P=0, Q=1, ...)。然后它从数组中取出对应的值,并将所有 6 个数组值相加,每个密码字母一个。

标签: assembly x86-64 reverse-engineering


【解决方案1】:

数组“array.3416”包含 16 个 4 字节值。
您输入的字母(它们的正确十六进制数字)用作该数组中的索引。

索引可以有 16 个可能的索引值:0 .. 15.
第 36 行的 and 操作取输入字符的最右边的十六进制数字(ASCII 码 & 0xF: '@'=>0, 'A'=>1, 'B'=>2, ..., 'O'= >15,'P'=>0,'Q'=>1,...)。

然后它从数组中取出相应的值,并同时(在第 39 行)将所有 6 个数组值相加,每个密码字母循环一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    相关资源
    最近更新 更多