问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
安卓学习思路方法总结(六)
移动安全
分享者才是学习中最大的受益者!
前言 -- [安卓学习(一)](https://forum.butian.net/share/321) [安卓学习(二)](https://forum.butian.net/share/332) [安卓学习思路方法总结(三)](https://forum.butian.net/share/505) [安卓学习思路方法总结(四)](https://forum.butian.net/share/510) [安卓学习思路方法总结(五)](https://forum.butian.net/share/511) NDK动态 ----- Eclipse创建工程   然后一路默认 Finish即可 这个 前面讲过  去掉Hello world 我们今天的目标是做一个计算机 计算机 --- 放入两个Plain Test  在放入两个TestView  选中之后 修改文本   导入四个Button 做运算符  同样修改名字  进入xml底层 进行查看 双击即可  修改ID信息 ```php +:add -:sub *:mul /:div ```  进行保存 把位置重新规划好   Java代码编写 -------- 创建一个方法进行初始化控件  `init()`初始化控件  ### 绑定编辑框的变量 定义first变量 绑定编辑框 定义好类型:EditText  对应xml文件  定义第二个编辑框  对应xml文档  然后绑定Button类型的运算符  对应xml文档  一样的方法 绑定其他三个运算符  对应xml文档  ### 定义两个全局变量  ### 定义native方法 `native`方法的实现是在`so`层  ### 获取编辑框中的值 one 使用`getText`转到`toString`  two也是一样的  ### 定义运算方法  ### 监听绑定按钮 new一个`OnClickListener` 通过onClick进行监听 逻辑是通过ID来执行命令操作  ### 接收按钮Id key->v中getId的按钮 value是add按钮的ID  继续添加其他三个运算符  ### 显示界面 需要去调用方法Toast 需要三个参数 之前讲述过 这里就不展开说了  ```php context参数:上下文使用 MainActivity中的 text参数:我们获取的add(one,tWo) duration参数:使用show()进行显示 ``` 注:add这个类型是`float`类型,需要转换为`string`类型 加个字符串即可  进行其他三个运算符的显示  ### 默认值的绑定 使用`OnClickListener`进行默认值的绑定 定义变量`cli` 修饰符:`final`  我们在加减乘除的时候 都要用到编辑框 最后把编辑框放入`case`中  保存 即可 JNI层编写 ------ ### 创建JNI文件夹    ### 创建`.c`文件   ### 写入头文件  ### jfloat 使用jfloat 前两个参数是固定的 查万能表即可 然后使用方法add 后面两个是传入的参数 ```php jfloat add(JNIEvn* env, jobject obj, jfloat a, jfloat b) ```  方法体写入+  一样的方法写入其他三个 运算符  注: 方法名是不需要一样的 因为会使用JNI的接口进行两边函数的关联  ### C层和Java层的绑定 使用结构体定义结构体数组:JNINativeMethod ```php JNINativeMethod nativeMethod[]{}; ``` 写入结构体:struct 查万能表 ```php //定义一个动态注册JNINativeMethod结构体,这个与动态注册有关,里面有三个元素 typedef struct { const char* name; //第一个参数 name 是java 方法名; const char* signature; //第二个参数 signature 用于描述方法的参数与返回值,也就是java方法签名信息, void* fnPtr; //第三个参数 fnPtr 是函数指针,指向 jni 函数; } JNINativeMethod; ``` 可以看到需要三个参数 ```php 1、java方法名称 2、参数、返回值、签名信息 3、函数指针 ``` ```php {"add","(FF)F",(void*)add}, {"sub","(FF)F",(void*)sub}, {"mul","(FF)F",(void*)mul}, {"div","(FF)F",(void*)div}, ```  ### 定义函数 使用`RegisterNatives` 查万能表 ```php jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,jint); ```  四个参数 进行指出  第二个参数jclass 需要调用FindClass 重新定义一个方法aaa 继续指出,定义参数,被修饰的方法的类路径   第三个参数 是定义的数组名称 第四个参数 是数组的数量  ### 条件判断 写入一个if条件判断 和0比较 满足条件,返回-1 不满足条件,返回0 查万能表可知 ```php #define JNI_OK (0)#define JNI_ERR (-1) ```  注:这里的数组个数`jnit` 为4位 严谨的写法是: ```php sizeof(nativeMethod)/sizeof(nativeMethod[0]) ```  这个时候 注册函数 就写完了 写动态注册 ### JNI\_Onload 继续 开始 写动态注册 使用`JNI_Onload` 查万能表可知 ```php JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved); ```  给方法体定义一个jni ```php jint (*GetEnv)(JavaVM*, void**, jint); ``` `GetEnv`有三个参数 ```php 第一个参数VM:补全第二个参数void**:二级指针,指向(&)env的地址第三个参数jint:版本 ``` 最后 还需要进行指出  ### 条件判断 判断env是否获取成功 不等于0就返回-1  继续对注册函数 进行条件判断 不等于0就返回-1 加上env参数  最后添加一个返回版本  so库 --- 编写两个`.mk`文件即可 把之前的拿过来 就可以 `Android.mk` ```php LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := jsq #模块名称 LOCAL_SRC_FILES := jsq.c #源文件 .c或者.cppLOCAL_ARM_MODE := arm #编译后的指令集 ARM指令LOCAL_LDLIBS += -llog #依赖库 include $(BUILD_SHARED_LIBRARY) #指定编译文件的类型 ```  注:so库要调用的编译文件类型是:`BUILD_SHARED_LIBRARY` `Application.mk` ```php APP_ABI := x86 armeabi-v7aAPP_PLATFORM := android-8 ```  简单排错 ----    ### 编译  刷新   java层调用so库 ----------  ARM汇编 ----- 要去熟悉so库了,冲冲冲 丢入一个so文件  `so`文件的位置:`一个项目的libs目录下`  进制转换对应表 -------  ### 一、跳转指令 B:表示程序跳转 ```php 1.B:无条件跳转2.BL:带链接的无条件跳转3.BX:带状态切换的无条件跳转 根据目标地址最低位切换状态(arm/thumb)4.BLX:带链接和状态切换的无条件跳转5.B 1oc_:地址6.BEQ,BNE ``` ### 二、存储器与寄存器交互数据指令核心 存储器、寄存器:用来存储数据 ```php 小数据:寄存器;大数据:栈 ``` ```php 存储器(主存,内存)寄存器中放的数据:可以是字符串,可以是数,也可以是一个地址,它可以放各种类型的数据存储地址单元:地址与地址中存在的值 ``` #### 1、LDR、STR LDR:从存储器中加载数据到寄存器 ⬅ Load(从右到左) STR:将寄存器的数据存储到存储器 ➡ Store(从左往右) LDR `R8,[R9,#4]` R8为待加载数据的寄存器,加载值为`R9+0×4`所指向的存储单元 就是把右边放到左边 \[\]如果没括号就是直接把值直接放入R8 举个例子 ```php LDR PC, [SP+4+var_4] ``` 解析 ```php SP 栈指针寄存器,地址数据SP+4+var_4将被放进PCSTR R8,[R9,#4]:和LDR相反将R8寄存器的数据存储到R9+0x4指向的存储单元 ``` #### 2、LDM、STM ```php LDM:将存储器的数据加载到一个寄存器列表 ➡ (从左往右)LDM RO,{R1-R3}将R0指向的存储单元的数据`依次`加载到R1,R2,R3寄存器LDR:从存储器中加载数据到寄存器←Load LDR:用在函数快结尾的地方,添加对象的地方STM:将一个寄存器列表的数据存储到指定的存储器 ⬅(从右到左) ``` #### 3、PUSH、POP ```php PUSH:将寄存器值推入堆栈 压栈POP:将堆栈值推出到寄存器 岀栈 ``` #### 4、SWP SWP ```php SWP:将寄存器与存储器之间的数据进行交换SWP R1,R1 [RO]将R1寄存器与R0指向的存储单元的内容进行交换堆,队列:数据结构,栈是竖的,后进先岀,且只能从栈顶依次填入数据 ``` ### 三、数据传送指令 ```php MOV:move MOV:将立即数或寄存器的数据传送到目标寄存器MOV RO,#8 R0=8把后面的#8值给前面的RO ``` ### 四、数据算术运算指令 ```php ADD(+),SUB(-),MUL(*),DIV(/)涉及到:有符号,无符号运算,带进位运算 ``` ### 五、数据逻辑运算指令 ```php 与:AND 全1出1两边为真,结果才为真或:ORR 有1出1有一个为真,结果就为真异或:EOR 相同为零,不同为1如果两个值相等就为零,不相等就为1 ``` ```php 移位:实质是乘,除,类似于小数点移位但与平常算数相反,小数点左移,数变小;小数点右移,数变大 ``` ```php 逻辑移位小数点左移数变大,小数点右移数变小,且按2的倍数进行,因为是2进制LSL:逻辑左移LSR:逻辑右移LSL R0,R1҅#2 R0=R1*4 LSR R0,R1҅#2 R0=R1*2 ``` ### 六、比较指令 ```php CMP:比较CMP R0 #0 R0寄存器中的值与0比较标志位:如z位,这个都可以在动态调试时,寄存器窗口看到 ``` ### 七、其他指令 ```php 协处理器指令:SWT(切换用户模式、伪指令:DCB ``` ### 八、寄存器寻址方式 用到的是数据传送指令 ```php 立即寻址:MOV RO,#1234R0=0×1234寄存器寻址:MOV R0,R1 R0=R1寄存器移位寻址:MOV RO,R1,LSL #2R0=R1*4寄存器间接寻址:LDR R0,[R1]将R1寄存器中的值作为地址,取出地址中的值赋R0寄存器间接基址偏移寻址:LDR R0,[R1,#-4]将R1寄存器的值(-0×4)的值作为地址,取出地址中的值给RO ``` 简单分析so库 -------  ```php 1、从存储器中加载括号里面的RO值给R3寄存器中2、没括号就是数据,把括号內的数据直接放入R1寄存器里面3、把{R4,LR}这两个寄存器里面的值依次放到SP指向的地址,有STM就会有LDM对应4、ADD是加,R1+PC在把值放入R1里面5、把(R3+#0x18)数据作为一个地址,然后取这个地址里面的值放入R3里面6、MOV把R0里面的值放入R4里面7、BLX是进行跳转8、把R4作为一个地址取地址里面的值,放入R129、把(byte_DA4)数据放入R2里面10、MOV这里是把#4的值放入R3里11、BLX进行跳转,SUB减12、最后MOV给值,LDM返回 ``` ARM处理器寻址方式 ---------- ### 前言 寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式 了解其中一些基础的 ### 1、寄存器寻址 把R2值给R1,或者是把R1给R2在给R0 ### 2、立即寻址 立即数,只能放在寄存器里面存放,立即数要以`#`为前缀,表示16进制的0x ### 3、寄存器偏移寻址 ```php LSR:逻辑右移,寄存器中字的高端空出的位补0ASR:算术右移,移位过程中保持符号位不变,即如果源操作数为正数,则字的高端空出的位补0,否则补1ROR:循环右移,由字的低端移出的位填入字的高端空岀的位RRX:带扩展的循环右移,操作数右移一位,高端空出的位用原C标志值填充。 ```  ### 4、寄存器间接寻址 第二个参数都是方括号:\[\] 一个地址 直接取这个地址叫:直接寻址 取在该地址中取某个值叫:间接寻址 ### 5、基址寻址 `:#` 后数字如果是1,就取该地址加1后的数值 后数字如果是-1,就是数值減1作为地址 ### 6、多寄存器寻址 ```php 多寄存器寻址就是一次可以传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器。多寄存器寻址指令举例如下:LDMIA R1!,{R2-R7,R12}->将R1单元中的数据读出到R2-R7,R12,R1自动加1STMIA R0!,{R3-R6,R10}->将R3-R6,R10中的数据保存到R0指向的地址,R0自动加1 ``` 使用多寄存器寻址指令时,寄存器子集的顺序时由小到大的顺序排列,连续的寄存器可用`一`连接,否则,用`,`分隔书写 简单来讲 就是需要跳转的时候,把寄存器的值放在一个特定的寄存器里面,把这些值暂时存放起来 执行完特定的函数在将特定的寄存器里面的值取出来,然后在执行下一步操作 OK 这次就到这里
发表于 2021-09-15 15:38:08
阅读 ( 6310 )
分类:
WEB安全
0 推荐
收藏
0 条评论
请先
登录
后评论
略略略
36 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!