首页
社区
课程
招聘
[原创]第一枚ARM汇编版CrackMe分析
2013-7-29 18:36 38904

[原创]第一枚ARM汇编版CrackMe分析

2013-7-29 18:36
38904
不知道 这算不算论坛 第一枚ARM汇编的CrackMe,反正 之前没看见人发过,至少可以算我自己的第一枚吧。
具体分析 我都 写在每行代码 中了,如有什么地方分析错了,希望大神指正。
当然,若有什么地方我没有分析清楚,让你看不懂,欢迎回贴一起交流。
我也是初学者,这篇文章复杂度虽然不大,但是却费了我不少劲,哈哈。。

第二枚ARM汇编程序分析
http://bbs.pediy.com/showthread.php?p=1204856#post1204856
.text:0000850C ; ---------------------------------------------------------------------------
.text:0000850C
.text:0000850C loc_850C                                ; DATA XREF: .got:0000AFA8o
.text:0000850C STMFD   SP!, {R4-R8,LR}
.text:00008510 LDR     R3, =(aHelloworld - 0x8524)     ; helloworld字符串的相对地址
.text:00008514 LDR     LR, =(unk_9B38 - 0x854C)        ; 一组特殊数据的相对地址
.text:00008518 SUB     SP, SP, #0x48
.text:0000851C ADD     R3, PC, R3                      ; 相对地址+当前指令地址=绝对地址,现                   在可以通过r3访问到字符串了
.text:00008520 MOV     R6, R1
.text:00008524 ADD     R5, SP, #0x2C
.text:00008528 LDMIA   R3, {R0-R2}                     ; 读取r3寄存器中的数据到r0,r1,r2中
.text:0000852C MOV     R3, R2,LSR#16                   ; 将r2的中值逻辑右移16位,再赋值给r3
.text:00008530 STR     R0, [SP,#0x2C]                  ; 将寄存器中的值存入到内存中
.text:00008534 STR     R1, [R5,#4]                     ; R5=SP+0X2C,R5+4刚好在上一个指令SP+0X2C之后
.text:00008538 STRH    R2, [SP,#0x34]                  ; 将R2的低位字节存入内存中,H表示无符号半字
.text:0000853C STRB    R3, [SP,#0x36]                  ; 将R3的值按无符号字节放入内存,B代表无符号字节
.text:00008540 ADD     R12, SP, #4                     ; 栈空间向上移动4,地址存入R12,便于后面存放数据
.text:00008544 ADD     LR, PC, LR                      ; 特殊数据的相对地址+当前地址=特殊数据的绝对地址,现在可以访问其中的数据 了
.text:00008548 LDMIA   LR!, {R0-R3}                    ; 读取前四个数据的值到R0-R3四个寄存器中
.text:0000854C STMIA   R12!, {R0-R3}                   ; 将读取到的数值放入内存,以便空出寄存器,继续读取数据
.text:00008550 LDMIA   LR!, {R0-R3}                    ; 继续读取数据
.text:00008554 LDR     R4, =(off_AFAC - 0x8564)
.text:00008558 STMIA   R12!, {R0-R3}                   ; 读入数据到内存的同时,R12寄存器加上4*寄存器个数的偏移
.text:0000855C LDR     R4, [PC,R4]
.text:00008560 LDR     R0, [LR]                        ; 读取特殊字符串中的倒数第二个数
.text:00008564 LDR     R1, [LR,#4]                     ; 读取特殊字符串中的最后一个数据
.text:00008568 LDR     LR, [R4]                        ; 读取R4所以地址中的值到LR寄存器
.text:0000856C LDR     R2, =0x2AAAAAAB                 ; 赋值一个常量
.text:00008570 ADD     R3, SP, #4
.text:00008574 STR     LR, [SP,#0x44]
.text:00008578 STR     R0, [R12]                       ; 存储倒数第二个数据到内存
.text:0000857C STR     R1, [R12,#4]                    ; 存储最后一个数据到内存
.text:00008580 ADD     R0, SP, #0x2B                   ; 获取字符串的首地址,并存入到R0寄存器中
.text:00008584 MOV     LR, R3                          ; 获取特殊数据串的首地址,并放入LR寄存器中
.text:00008588
.text:00008588 loc_8588                                ; CODE XREF: .text:000085ACj
.text:00008588 LDR     R1, [R3]                        ; 取R3所指地址中的数据,放入R0寄存器中,如第一个数为0xB
.text:0000858C LDRB    R12, [R0,#1]!                   ; 取字符串中的一个字符,放入到R12寄存器中
.text:00008590 EOR     R1, R1, #7                      ; 将特殊数据串中取得的数据与7进行异或运算。
.text:00008594 SMULL   R8, R7, R2, R1                  ; 除法变乘法,相当于R1/6,R7存放结果
.text:00008598 SUB     R1, R7, R1,ASR#31               ; 算法优化,原文是+22,再-24,这里处理为直接-2,表达式等价于R1=R7-R1>>31
.text:0000859C SUB     R1, R1, #2                      ; 减2
.text:000085A0 EOR     R1, R1, R12                     ; R1与字符串中的一个字符进行异或运算
.text:000085A4 STR     R1, [R3],#4                     ; 将得到的数值存入R3所在的地址,完成后R3的值加4
.text:000085A8 CMP     R3, R5                          ; 比较R3与R5的值,R3是特殊数据字串的起始位置,R5是结束位置,如果两者相等,证明数据取完了
.text:000085AC BNE     loc_8588                        ; 取R3所指地址中的数据,放入R0寄存器中,如第一个数为0xB
.text:000085B0 MOV     R3, SP                          ; 计算出的数据的超始位置-4赋值给R3
.text:000085B4 ADD     R2, SP, #0x37                   ; 找到一块空地,便于下面赋值
.text:000085B8 ADD     LR, LR, #0x24                   ; 将计算出的字符串的末地址赋给LR,作为后面赋值的结束点
.text:000085BC
.text:000085BC loc_85BC                                ; CODE XREF: .text:000085C8j
.text:000085BC LDR     R1, [R3,#4]!                    ; 将计算出的一个数据放入R1中
.text:000085C0 CMP     R3, LR                          ; 比较开始和结束的位置,以便判断是否赋值结束
.text:000085C4 STRB    R1, [R2,#1]!                    ; 将结果放入上面找到的空地处,也就是新字符串变量中
.text:000085C8 BNE     loc_85BC                        ; 将计算出的一个数据放入R1中
.text:000085CC MOV     R3, #0                          ; 末尾置0,以便让字符串中不出现垃圾字符
.text:000085D0 ADD     R0, SP, #0x38
.text:000085D4 LDR     R1, [R6,#4]
.text:000085D8 STRB    R3, [SP,#0x42]
.text:000085DC BL      _83F0                           ; 调用string.h中的函数strcmp比较两个字符串的值
.text:000085E0 CMP     R0, #0                          ; 如果字符串相同,则注册成功
.text:000085E4 BEQ     loc_8610                        ; 取成功提示字符串的相对地址
.text:000085E8 LDR     R0, =(aNoYouAreFailed - 0x85F4) ; 取失败提示字符串的相对地址
.text:000085EC ADD     R0, PC, R0                      ; "NO,you are failed!"
.text:000085F0 BL      _83F_0
.text:000085F4
.text:000085F4 loc_85F4                                ; CODE XREF: .text:0000861Cj
.text:000085F4 LDR     R2, [SP,#0x44]
.text:000085F8 LDR     R3, [R4]
.text:000085FC MOV     R0, #0
.text:00008600 CMP     R2, R3
.text:00008604 BNE     loc_8620
.text:00008608 ADD     SP, SP, #0x48
.text:0000860C LDMFD   SP!, {R4-R8,PC}
.text:00008610 ; ---------------------------------------------------------------------------
.text:00008610
.text:00008610 loc_8610                                ; CODE XREF: .text:000085E4j
.text:00008610 LDR     R0, =(aGoodWorkYouHav - 0x861C) ; 取成功提示字符串的相对地址
.text:00008614 ADD     R0, PC, R0                      ; "Good Work,you have Successed!"
.text:00008618 BL      _83F_0
.text:0000861C B       loc_85F4


再贴上源码,源码没必要讲了吧,程序 是传一个命令行参数 ,然后取这个参数 与计算 出的字符串相比较 ,若一样就显示成功 ,不一样就失败。
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
	char name[]="helloworld";
	int  keys[]={0xb,0x1f,0x19,0x19,0x49,0xb,0xb,0xb,0x31,0x53};
	char Thekeys[11];
	int i;
	for(i=0;i<10;i++)
	{
		keys[i]^=7;
		keys[i]=keys[i]/6;
		keys[i]+=22;
		keys[i]-=24;
		keys[i]^=name[i];
	}
	for(i=0;i<10;i++)
	{
		Thekeys[i]=keys[i];
	}
	Thekeys[i]=0;
	if(!strcmp(Thekeys,argv[1]))
		printf("Good Work,you have Successed!");
	else
		printf("NO,you are failed!");
	return 0;
}



后记:
写这个CrackMe的目的是为了熟悉ARM汇编,同时也希望是抛砖引玉,希望大牛多关注移动平台这块,一起交流讨论。

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

上传的附件:
收藏
点赞6
打赏
分享
最新回复 (30)
雪    币: 276
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
邓韬 9 2013-7-29 18:45
2
0
站个沙发,学习学习。
雪    币: 456
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2013-7-29 20:12
3
0
感谢大神围观,向韬哥学习。
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
safeboy 2013-7-29 20:39
4
0
围观各路大神
雪    币: 6031
活跃值: (3950)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
pxhb 2 2013-7-29 21:58
5
0
不懂arm,来学下
雪    币: 27
活跃值: (84)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
tihty 2 2013-7-29 23:09
6
0
arm需要学

楼主的精神更应该学习
雪    币: 341
活跃值: (85)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
JoySauce 1 2013-7-30 09:22
7
0
crackmes.de
雪    币: 1413
活跃值: (401)
能力值: (RANK:270 )
在线值:
发帖
回帖
粉丝
Claud 6 2013-7-30 09:23
8
0
支持一下,很不错~
雪    币: 456
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2013-7-30 09:32
9
0
这个网站我知道 ,只是很久没去过了,
雪    币: 456
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2013-7-30 09:33
10
0
向版主学习。
雪    币: 86
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
threewind 2013-7-30 14:34
11
0
牛,我要一行行认真学习,谢谢分享。
雪    币: 1839
活跃值: (295)
能力值: ( LV9,RANK:370 )
在线值:
发帖
回帖
粉丝
fosom 8 2013-7-30 16:35
12
0
楼主用的DOS输出,也就是win32平台,怎么编译出来的arm指令啊,求教。。。。
雪    币: 456
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2013-7-30 18:02
13
0
我是在dos下用的adb shell 运行的程序,用的ndk-build编译的程序。用ida反编译这个elf文件,就是arm汇编 啦。
雪    币: 107
活跃值: (311)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Fido 2013-7-30 19:57
14
0
不错不错...谢谢楼主分享..学习了..
雪    币: 67
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小龙程序 2013-7-30 21:33
15
0
围观大神,学习一下!!
雪    币: 456
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2013-7-31 07:48
16
0
没想到这篇帖子这么受欢迎,来了这么多大牛,哈哈。
雪    币: 234
活跃值: (202)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tfrist 2013-8-6 15:48
17
0
学习学习!
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
chdlong 2014-2-14 21:51
18
0
新手把这个程序编译的可以在android上运行,还是要费一番手脚的,楼主不知道能不能把这内容详解下?
雪    币: 456
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2014-2-14 23:58
19
0
推荐你去看一下非虫大牛的那本书。
雪    币: 110
活跃值: (293)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ling林 2014-2-15 07:55
20
0
mark.....
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
chdlong 2014-2-15 20:54
21
0
没错,我也在看,刚开始理解的不好,经反复实验,按虫大的第三种编译法:eclipse自动编译成功,经IDA汇编确实为elf文件,只是还运行不起来。

D:\>adb shell D:/hello 1234567890
/system/bin/sh: D:/hello: not found

不清楚原因?

找到原因:此提示因为要执行的文件要放到android设备(或模拟器)中。

D:\>adb shell /data/local/tem/hello 1234567890
/system/bin/sh: /data/local/tem/hello: can't execute: Permission denied

上面提示是因为没有取得执行权限

D:\>adb shell chmod 755 /data/local/tem/hello        可解决

自己够笨的,呵呵
雪    币: 5
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
笨小孩xlz 2014-3-6 14:38
22
0
楼主要是能结合内存布局再来说汇编代码的含义 就更加清晰易懂了
雪    币: 310
活跃值: (111)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
rockl 2015-1-26 13:50
23
0
这个对我这个刚接触android太有用了!赞一个
雪    币: 188
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
JackJoker 2015-1-27 00:03
24
0
明天也玩下
雪    币: 39
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cb彬 2015-4-26 11:04
25
0
开始学习arm汇编,感谢楼主开新手帖,哈哈
游客
登录 | 注册 方可回帖
返回