前几天 发了一个ARM汇编版的CrackMe,好像还挺 受欢迎的,但是由于.o文件无法由安卓程序调用,所以只能在dos下用adb shell 执行,看上去很不直观,引起一些朋友不解。
今天 我给大家 写了一个so文件 ,这样android 程序 就可以调用它了,再加上安卓的界面,看起来就要舒服点,呵呵。
由于 本人根本没学过安卓开发,所以要写个复杂的程序还是比较困难的,而分析arm汇编的指令又不需要看安卓代码 ,因此我在sample中找了一个HelloJni程序,向里面
加了一段自己写的c代码,就这样,分析旅程就开始了。
我写这个程序旨在熟悉ARM汇编指令,所以我尽可能的让它产生各种指令,如MUL,SUB,EOR,LDR,STR等,再加入程序执行的各种流程,如顺序,if else,for循环,while循环,switch case,还有一个子程序调用。
libhello_jni.so:491DCD4C STMFD SP!, {R4-R8,LR} ; 将r4,45,r6,r7,r8,lr寄存器入栈
libhello_jni.so:491DCD50 LDR R3, =(aWww_pediy_com - 0xD64) ; 获取字符串name的相对地址
libhello_jni.so:491DCD54 SUB SP, SP, #0x80 ; 分配栈空间
libhello_jni.so:491DCD58 ADD R12, SP, #0x6C
libhello_jni.so:491DCD5C ADD R3, PC, R3 ; 相对地址加上当前地址,等于字符串Name的绝对地址
libhello_jni.so:491DCD60 MOV R5, R0
libhello_jni.so:491DCD64 LDR R6, =(unk_491DE3A8 - 0x491DCD78) ; 获取hash数组的首地址的相对地址
libhello_jni.so:491DCD68 LDMIA R3, {R0-R3} ; 将R3所指向的值存入到R0,R1,R2,R3寄存器中
libhello_jni.so:491DCD6C STMIA R12!, {R0-R2} ; 将R0,R1,R2中的数值放入R12所指向的内存,
;以便空出寄存器,继续读取数据,这里为什么没有读取R3中的数据呢?因为R3只有低8位有数据,不便于直接读入,在后面会读入
libhello_jni.so:491DCD70 ADD R6, PC, R6 ; 计算出hash数组的绝对地址
libhello_jni.so:491DCD74 STRH R3, [R12] ; 这里读入R3中的数据
libhello_jni.so:491DCD78 MOV R7, R6 ; 将R6中保存的hash数组首地址放入R7中
libhello_jni.so:491DCD7C ADD LR, SP, #4
libhello_jni.so:491DCD80 LDMIA R7!, {R0-R3} ; 依次读入R7所以地址的四个数据到R0-R3寄存器,完成后R7的地址自动加0x10
libhello_jni.so:491DCD84 STMIA LR!, {R0-R3} ; 将刚才读到的数据存入到lr所在的连续内存中,完成后lr的值自动加0x10
libhello_jni.so:491DCD88 LDMIA R7!, {R0-R3} ; 继续取hash数组中的值
libhello_jni.so:491DCD8C LDR R4, =(unk_491DFFB0 - 0x491DCDA0) ; 获取第三个数组data的首地址的相对地址
libhello_jni.so:491DCD90 STMIA LR!, {R0-R3} ; 将上面读到的数据存入到lr所在的连续内存中
libhello_jni.so:491DCD94 LDMIA R7!, {R0-R3} ; 继续取hash数组中的值
libhello_jni.so:491DCD98 LDR R4, [PC,R4] ; 注意这句不是像上面ADD R6,PC,R6,这句行等价于ADD R4,[PC+R4]
libhello_jni.so:491DCD9C LDR R8, [R4]
libhello_jni.so:491DCDA0 ADD R6, R6, #0x34 ; R6加上hash的长度,使其指向data数据的首地址
libhello_jni.so:491DCDA4 ADD R12, SP, #0x38 ; 调整栈空间,移到空位,准备接收新数据
libhello_jni.so:491DCDA8 STR R8, [SP,#0x7C]
libhello_jni.so:491DCDAC STMIA LR!, {R0-R3} ; 继续将上面未存完的hash数据存入到lr所在内存
libhello_jni.so:491DCDB0 LDMIA R6!, {R0-R3} ; 现在开始将data数组 中的数据进行存入操作
libhello_jni.so:491DCDB4 LDR R7, [R7]
libhello_jni.so:491DCDB8 STMIA R12!, {R0-R3} ; 将从data数组中得到 的数据存入到R12所在内存,完成后r12自动加0x10
libhello_jni.so:491DCDBC LDMIA R6!, {R0-R3} ; 继续获取data中的数据
libhello_jni.so:491DCDC0 STMIA R12!, {R0-R3} ; 再存入
libhello_jni.so:491DCDC4 LDMIA R6!, {R0-R3} ; 再读取
libhello_jni.so:491DCDC8 STMIA R12!, {R0-R3} ; 再存入
libhello_jni.so:491DCDCC LDR R3, [R6]
libhello_jni.so:491DCDD0 ADD R0, SP, #0x6C
libhello_jni.so:491DCDD4 STR R7, [LR]
libhello_jni.so:491DCDD8 STR R3, [R12]
libhello_jni.so:491DCDDC BL unk_491DCBFC ; 调用 strlen 计算name值长度
libhello_jni.so:491DCDE0 CMP R0, #0 ; 比较是否为空
libhello_jni.so:491DCDE4 BLE loc_491DCE78 ; 若长度小于等于0,则跳过后面的for循环
libhello_jni.so:491DCDE8 ADD R6, SP, #0x6C
libhello_jni.so:491DCDEC MOV R12, SP
libhello_jni.so:491DCDF0 ADD R7, R6, R0
libhello_jni.so:491DCDF4 MOV R3, R6
libhello_jni.so:491DCDF8
for循环:
.text:00000DF8 loc_DF8 ; CODE XREF: .text:00000E24j
.text:00000DF8 LDR R1, [R12,#4]! ; 取name[i]的值
.text:00000DFC LDRB R2, [R3] ; R3等于变量i,作为循环基数
.text:00000E00 EOR R2, R1, R2 ; 进行异或运算
.text:00000E04 AND R2, R2, #0xFF ; 若得到的数越界,则取低8位
.text:00000E08 SUB R1, R2, #0x14 ; name[i]减20
.text:00000E0C TST R1, #1 ; 判断数值是否为2的倍数
.text:00000E10 STRB R1, [R3],#1 ; 将R1的值存入R3所指向的地址,完成后R3加1
.text:00000E14 SUBEQ R2, R2, #0xA ; 是2的倍数,则减10
.text:00000E18 SUBNE R2, R2, #0xF ; 不是2的倍数,则减15
.text:00000E1C CMP R3, R7 ; R7是字符串长度,循环的上限
.text:00000E20 STRB R2, [R3,#-1] ; 将R2的值,存入到[R3-1]所指向的地址
.text:00000E24 BNE loc_DF8 ; for循环条件判断
.text:00000C74 STMFD SP!, {R4,R5}
.text:00000C78 LDRB R3, [R0] ; 取name[i]的值,其实 就是while循环的首次条件判断
.text:00000C7C CMP R3, #0
.text:00000C80 BEQ loc_CF8 ; 等于0则while循环结束
.text:00000C84 LDR R4, =0xCCCCCCCD ; 为下面的求模运算作准备
.text:00000C88 ADD R2, R0, #1 ;为下一次取name数组的值做准备
.text:00000C8C MOV R12, #0xA
.text:00000C90
.text:00000C90 loc_C90 ; CODE XREF: function+80j
.text:00000C90 MOV R3, R3,LSR#2 ; R3=R3>>2,对应源码中的name[i]=name[i]>>2
.text:00000C94 UMULL R5, R1, R4, R3 ; R1存放结果中的高数数据,R5存入低位数据
.text:00000C98 MOV R1, R1,LSR#3 ; R1=R1>>3
.text:00000C9C MUL R1, R12, R1 ; R1=R12*R1
.text:00000CA0 RSB R1, R1, R3 ; 逆减法指令,R1=R3-R1
.text:00000CA4 AND R1, R1, #0xFF ; 如果越界,则取低8位的数
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课