处理数组和 for 循环的汇编代码,以及如何解码 map 函数
Assembly code that deals with arrays and for-loops, and how to decode a map function
这是我的汇编代码:
0x000000000040114b <+0>: push %rbx
0x000000000040114c <+1>: mov %rdi,%rbx
0x000000000040114f <+4>: callq 0x4013ab <string_length>
0x0000000000401154 <+9>: cmp [=10=]x6,%eax //expecting 6 characters
0x0000000000401157 <+12>: je 0x40115e <phase_5+19>
0x0000000000401159 <+14>: callq 0x4016a5 <explode_bomb>
0x000000000040115e <+19>: mov [=10=]x0,%eax
0x0000000000401163 <+24>: mov [=10=]x0,%edx
0x0000000000401168 <+29>: movzbl (%rbx,%rax,1),%ecx
0x000000000040116c <+33>: and [=10=]xf,%ecx
0x000000000040116f <+36>: add 0x402740(,%rcx,4),%edx
0x0000000000401176 <+43>: add [=10=]x1,%rax
0x000000000040117a <+47>: cmp [=10=]x6,%rax
0x000000000040117e <+51>: jne 0x401168 <phase_5+29>
0x0000000000401180 <+53>: cmp [=10=]x3d,%edx // 0x3d = 61
0x0000000000401183 <+56>: je 0x40118a <phase_5+63>
0x0000000000401185 <+58>: callq 0x4016a5 <explode_bomb>
0x000000000040118a <+63>: pop %rbx
0x000000000040118b <+64>: retq
第 <+36> 行是以下数组 table
0x402740 <array.3456>: 2 10 6 1
0x402750 <array.3456+16>: 12 16 9 3
0x402760 <array.3456+32>: 4 7 14 5
0x402770 <array.3456+48>: 11 8 15 13
在线 <+53> 我看到只要 %edx = 61
我就可以避开炸弹
我明白我需要数组table中的六个整数相加到61。例如2+9+10+15+14+11 = 61
我知道如何找到值的地址。例如:
x/w 0x402740 = 2
x/w 0x402744 = 10
等等
我想不通的是如何确定将字符 'q' 和 "map" 转换为所需值(例如 10)的函数。
实际上,我可能需要反向映射我需要的 6 个值。就像找到值 10 的映射。
如有任何建议,我们将不胜感激!
更新:
** 我认为汇编代码是这样的**
void function(char *str)
{
const uint32_t *table = 0x402740;
if (strlen(str) == 6)
{
uint32_t j = 0;
for (int i = 0; i < 6; i++)
j += table[str[i]];
if (j == 0x3d)
return;
}
call explode_bomb;
}
我认为关键部分是如何处理字符串中的每个字符:
and [=10=]xf,%ecx
0x000000000040116f <+36>: add 0x402740(,%rcx,4),%edx
这看起来像 table[str[i] & 0xF]
,其中 0xF 部分与您的 C 解释不同。
所以是每个字符的 低 4 位 定义了使用哪个索引。这为您提供了多个可能的字符以供使用,因为多个字符将共享相同的低位。所以拿你的2+9+10+15+14+11的解,算出它们对应的索引是什么,每个索引可以选择什么字符。
例如 9 在 table[6] 是似乎,所以你可以使用 F
是 0x46 或 V
是 0x56,在 ASCII 中。
这是我的汇编代码:
0x000000000040114b <+0>: push %rbx
0x000000000040114c <+1>: mov %rdi,%rbx
0x000000000040114f <+4>: callq 0x4013ab <string_length>
0x0000000000401154 <+9>: cmp [=10=]x6,%eax //expecting 6 characters
0x0000000000401157 <+12>: je 0x40115e <phase_5+19>
0x0000000000401159 <+14>: callq 0x4016a5 <explode_bomb>
0x000000000040115e <+19>: mov [=10=]x0,%eax
0x0000000000401163 <+24>: mov [=10=]x0,%edx
0x0000000000401168 <+29>: movzbl (%rbx,%rax,1),%ecx
0x000000000040116c <+33>: and [=10=]xf,%ecx
0x000000000040116f <+36>: add 0x402740(,%rcx,4),%edx
0x0000000000401176 <+43>: add [=10=]x1,%rax
0x000000000040117a <+47>: cmp [=10=]x6,%rax
0x000000000040117e <+51>: jne 0x401168 <phase_5+29>
0x0000000000401180 <+53>: cmp [=10=]x3d,%edx // 0x3d = 61
0x0000000000401183 <+56>: je 0x40118a <phase_5+63>
0x0000000000401185 <+58>: callq 0x4016a5 <explode_bomb>
0x000000000040118a <+63>: pop %rbx
0x000000000040118b <+64>: retq
第 <+36> 行是以下数组 table
0x402740 <array.3456>: 2 10 6 1
0x402750 <array.3456+16>: 12 16 9 3
0x402760 <array.3456+32>: 4 7 14 5
0x402770 <array.3456+48>: 11 8 15 13
在线 <+53> 我看到只要 %edx = 61
我就可以避开炸弹我明白我需要数组table中的六个整数相加到61。例如2+9+10+15+14+11 = 61
我知道如何找到值的地址。例如:
x/w 0x402740 = 2
x/w 0x402744 = 10
等等
我想不通的是如何确定将字符 'q' 和 "map" 转换为所需值(例如 10)的函数。 实际上,我可能需要反向映射我需要的 6 个值。就像找到值 10 的映射。
如有任何建议,我们将不胜感激!
更新:
** 我认为汇编代码是这样的**
void function(char *str)
{
const uint32_t *table = 0x402740;
if (strlen(str) == 6)
{
uint32_t j = 0;
for (int i = 0; i < 6; i++)
j += table[str[i]];
if (j == 0x3d)
return;
}
call explode_bomb;
}
我认为关键部分是如何处理字符串中的每个字符:
and [=10=]xf,%ecx
0x000000000040116f <+36>: add 0x402740(,%rcx,4),%edx
这看起来像 table[str[i] & 0xF]
,其中 0xF 部分与您的 C 解释不同。
所以是每个字符的 低 4 位 定义了使用哪个索引。这为您提供了多个可能的字符以供使用,因为多个字符将共享相同的低位。所以拿你的2+9+10+15+14+11的解,算出它们对应的索引是什么,每个索引可以选择什么字符。
例如 9 在 table[6] 是似乎,所以你可以使用 F
是 0x46 或 V
是 0x56,在 ASCII 中。