如何从给定机器码确定switch语句的有效case、缺失case及对应逻辑
逆向还原switch语句解答
1. 确定case范围与跳转表映射
首先分析汇编指令逻辑:
- 汇编第6行
sub $0x32,%edx:0x32对应十进制50,也就是将参数n减去50得到跳转偏移量,存在%edx中 - 汇编第7-8行
cmp $0x5,%edx; ja 8048448:如果偏移量大于5(即n>55),直接跳转到地址0x8048448执行,对应switch的default分支 - 跳转表共6个元素,对应偏移量05,也就是`n`的有效取值范围为5055
跳转表映射关系如下:
| 偏移量(n-50) | n取值 | 跳转地址 |
|---|---|---|
| 0 | 50 | 0x08048438 |
| 1 | 51 | 0x08048448 |
| 2 | 52 | 0x08048438 |
| 3 | 53 | 0x0804843d |
| 4 | 54 | 0x08048442 |
| 5 | 55 | 0x08048445 |
2. 解析跳转地址对应的操作
逐个分析每个地址的汇编指令对应的C语言逻辑:
- 地址0x08048438:
shl $0x2,%eax-> 算术左移2位等价于result = result *4,执行后直接跳转到函数返回,无后续操作 - 地址0x0804843d:
sar $0x2,%eax-> 有符号数算术右移2位等价于result = result /4(符合C语言有符号整数除法规则),执行后直接跳转到函数返回 - 地址0x08048442:
lea (%eax,%eax,2),%eax-> 等价于result = result *3,无跳转指令,直接向下执行后续指令 - 地址0x08048445:
imul %eax,%eax-> 等价于result = result * result(平方),无跳转指令,直接向下执行后续指令 - 地址0x08048448:
add $0xa,%eax->0xa对应十进制10,等价于result = result +10,执行后返回
3. 最终补全的switch代码
switch(n) { case 50: case 52: result *= 4; break; case 53: result /= 4; break; case 54: result *= 3; // 无break,穿透到下一个case case 55: result *= result; // 无break,穿透到default default: result += 10; }
内容的提问来源于stack exchange,提问作者Dany Nuñez
相关产品推荐
相关产品推荐

