一、So简介 
1.Android底层是Linux,Linux本身就是使用C/C++语言,Android使用了一个Dalvik虚拟机才使得应用程序开发使用Java语言; 
2.Dalvik支持JNI编程方式,第三方应用完全可以通过JNI调用自己的C/C++动态库(so文件),使用“Java+C”编程方式; 
3.NDK(Native Development Kit)是“Java+C”开发的工具库,保证程序的兼容性、调试性和调用API方便性,也避免Java的不足,如安全性; 
二、“Java+C”编程方式
 

三、使用NDK原因 
1.代码保护:APK对Java代码很容易反编译、阅读和篡改,而对C/C++开发出来的so库进行反汇编难度较大; 
2.方便使用现存的开源库:大部分现存的开源库(OpenCV、OPENGL等)都是用C/C++代码编写的; 
3.提高程序的执行效率:将要求高性能的逻辑使用C开发,从而提高应用程序的执行效率; 
4.便于移植:用C/C++写的so库可以方便移植到其它的嵌入式平台上使用; 
四、NDK开发流程
 
在讲解so分析之前,我们先创建一个NDKDemo程序(Android Studio为例),简单通过Java调用C中的方法,返回字符串Toast显示; 
1.File->Project Structure->SDK Location->Android NDK location->Download Android NDK,完成安装NDK(新版本NDK,安装在SDK目录下的ndk-bundle); 
2.从传统的Android Gradle插件迁移,需要修改如下Gradle配置:

[plain] view plaincopy
  1. .
  2. ├── app/
  3. │   ├── app.iml
  4. │   ├── build.gradle
  5. │   └── src/
  6. ├── build.gradle
  7. ├── gradle/
  8. │   └── wrapper/
  9. │       ├── gradle-wrapper.jar
  10. │       └── gradle-wrapper.properties
  11. ├── gradle.properties
  12. ├── gradlew*
  13. ├── gradlew.bat
  14. ├── local.properties
  15. ├── MyApplication.iml
  16. └── settings.gradle

./gradle/wrapper/gradle-wrapper.properties 

[plain] view plaincopy
  1. #Wed Apr 10 15:27:10 PDT 2013
  2. distributionBase=GRADLE_USER_HOME
  3. distributionPath=wrapper/dists
  4. zipStoreBase=GRADLE_USER_HOME
  5. zipStorePath=wrapper/dists
  6. //修改gradle版本
  7. distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

./build.gradle 

[plain] view plaincopy
  1. buildscript {
  2. repositories {
  3. jcenter()
  4. }
  5. dependencies {
  6. //修改依赖的gradle插件
  7. classpath "com.android.tools.build:gradle-experimental:0.7.0-alpha1"
  8. // NOTE: Do not place your application dependencies here; they belong
  9. // in the individual module build.gradle files
  10. }
  11. }

build.gradle 

[plain] view plaincopy
  1. //修改使用插件
  2. apply plugin: 'com.android.model.application'
  3. //修改model层级
  4. model {
  5. android {
  6. compileSdkVersion 23
  7. buildToolsVersion "24.0.0"
  8. //增加ndk配置
  9. ndk {
  10. moduleName "hello"
  11. }
  12. defaultConfig {
  13. applicationId "com.example.pengchengxiang.securitydemo"
  14. //修改sdk相关版本声明
  15. minSdkVersion.apiLevel 21
  16. targetSdkVersion.apiLevel 23
  17. versionCode 1
  18. versionName "1.0"
  19. }
  20. buildTypes {
  21. release {
  22. minifyEnabled false
  23. //修改proguard相关配置
  24. proguardFiles.add(file("proguard-rules.pro"))
  25. signingConfig = $("android.signingConfigs.myConfig")
  26. }
  27. }
  28. }
  29. //修改签名相关配置
  30. android.signingConfigs {
  31. create("myConfig") {
  32. storeFile "/home/pengchengxiang/KeyStores/android.jks"
  33. storePassword "12345678"
  34. keyAlias "MyAndroidKey"
  35. keyPassword "11111111"
  36. storeType "jks"
  37. }
  38. }
  39. }
  40. dependencies {
  41. compile fileTree(include: ['*.jar'], dir: 'libs')
  42. testCompile 'junit:junit:4.12'
  43. compile 'com.android.support:appcompat-v7:23.4.0'
  44. }

3.迁移新的插件com.android.model.application后,你会发现Gradle构建中添加了许多相关的Task: 

4.在Java类中定义native方法; 
MainActivity.java:

[java] view plaincopy
  1. public class MainActivity extends Activity {
  2. //加载hello.so库
  3. static {
  4. System.loadLibrary("hello");
  5. }
  6. private Button button;
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. button = (Button) findViewById(R.id.Button1);
  12. button.setOnClickListener(new View.OnClickListener() {
  13. @Override
  14. public void onClick(View v) {
  15. //调用native方法
  16. Toast.makeText(MainActivity.this, "add result =" + helloWorldFromJNI(100), Toast.LENGTH_SHORT).show();
  17. }
  18. });
  19. }
  20. //定义native方法
  21. public native int helloWorldFromJNI(int count);
  22. }

4.在Java源代码目录下,使用javah命令生成头文件;

[plain] view plaincopy
  1. pengchengxiang@ubuntu:~/SecurityWorkSpace/SecurityDemo/app/src/main/java$ javah -d ../jni com.example.pengchengxiang.securitydemo.MainActivity


5.在生成的jni目录下,创建hello.c文件,实现相关方法并引用生成的头文件; 
Hello.c文件: 

[plain] view plaincopy
  1. #include "com_example_pengchengxiang_securitydemo_MainActivity.h"
  2. JNIEXPORT jint JNICALL Java_com_example_pengchengxiang_securitydemo_MainActivity_helloWorldFromJNI(JNIEnv * env, jobject obj, jint count)
  3. {
  4. return count + 1;
  5. }

6.构建并运行程序; 

五、so分析步骤 
在分析之前,我们讲解一些两个概念,反汇编和反编译: 
    反编译:针对NDK开发出来的so文件进行逆向; 
    反混淆:逆向dex文件; 
1.安装ida pro软件(该软件为收费软件); 
2.将apktool反编译apk,在libs/armeabi-v7a目录中找到动态库libhello.so文件; 
3.打开ida pro软件,点击Open按钮选择libhello.so文件,然后弹出一个对话框,保持自动选择,点击“OK”; 

4.进入到ida pro主界面(如下图),在左边栏中列举了hello.so文件里面的函数名,如Java_com_example_pengchengxiang_securitydemo_MainActivity_helloWorldFromJNI方法,以及该函数地址00000D1C和汇编代码内容; 

5.切换到Hex View(十六进制)视图,查看对应的16进制数据; 

6.f5插件(如何查看伪代码?) 
六、修改so逻辑 
1.ids pro是伪代码的查看,so是二进制文件,不能直接对so文件进行修改和注入代码。如果希望修改so文件需要针对其代码片段的二进制进行修改。则使用UtralEdit打开libhello文件,寻找地址00000D1C(地址是连续的,在UtralEdit中找到最近的地址00000d10h),将“50 1C”修改为“90 1C”并保存(汇编代码阅读不在本章节解读范围),将count = count + 1修改为count = count + 2; 

2.将修改过的so包,替换libs/areambi-v7a目录,使用apktool重新打包,签名,重新安装,运行如下: 

Android安全:So分析相关推荐

  1. android释放acitity内存,Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  2. android挂载usb设备,android usb挂载分析---MountService启动

    在android usb挂载分析----vold启动,我们的vold模块已经启动了,通信的机制也已经建立起来了,接下来我们分析一下MountService的启动,也就是我们FrameWork层的启动, ...

  3. Android源码分析-全面理解Context

    前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...

  4. Android Studio +MAT 分析内存泄漏实战

    点击打开链接 对于内存泄漏,在Android中如果不注意的话,还是很容易出现的,尤其是在Activity中,比较容易出现,下面我就说下自己是如何查找内存泄露的. 首先什么是内存泄漏? 内存泄漏就是一些 ...

  5. Android源码分析--MediaServer源码分析(二)

    在上一篇博客中Android源码分析–MediaServer源码分析(一),我们知道了ProcessState和defaultServiceManager,在分析源码的过程中,我们被Android的B ...

  6. Android系统启动流程分析之安装应用

    2016六月 21 原 Android系统启动流程分析之安装应用 分类:Android系统源码研究 (295)  (0)  举报  收藏 跟随上一篇博客Android系统的启动流程简要分析继续分析an ...

  7. android settings源代码分析(2)

    通过前一篇文章  Android settings源代码分析(1)  分析,大概知道了Settings主页面是如何显示,今天主要分析"应用"这一块google是如何实现的. 应用对 ...

  8. Android `AsyncTask`简要分析

    Android `AsyncTask`简要分析 AsyncTask简要分析 经典异步任务:AsyncTask,使用场景有:批量下载,批量拷贝等.官方文档就直接给出了一个批量下载的示例. private ...

  9. 转 android anr 分析示例,[摘]Android ANR日志分析指南之实例解析

    前文<[摘]Android ANR日志分析指南>也摘抄了如何分析,接下来通过实例解析. 一.主线程被其他线程lock,导致死锁 waiting on <0x1cd570> (a ...

  10. android 实例源码解释,Android Handler 原理分析及实例代码

    Android Handler 原理分析 Handler一个让无数android开发者头疼的东西,希望我今天这边文章能为您彻底根治这个问题 今天就为大家详细剖析下Handler的原理 Handler使 ...

最新文章

  1. Android CountDownTimer倒计时器的使用
  2. 阿里巴巴云舒:弹性计算的安全问题
  3. c语言把文件导入链表,【求解答】c关于把文件数据放进链表,并将链表遍历
  4. Intel Realsense D435 python(Python Wrapper)example02: NumPy and OpenCV 用窗口展示并排堆叠的RGB流和深度流
  5. Redisbook学习笔记(3)数据类型之集合
  6. 调试 SAP Spartacus 服务器端渲染 SEO HTML Tag 生成逻辑的注意事项
  7. 字符串太占内存了,我想了各种奇思淫巧对它进行压缩
  8. css定位:相对定位
  9. oracle数据库全数据库名,Oracle数据库中的 数据库域名、数据库名、全局数据库名、SID、数据库实例名、服务名 解释...
  10. 《大数据》第1期“论坛”——数据技术时代的未来
  11. raspberry pi_使用Kubernetes在Raspberry Pi上进行集群计算
  12. 【深度语义匹配模型】实践篇:语义匹配在贝壳找房智能客服中的应用
  13. 基于PHP的学生选课管理系统
  14. 实验二木马分析(控制分析)实验和实验三冰河木马实验
  15. python成绩分析系统_用Python编写学生成绩分析系统
  16. Windows10开启虚拟化
  17. 图扑软件数字孪生 SMT 产线,智能工业可视化管理
  18. 二元二次方程例题_二元二次方程练习题.doc
  19. Office 2016安装
  20. 生产系统功能目标和组织结构

热门文章

  1. Beyond Compare可以进行二进制比较
  2. ExtJS简介--车辆调度
  3. C/C++语言中Static的作用详述
  4. struts2生成随机验证码图片
  5. 工作所思--IT新人
  6. 前端开发和设计必备的Chrome插件
  7. linux qt调用摄像头,Qt5下实现摄像头预览及捕获图像方法实例
  8. 单片机的各种存储的含义和区别
  9. pythonmooc期末考试编程题_大学moocPython编程基础期末考试搜题公众号答案
  10. c语言数字分解一个数,关于一道分解整数为N个连数整数的编程题