一、目标
遥想当年上小学的时候,语文是先学 人口手 上中下;数学就是先数数,然后加减乘除了。
今天的目标就是ARM汇编的加减乘除
二、步骤
伪代码
int add(int a, int b) { return a + b; } int calc(int a, int b, int c, int d) { int e = add(a-b, c-d); return e * a; }
咱们心算一下 calc(3,2,4,3) 的结果 [(3-2)+(4-3)] * 3 = 6
汇编代码
.text .globl _start _start: mov r0, $3 // 参数a = 3 mov r1, $2 // 参数b = 2 mov r2, $4 // 参数c = 4 mov r3, $3 // 参数d = 3 bl _calc // 调用 calc函数 add r0,r0,$0x30 // 把calc函数计算结果 加上0x30。 用于显示 比如 1的 ASCII值 就是 1+0x30 = 49 ldr r1, =message // 把内存message的地址存入 r1 str r0,[r1] // 把calc函数计算结果的 ASCII值 存入 message对应的内存里 mov r0, $1 // fd 1 (stdout) ldr r1, =message mov r2, $message_len mov r7, $4 // syscall 4 (write) swi $0 mov r0, $0 // exit status 0 (ok) mov r7, $1 // syscall 1 (exit) swi $0 _add: add r0, r0, r1 // r0 = r0 +r1 bx lr _calc: push {r4, r5, lr} // 保存寄存器上下文 mov r4, r0 // r4 = a mov r5, r1 // r5 = b sub r0, r0, r1 // r0 = a - b sub r1, r2, r3 // r1 = c - d bl _add // 调用_add mov r2, r0 // r2 = e mul r0, r2, r4 // r0 = e * a pop {r4, r5, pc} // 恢复寄存器上下文并返回 .data message: .ascii "0000\n" message_len = . - message
敲黑板
calc程序里面一共有 bl str add sub 和mul 几个指令
- bl
无条件跳转指令,类似C语言中的goto, 也可以调用函数用
- str
数据存储指令
- add
加法指令
- sub
减法指令
- mul
乘法指令
编译
编译连接加运行,好几条命令,一条一条敲显然不符合我们高级程序员的身份
#!/bin/bash cmdPath="/Users/fenfei/Library/Android/sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin" name="calc" $cmdPath/arm-linux-androideabi-as -o $name.o $name.S $cmdPath/arm-linux-androideabi-ld -o $name $name.o adb push $name /data/local/tmp/$name adb shell chmod +x /data/local/tmp/$name adb shell /data/local/tmp/$name
跑一下
fenfeiMac:ARMStudy fenfei$ ./b.sh calc: 1 file pushed, 0 skipped. 1.8 MB/s (976 bytes in 0.001s) 6
结果和咱们心算的一样 6
三、总结
李老板: 不是说好的加减乘除吗? 除呢?
奋飞: 这个 ARM的除比较复杂,不是一条指令就能搞定的……
其实ARM汇编就是要细心和耐心,不要一看到汇编就头大,仔细一条一条的分析和其他语言差不多,甚至更呆板一些
朝正确地方向努力能使自己变得优秀,这是确定性。努力但未必能成就事业,这叫不确定性。
TIP: 本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系,本文涉及到的代码项目可以去 奋飞的朋友们 知识星球自取,欢迎加入知识星球一起学习探讨技术。有问题可以加我wx: fenfei331 讨论下。
关注微信公众号 奋飞安全,最新技术干货实时推送