逆向Android软件的步骤

逆向Android软件的步骤:

首先使用反编译的工具对反编译,然后阅读反汇编代码,如果有必要还会对其进行动态调试,找到突破口后注入或直接修改反汇编代码,最后重新编译软件进行测试。整个过程可分为反编译、静态分析、动态调试、重编译等4个环节。

结论:反破解技术也是从这四个方面进行的。

一、对抗反编译工具(如ApkTool、BackSmali、dex2jar),使其无法进行反编译,或者反编译后无法得到软件正确的反汇编代码。

思路是:寻找反编译工具在处理apk或dex文件时的缺陷,然后在自己的软件中加以利用。主要方法有:

1、阅读反编译工具源码,找出漏洞。

2、压力测试。测试大量apk文件,找到反编译工具反编译不了的,分析其特征。

此方法难度较大,而且反编译工具不断升级,方法容易过时,因此不太建议。(不行)

二、对抗静态分析。


1、代码混淆技术:

Android2.3的SDK中正式加入了ProGuard代码混淆工具,开发人员可以使用该工具对自己的代码进行混淆。Android2.3以前的项目同样可以使用此工具。

2、NDK保护。

NDK简介:“android原生开发套件”。他是一款功能强大的工具,可以将原生C,C++代码的强大功能和android应用的图形化界面结合到一起,解决软件的跨平台问题。通过使用该工具,一些应用程序直接通过JNI调用(ps:java native interface,允许Java代码和其他语言编写的代码进行交互)与CPU打交道使性能得到提升。同时能够将程序的核心功能封装进基于“原生开发套件”的模块中,从而大大提高性能!(PS:C/C++的抗攻击能力比Java强)

优势:逆向NDK程序是很困难和繁琐的,安全性很高。

缺点:程序员开发成本提高。

3、外壳保护。

java由于其语言自身特殊性,没有外壳保护这个概念,只能通过混淆方式对其进行保护。外壳保护重点针对使用NDK编写的Native代码,逆向Native本身就已经够困难了,如果添加了外壳保护则更是难上加难,目前已知可用于ARM Linux内核程序的加壳工具只有upx。

PS:关于upx:http://upx.sourceforge.net/    支持的平台

三、对抗动态调试。


1、检测调试器:

动态调试使用调试器来挂钩软件,获取软件运行时的数据,我们可以在软件中加入检测调试器的代码,当检测到软件被调试器连接时,中止软件的运行。

首先,在AndroidManifest.xml文件的Application标签中加入android:debuggable="false",让程序不可调试,这样,如果别人想调试该程序,就必然会修改它的值,我们在代码中检查它的值来判断程序是否被修改过。代码如下:

if (0!=(getApplicationInfo().flags&=ApplicationInfo.FLAG_DEBUGGABLE)) {  
            Log.e("DEBUG", "程序被修改为可调试状态!!!");  
            android.os.Process.killProcess(android.os.Process.myPid());  
        }

另外,Android SDK中提供了一个方法方便程序员来检测调试器是否已经连接,代码如下:

android.os.Debug.isDebuggerConnected()

如果方法返回真,说明了调试器已经连接。我们可以随机地在软件中插入这行代码来检测调试器,碰到有调试器连接就果断地结束程序运行。

(PS:感觉这是个好的办法!但是不知道是否有破解的方法???如果有必要留待以后查资料)

对抗检测调试器的方法:

方法1:IsDebuggerPersent()/查找PEB中BeingDebugged内容

方法2:检查是否有异常处理器

方法3:利用调试器约定特殊指令检测

方法4:查找当前硬件断点

方法5:在执行特殊函数后检查GetLastError()值

方法6:DebugPort: CheckRemoteDebuggerPresent()/NtQueryInformationProcess()

方法7:检测SetUnhandledExceptionFilter()

方法8:ThreadHideFromDebugger

方法9:进程遍历

方法10:父进程检查

方法11:SeDebugPrivilege()

方法12:FindWindow

方法13:STARTUPINFO

方法14:timecheck

...

方法N:利用调试器漏洞

(未扩展   但是不知道能不能在android上实现这些对抗)

2、检测模拟器。(ps:只是增加了逆向的成本,必须有一台android机器)

软件发布后会安装到用户的手机中运行,如果有发现软件运行在模拟器中,很显然不合常理,可能是有人试图破解或分析它,这种情况我们必须予以阻止。

模拟器与真实的Android手机有许多差异,我们可以在命令提示符下执行"adb shell getprop"查看并对比它们的属性值,经过对比发现如下几个属性值可以用来判断软件是否运行在模拟器中:

ro.product.model、ro.build.tag、ro.kernel.qemu。

编写检测代码如下:

boolean isRunningInEmualtor() {  
        boolean qemuKernel = false;  
        Process process = null;  
        DataOutputStream os = null;  
        try{    
            process = Runtime.getRuntime().exec("getprop ro.kernel.qemu");    
            os = new DataOutputStream(process.getOutputStream());  
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));  
            os.writeBytes("exit\n");    
            os.flush();  
            process.waitFor();  
            qemuKernel = (Integer.valueOf(in.readLine()) == 1);  
            Log.d("com.droider.checkqemu", "检测到模拟器:" + qemuKernel);               
        } catch (Exception e){    
            qemuKernel = false;  
            Log.d("com.droider.checkqemu", "run failed" + e.getMessage());   
        } finally {  
            try{    
                if (os != null) {    
                    os.close();    
                }    
                process.destroy();    
            } catch (Exception e) {  
                  
            }    
            Log.d("com.droider.checkqemu", "run finally");   
        }  
        return qemuKernel;  
    }  
      
    public static String getProp(Context context, String property) {  
        try {  
            ClassLoader cl = context.getClassLoader();  
            Class SystemProperties = cl.loadClass("android.os.SystemProperties");  
            Method method = SystemProperties.getMethod("get", String.class);  
            Object[] params = new Object[1];  
            params[0] = new String(property);  
            return (String)method.invoke(SystemProperties, params);  
        } catch (Exception e) {  
            return null;  
        }  
    }

四、防止重编译。


1、检查签名。

每一个软件在发布时都需要开发人员对其进行签名,而签名使用的密钥文件是开发人员所独有的,破解者通常不可能拥有相同的密钥文件,因此,签名成了Andriod软件一种有效的身份标识,如果软件运行时的签名与自己发布时的不同,说明软件被篡改过,这个时候我们就可以让软件中止运行。

获取签名hash值的代码如下:

public int getSignature(String packageName) {        
        PackageManager pm = this.getPackageManager();  
        PackageInfo pi = null;  
        int sig = 0;  
        try {  
            pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);  
            Signature[] s = pi.signatures;  
            sig = s[0].hashCode();    
        } catch (Exception e1) {  
            sig = 0;  
            e1.printStackTrace();  
        }  
        return sig;  
    }

可使用Eclipse自带的调试版密钥文件生成的apk文件的hash值,与上面的函数获取的hash比较,可以判断签名是否一致。


2、校验保护。(PS:通过联网的方式检验)

重编译Andriod软件的实质是重新编译classes.dex文件,代码经过重新编译后,生成的classes.dex文件的hash值已经改变,我们可以检查程序安装后classes.dex文件的Hash值,来判断软件是否被重打包过。

private boolean checkCRC() {  
    boolean beModified = false;  
    long crc = Long.parseLong(getString(R.string.crc));  
    ZipFile zf;  
try {  
    zf = new ZipFile(getApplicationContext().getPackageCodePath());  
    ZipEntry ze = zf.getEntry("classes.dex");  
    Log.d("com.droider.checkcrc", String.valueOf(ze.getCrc()));  
    if (ze.getCrc() == crc) {  
        beModified = true;  
    }   
} catch (IOException e) {  
    e.printStackTrace();  
    beModified = false;  
}  
return beModified;  
  }

五:动态修改dalvik字节码 增加逆向分析的难度,这个技术比较新 搜不到相应的比较详细的技术介绍

六:将核心代码隐藏,增加分析的难度,这个技术有待查询

转载自梦想天涯的博客:http://blog.csdn.net/viviwen123/article/details/9117589

时间: 2024-10-05 11:30:44

逆向Android软件的步骤的相关文章

android 软件开发包的安装流程

开发简单的安卓程序需要:一台装有Android SDK和手机模拟器的计算机.    Android软件开发包(SDK)可以在Windows.Linux.Mac OS X上运行.创建的应用程序也可以在任意的Android设备上.    前期工作:1.Java,所有的Android开发工具都需要.只有一个运行环境(JRE)还不够,需要完整的开发包.(测试安装的版本:在命令提示框中输入Java -version,现实的版本应该高于或者等于1.6.其他数字).2.Eclipse,选择Eclipse ID

Android逆向-Android基础逆向(2-2)

[toc] #0x00 前言##不知所以然,请看Android逆向-Android基础逆向(1)Android逆向-Android基础逆向(2)##以及java系列:Android逆向-java代码基础(1)Android逆向-java代码基础(2)Android逆向-java代码基础(3)Android逆向-java代码基础(4)Android逆向-java代码基础(5)Android逆向-java代码基础(6)Android逆向-java代码基础(7)Android逆向-java代码基础(8

Android上开发Android软件

先吐槽下Windows的Android开发环境配置,能把人恶心到死.为了这个,不小心把房东的楼梯护栏踢歪了.自己装过的人都懂,眼泪哗哗不想说了在Android上配置开发环境超乎寻常的简单,只需要下载一个软件就可以搞定:AIDE (Android java IDE)下载地址1: http://apk.banma.com/v0/app-feed/soft/apk/20140123/106bbb48f9c34982b84114f515958133.apk下载地址2:http://pan.baidu.c

Android 软件工程师----炼成计划

Android了解背景,未来,大致架构 了解部分重要UI组件 学习四大控件 四大控件应用 文件 数据库 网络编程 项目实践 传感器 地理位置服务 音频.视频以及摄像头的使用蓝牙.NFC.网络和Wi-Fi,电话服务和SMS 设计模式 框架 项目实践 Android 软件工程师----炼成计划,布布扣,bubuko.com

[原] Android 自定义View步骤

例子如下:Android 自定义View 密码框 例子 1 良好的自定义View 易用,标准,开放. 一个设计良好的自定义view和其他设计良好的类很像.封装了某个具有易用性接口的功能组合,这些功能能够有效地使用CPU和内存,并且十分开放的.但是,除了开始一个设计良好的类之外,一个自定义view应该: l 符合安卓标准 l 提供能够在Android XML布局中工作的自定义样式属性 l 发送可访问的事件 l 与多个Android平台兼容. Android框架提供了一套基本的类和XML标签来帮您创

Android 软件开发与游戏开发1 至 32系列博文大合集

Android 软件开发与游戏开发1 至 32系列博文大合集Android 软件开发与游戏开发1 至 32系列博文大合集 http://www.qdmm.com/BookReader/17958,65822595.aspxhttp://www.qdmm.com/BookReader/17958,65822597.aspxhttp://www.qdmm.com/BookReader/17958,65822598.aspxhttp://www.qdmm.com/BookReader/17958,65

android软件开发之webView.addJavascriptInterface循环渐进【二】

说明 文章列表 android软件开发之webView.addJavascriptInterface循环渐进[一]: http://www.sollyu.com/android-software-development-webview-addjavascriptinterface-cycle-of-gradual-oneandroid软件开发之webView.addJavascriptInterface循环渐进[二]: http://www.sollyu.com/586 上一篇文章发布之后,得到

【Android】Android软件开发之ListView 详解

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://xys289187120.blog.51cto.com/3361352/657171 ListView的使用方法 ListView是Android软件开发中非常重要组件之一,基本上是个软件基本都会使用ListView ,今天我通过一个demo来教大家怎么样使用ListView组件 绘制出漂亮的列表,说道ListView就不得不说Adapter适配器,因为只有通过Adapter才可

Android - 软件自动更新的实现(转)

在客户端实现更新操作 涉及到三个技术: 1.xml文件的解析 2.HttpURLConnection连接 3.文件流I/O 这里创建一个解析xml文件的服务类:ParXmlService.java [java] view plaincopy package com.xiaowu.news.update; import java.io.InputStream; import java.util.HashMap; import javax.xml.parsers.DocumentBuilder; i