android平台arm指令学习和调试

发布者:美好梦想最新更新时间:2016-07-12 来源: eefocus关键字:android平台  arm指令  学习和调试 手机看文章 扫描二维码
随时随地手机看文章
*/

一、Ndk下内联汇编

跟vc下一样,ndk编译环境下也能使用内联汇编,如下:

include 

int my_thumb(int dummy)

{

__asm__(

“mov r0,#1 \t\n”

“mov r1,#2 \t\n”

“add r0,r0,r1 \t\n”

“bx lr”

);

}

int main()

{

int n = my_thumb(12);

printf(“result :%08x”,n);

return 0;

}

再看看使用标签的例子:

#include 

int my_thumb(int dummy)

{

__asm(

“mov r0,#0x1\t\n”

“ldr r0,__start\t\n”

“adr r0,__start\t\n”

“ldr r0,=__start\t\n”

“__start:\t\n”

“nop\t\n”

);

}

int main()

{

int n = my_thumb(12);

printf(“result :%08x”,n);

return 0;

}

二、编译

创建android.mk文件,然后使用ndk-build进行编译

1)编译一个可执行程序,Android.mk文件的内容如下:

LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_MODULE:= helloa

 

LOCAL_SRC_FILES := testHello.c

 

include $(BUILD_EXECUTABLE)

2)编译一个so,android.mk文件内容如下:

LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_MODULE    := testJniSo

LOCAL_SRC_FILES := testJniSo.c

 

include $(BUILD_SHARED_LIBRARY)

3)必须有一个jni目录,目录结构:

android平台arm指令学习和调试

4)这样之后,就可以在cmd窗口中,切换到代码目录,使用ndk-build命令进行编译。

三、调试可执行程序

1)Push 编译好的elf到样机中

2)使用gdbserver 启动该文件

“/data/local/gdbserver  :12345 /data/local/helloa”

3) adb forward tcp:12345 tcp:12345

4) 启动gdb

5) Target remote 127.0.0.1:12345

6) Ni 是单步,set disassemble-next on 下一句指令显示反汇编,使用set arm force-mode arm或者set arm force-mode thumb让gdb切换thumb和arm代码显示。

7) Display /i $pc 显示当前的代码

8) Continue 就是windbg的f5,od的f9

9) Info breakpoints 显示断点,而 delete删除断点 disable禁用断点

10) Disas 0xAAAA,+20(20字节的数据) 显示反汇编

11) 调试比较

android平台arm指令学习和调试
 android平台arm指令学习和调试
Gdb arm和ida反汇编比较:

android平台arm指令学习和调试

四、调试so

以爱加密为例,进行调试,范例是看雪求助帖给出的,链接如下:

http://bbs.pediy.com/showthread.php?t=184375

 

调试方法

1)So中实现的方法,程序跑起来再附加的话,该方法可能已经执行完。看雪上给出方法步骤较多,应用和底层都调试,有点复杂如下:

android平台arm指令学习和调试

我试出来的方法,对so文件进行修改,让其在入口处直接调用它本身。需要注意的是,必须在so的入口函数处修改,如果在内部调用函数修改,app会自动退出。

 

2)gdb的调试,使用ndk下自带的gdbserver和gdb进行调试

3)将修改的so导入到手机该应用的lib目录下,覆盖之前的so文件。然后运行app,出现只有边界的黑框。Gdbserver附加,使用set 命令,将bl 调用自身的命令改回去,则可以进行正常调试了。

4)模块基地址的获取 cat /proc/pid/maps 找到

5)Dump 内存的命令式 dump binary memory c:\xxx startAd endAd

6)  小细节要注意的是:.init_proc的地址是0x31cb9,ida直接点过去,是一堆数据,摁c无法转成代码

 

因为arm指令和thumb指令是2字节或者4字节对齐的,所以,改地址加1应该是真正的地址。将该地址修改为调用自身,然后gdb附加,成功断下来,然后输入“i r $lr”查看返回值,如下

 

该地址恰巧是在linker模块中, 

此处的在linker中的代码如下:

 

7)至于为什么系统的linker会调用.init_proc,不得而知。该so的oep为空,没有section表,但是有dynamic section表。自己写一个so,并没有函数“init_proc”的导出,需要再研究下elf文件格式。

自解码

本身的so是经过加密的,解密的代码是在.init_proc+1的位置,字节码的代码较长,部分代码如下:

 

1)windows下逃避断点的方法,就是利用“code shadow”的方式,在申请内存,然后将代码拷贝到指定的申请的空间上执行,这样,直接断原代码是断不到的。但是,直接搜索二进制就可以找到这样的镜像代码。

如下,之前应该运行的代码:

 

拷贝到其它地方执行的代码:

 

2)计算指定函数的汇编指令长度:代码要进行拷贝执行,必须计算拷贝代码的长度。爱加密计算拷贝代码的长度方式是通过call来计算的。函数实现的排布如下:

__asm call targetFunc

xxxxxx

xxxxxx

xxxxxx

xxxxxx

xxxxxx

xxxxxx

Void targetFunc

而call的指令是:

 

00 f0是指令opcode,c0与跳转的距离有关,计算公式是(targetAddr – curAddr)/2 – 2 =opdataLen。那么知道c0就知道中间xxx代码的长度了。

3)爱加密处理的数据有三块,第一块未知,第二块是压缩过的指令数据,第三块是需要拷贝到堆上的代码,这三块数据总长度为0x29e3c,使用mmap2进行申请映射内存,如下:

 

然后将三块数据拷贝到映射的内存上, 

在此之后,数据内存排布:

AAAAAAAAA

BBBBBBBBBB

CCCCCCCCCC

爱加密还原代码前,处理了三块数据,如上。其中,“AAAAAAAAAA”数据是一组未使用过的数据,具体功能未知,长度为0x6b0;“BBBBBBBBBB”代表的是lzma压缩过的数据;“CCCCCCCCCC”代表的是拷贝函数的数据(一共拷贝三个函数的代码)。

 

4)修改lr,然后刷新cache,返回到mmap2得到的堆上的函数进行执行

OAD:510A4010 01 1C                       MOVS    R1, R0          ; r0             0x4fb83e3c
LOAD:510A4012 10 1C                       MOVS    R0, R2          ; r2             0x4fb83bd8
LOAD:510A4014 BE 46                       MOV     LR, R7          ; r7             0x4fb83d91
LOAD:510A4014                                                     ; 这里对lr寄存器进行修改
LOAD:510A4016 C3 E7                       B       libexec___ARM_NR_cacheflush

5)再次调用mmap2,抹掉最初的“AA”、“BB”和“CC”三块数据,这样,之前执行的代码和数据将都被清零。这三块数据就被搬运到第一次调用mmap2得到的地址上,数据在内存重新做了排布。

 

6)解压数据:将数据解压到第二次调用mmap2清零的地址上,偏移为0x6b0。数据的解压使用的是lzma算法,解压的代码: 

上图中,r4指向的lzma的解压函数,r0是待解压的数据,r1是待解压的长度,r2是解压到的地址,r3上是保存解压到的地址空间的长度的地址。Lzma的具体实现: 

7)修正指定数据:解压完的数据并不是最终的代码,还需要进行修正。修正代码如下: 

修正的方法是:解压后的数据从末端开始往前,每四字节为单位,如果这四字的最高个字节是低四位是0xb,则进行移位修复。(这种方法很像pe壳中解密代码后,对0xe8、0xe9、0xff25等的修复)修复代码如下: 

8)修改内存属性,代码就完全解密,并可以运行了。 

解密前的导出函数代码如下:

 

显然上图中的代码没法运行,解码后的代码如下: 

解码后的代码分析

解密后的代码上边已经给出,r0传递的就是jnienv虚表指针,gdb中显示相关api在libicuil8n.so模块中,如下:

 

1)动态注册接口:解密后的代码主要是动态注册用于java调用的接口,如下: 

2)load的实现 

3)run方法的实现 

gdb调试的问题:

1)Gdb在遇到bx pc;nop指令,从thumb指令切换到arm指令时,会出错,调试无法继续进行。解决方法:

http://sourceware-org.1504.n7.nabble.com/Fix-ARM-stepping-over-Thumb-mode-quot-bx-pc-quot-or-quot-blx-pc-quot-td69213.html)

2)gdb遇到如下的拷贝指令也会退出调试,解决方法是跳过这段代码的位置下断点。

LOAD:510A3F88             loc_510A3F88                            ; CODE XREF: libexec_memcopy+1Ej
LOAD:510A3F88 DC 13 B1 E8                 LDMIA   R1!, {R2-R4,R6-R9,R12}
LOAD:510A3F8C 01 50 55 E2                 SUBS    R5, R5, #1      ; 这里r5不断的减少
LOAD:510A3F90 DC 13 A0 E8                 STMIA   R0!, {R2-R4,R6-R9,R12}
LOAD:510A3F94 FB FF FF 1A                 BNE     loc_510A3F88
LOAD:510A3F98 D4 03 BD E8                 LDMFD   SP!, {R2,R4,R6-R9}

关键字:android平台  arm指令  学习和调试 引用地址:android平台arm指令学习和调试

上一篇:Android ARM 指令学习
下一篇:ARM指令机器码学习

推荐阅读最新更新时间:2024-03-16 14:59

ARM指令集中经常使用的存储载入指令
ARM微处理器支持载入/存储指令用于在寄存器和存储器之间传送数据,载入指令用于将存储器中的数据传送到寄存器,存储指令则完毕相反的操作。经常使用的载入存储指令例如以下: LDR 字数据载入指令 LDRB 字节数据载入指令 LDRH 半字数据载入指令 STR 字数据存储指令 STRB 字节数据存储指令 STRH 半字数据存储指令 1、LDR指令 LDR指令的格式为: LDR{条件} 目的寄存器, 存储器地址 LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。该指令通经常使用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理。当程序计数器
[单片机]
ARM指令LDRADR的一些区别
之前在阅读 arm的汇编代码时,碰到了adr指令,查arm的指令手册,只说该指令是采用相对地址的,但这个相对地址应该怎么理解,却没有具体说明。之后在网上以 adr指令为关键字进行搜索,也没有找到进一步的知识。结果,今天在搜索android资料的时候,意外的发现了adr指令与ldr指令的不同,一下子解 决了心中的问题。以adr指令与ldr指令对比作为关键字,甚至可以搜到好几篇文章,实在是...... 竟然困扰了自己那么长时间。 将两篇转来,作为备忘吧。 一、adr和ldr的区别 同学们在学习ARM指令时,多数都会对adr和ldr这两个命令产生疑惑,那他们究竟有什么区别呢? 其实这两个都是伪指 令:adr是小范围的
[单片机]
调查显示Android男性用户比例达73%
据国外媒体昨日报道,美国手机广告网络AdMob发布的报告显示,Android手机用户多数为男性,比例高达73%。而iPhone的男女比例则较为平均,男性用户比例为56%。   除此之外,AdMob的报告还有如下要点:   - iPod Touch用户平均每月下载12个应用,而iPhone和Android用户平均每月的应用下载量均为9个;   - Palm WebOS用户对应用的兴趣最低,平均每月下载量仅为6个,这或许是因为该款手机的应用数量最少;   - iPod Touch用户平均每天的应用使用时间为100分钟,WebOS用户为87分钟,Android和iPhone分别为80分钟和79分钟;   - 78%的iPod To
[手机便携]
谷歌新智能电视平台Android TV细节曝光
    导语:美国科技博客The Verge周末刊文称,谷歌(538.15, -4.99, -0.92%)最新的智能电视平台Android TV已经曝光。与此前遭遇失败的Google TV不同,谷歌此次将专注于简单的电视界面、应用和游戏。     以下为文章全文:   一些企业计算公司常常会宣称,已经解决了电视机产品存在的问题。这些公司会说,它们已将枯燥的电视终端变成了智能计算平台,将你的工作和游戏转移至尺寸更大的屏幕。然而,这样的产品往往难以获得成功。这要么是因为缺乏内容,要么是因为带来的体验令人迷惑。这就是Google TV的故事。谷歌原本希望Google TV成为新的电视机平台,但最终却沦为行业笑柄。   这些公
[家用电子]
4种栈结构对应的ARM指令后缀
ARM的8种指令后缀: ia(increase after)先传输,再地址+4 ib(increase before)先地址+4,再传输 da(decrease after)先传输,再地址-4 db(decrease before)先地址-4,再传输 fd(full decrease)满递减堆栈 ed(empty decrease)空递减堆栈 fa(full add) 满递增堆栈 ea(empty add)空递增堆栈 例如: stmia sp, {r0 - r12} 将r0存入sp指向的内存处(假设为0x30001000);然后地址+4(即指向0x30001004),将r1存入该地址;然后地址再+4(指向0x30001008)
[单片机]
基于Android Automotive OS 的Cerence Drive对话式AI平台已经上市
Cerence Inc., AI for a world in motion,宣布基于安卓嵌入式车载操作系统(Android Automotive OS)的Cerence Drive对话式人工智能平台已经上市,使汽车制造商首次能够在Android Automotive OS框架上定制车厂自家品牌的对话式车载助理。这些新功能对汽车制造商至关重要:掌控其独特的品牌体验,和对车辆以及驾驶者数据的控制权,并与多个大型技术生态系统集成,实现多助理共存和协作。 一直以来,Cerence致力于打造让各种大型技术与通用助理生态系统共存和互操作的软件架构,并已将其Cerence Drive平台进化为真正开放与任何操作系统协作的产品。有了基于An
[汽车电子]
基于<font color='red'>Android</font> Automotive OS 的Cerence Drive对话式AI<font color='red'>平台</font>已经上市
研究显示Android并不是最开放的开源平台
     市场研究公司VisionMobile受欧盟资助,根据开放式管理、包容性、透明度和源代码易于访问等量化和评估八大开源项目的开放程度。研究报告(需要输入电邮)称,Google的Android是最不开放的开源移动平台。 八个项目从低到高的排名是Android(23%)、Qt(58%)、Symbian(58%,基于闭源前的管理模式)、MeeGo(61%)、Mozilla(65%)、WebKit(68%)、Linux(71%)和Eclipse(84%)。 VisionMobile的报告指出了Android管理模式中的多个重要问题: 缺乏清晰且公开的路线图; Google控制着整个项目,外界参与很少; 开放式手机联盟的作
[工业控制]
高通CEO:Windows传统程序需走向触摸屏平台
近日,高通CEO雅各布(Paul Jacobs)在纽约参加2012年度电子消费品展会时表示,“触摸”现在已成为电子市场一个重要词汇,Windows的传统程序必须升级以支持在平板等设备中的触摸功能。 雅各布认为,传统的Windows程序应旨在向触摸化的方向发展,支持现在很多设备的触摸功能,从而促进新系统的发展。 就在今日雅各布称,当Windows RT发布,会随其传统应用而来的是“恐惧、不确定性和怀疑”,但新系统中提供的功能最终会赢得消费者的心。 雅各布表示,为了利用微软最新版本系统的新功能,传统程序必须升级。就像是Windows RT最先推出时,就同时有了专为触摸屏设计的微软Word、Excel、PowerP
[网络通信]
高通CEO:Windows传统程序需走向触摸屏<font color='red'>平台</font>
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved