ARM中跳转指令BL/BLX偏移值计算规则
2016-01-14 10:08
519 查看
源文地址:http://www.cnblogs.com/Reyzal/p/4857948.html
原因:
指令地址 + 8:因为ARM的流水线使得指令执行到当前指令处时,PC实际的值是A+8。
跳转指令 - 上一步得到地址:得到跳转指令与当前PC处的差值。
÷4:因为ARM的指令是4对齐的,即最低两位为00,于是将这个值右移两位。
执行时:
取出偏移,左移两位,加入PC,这时PC的值刚好为目标处的地址值,即目标地址指令进入取值,流水线前两级被清空。
实例测试:
(0010d4 - (001284 + 8))/4 = 00FFFF92。
对应机器码为 92 ff ff
(转自 http://bbs.pediy.com/showthread.php?t=199429 ))
1.向后跳转
0012 00F001F8 bl .Lhelo
.Lhelo:
0018 05F0D1F7 pld [r1, r5]
计算方式:
取高位 f000, 取后11位 => 000
取低位 f801, 取后11位 => 001
计算: (000 << 12) | (001 << 1) = 2
由于这个最高位符号位为0. 代表向后跳转, 只需要保留该值2即可
然后计算得到的目标地址为 : 0x0012 + 4 + 2 = 0x0018
向前跳转
00001164 FF F7 BE FF BL _Z4testv
_Z4testv
000010E4 07 B5 PUSH {R0-R2,LR}
计算方式:
取高位 f7ff, 取后11位 => 7ff
取低位 ffbe, 取后11位 => 7be
计算: (7ff << 12) | (7be << 1) = 7fff7c
由于这个最高位符号位为1 代表向前跳转, 需要-1然后取反 得到值为 ff800084。取84即可
然后计算得到的目标地址为 : 0x1164 + 4 - 0x84 = 0x10e4
逆向过程:
BL <label>
由BL指令得到机器码算法:
BLX <label>
与BL类似。
1. 4字节对齐arm指令
规则:偏移=( 跳转地址-(指令地址+8) )/4原因:
指令地址 + 8:因为ARM的流水线使得指令执行到当前指令处时,PC实际的值是A+8。
跳转指令 - 上一步得到地址:得到跳转指令与当前PC处的差值。
÷4:因为ARM的指令是4对齐的,即最低两位为00,于是将这个值右移两位。
执行时:
取出偏移,左移两位,加入PC,这时PC的值刚好为目标处的地址值,即目标地址指令进入取值,流水线前两级被清空。
实例测试:
.text:0000126C 90 00 9F E5 LDR R0, =0x4D44 .text:00001270 00 70 8F E0 ADD R7, PC, R0 ; _GLOBAL_OFFSET_TABLE_ .text:00001274 07 00 86 E0 ADD R0, R6, R7 .text:00001278 74 10 80 E2 ADD R1, R0, #0x74 .text:0000127C DC 20 80 E2 ADD R2, R0, #0xDC .text:00001280 04 00 A0 E3 MOV R0, #4 .text:00001284 92 FF FF EB BL __android_log_print .text:00001288 00 00 95 E5 LDR R0, [R5] .plt:000010D4 __android_log_print .plt:000010D4 00 C6 8F E2 ADR R12, 0x10DC |
对应机器码为 92 ff ff
2. thumb2指令
(转自 http://bbs.pediy.com/showthread.php?t=199429 ))1.向后跳转
0012 00F001F8 bl .Lhelo
.Lhelo:
0018 05F0D1F7 pld [r1, r5]
计算方式:
取高位 f000, 取后11位 => 000
取低位 f801, 取后11位 => 001
计算: (000 << 12) | (001 << 1) = 2
由于这个最高位符号位为0. 代表向后跳转, 只需要保留该值2即可
然后计算得到的目标地址为 : 0x0012 + 4 + 2 = 0x0018
向前跳转
00001164 FF F7 BE FF BL _Z4testv
_Z4testv
000010E4 07 B5 PUSH {R0-R2,LR}
计算方式:
取高位 f7ff, 取后11位 => 7ff
取低位 ffbe, 取后11位 => 7be
计算: (7ff << 12) | (7be << 1) = 7fff7c
由于这个最高位符号位为1 代表向前跳转, 需要-1然后取反 得到值为 ff800084。取84即可
然后计算得到的目标地址为 : 0x1164 + 4 - 0x84 = 0x10e4
逆向过程:
BL <label>
由BL指令得到机器码算法:
offset = dstAddr - srcAddr; offset = (offset -4) & 0x007fffff; high = offset >> 12; low = (offset & 0x00000fff) >> 1; machineCode = ((0xFF00 | low) << 16) | (0xF000 | high); |
与BL类似。
offset = dstAddr - srcAddr; offset = (offset -4) & 0x007fffff; high = offset >> 12; low = (offset & 0x00000fff) >> 1; if(low%2 != 0) { low++; } machineCode = ((0xEF00 | low) << 16) | (0xF000 | high); |
相关文章推荐
- 网络编程Socket入门篇
- Listview的几种特殊的属性
- Python学习笔记——实例方法和静态方法
- Xcode测试
- UGUI中的InputField下的placeholder的作用?
- 关于js事件冒泡和事件捕获
- c#范型List的Sort方法详解
- JUnit简单教程
- java 反射的一个例子
- Java SE 学习笔记 chapter3
- GUID
- App自动更新之通知栏下载(转)
- 继承抽象类运行其方法出现null的异常
- JAVA可阻塞队列-ArrayBlockingQueue
- 时间戳转换为"yyyy-MM-dd hh:mm:ss"格式(24小时)
- 百度地图开发(二)之添加覆盖物 + 地理编码和反地理编码
- 怎样激励身边的朋友积极向上?
- Integer类型用 “==” 比较的问题
- Storm有关worker、task、spout/bolt、executor、component之间的关系
- Db2性能优化-表分区