转载

Android逆向:初探Android逆向

逆向工程(又称逆向技术),是一种产品设计技术再现过程,即对一项目标产品进行逆向分析及研究,从而演绎并得出该产品的处理流程、组织结构、功能特性及技术规格等设计要素,以制作出功能相近,但又不完全一样的产品。逆向工程源于商业及军事领域中的硬件分析。其主要目的是在不能轻易获得必要的生产信息的情况下,直接从成品分析,推导出产品的设计原理。

逆向工程可能会被误认为是对知识产权的严重侵害,但是在实际应用上,反而可能会保护知识产权所有者。例如在集成电路领域,如果怀疑某公司侵犯知识产权,可以用逆向工程技术来寻找证据。

这里我们以安卓项目开始探索逆向工程之路

逆向工具

工欲善其身,必先利其器。

反编译代码的工具下载:

  • dex2jar: 把dex文件转成jar文件下载地址: https://sourceforge.net/projects/dex2jar/files/
  • jd-gui: 这个工具用于将jar文件转换成java代码下载地址: http://jd.benow.ca/

反编译资源的工具:

  • APKTool: 本文重要工具,APK逆向工具,使用简单下载地址: http://ibotpeaches.github.io/Apktool/install/

    这里简单介绍下大概流程,首先把后缀为.apk的文件改为.zip的一个压缩文件,方便解压。dex2jar和jd-gui配套使用,用于逆向代码部分,APKTool用于逆向res文件夹下的图片布局等部分。

新建一个简单的项目

新建一个项目,名字是 Androidrefirst,实现的逻辑是在输入框内填写 2019之后 点击按钮跳转到成功页面。

主要代码如下

package com.example.androidrefirst;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private EditText code;
    private Button btn_verify;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    private void init() {
        code = findViewById(R.id.editText);
        btn_verify = findViewById(R.id.button);
        btn_verify.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String verifyCode=code.getText().toString().trim();
                if(verifyCode.equals("2019")){
                    Intent intent=new Intent(MainActivity.this,SuccessActivity.class);
                    startActivity(intent);
                }else {
                    Toast.makeText(MainActivity.this,"验证码错误!", Toast.LENGTH_LONG).show();
                }
            }
        });
    }
}

生成 apk安装包 app-release.apk

逆向 apk

解压apk得到 classes.dex 文件

需要用到的是dex2jar包里面的三个文件(当前是在windows环境下,Mac环境用对应的.sh文件):

d2j_invoke.bat

d2j-dex2jar.bat

lib

将这三个文件复制到一个空的文件夹内,将刚才.apk解压后的classes.dex文件也一起复制到这里

使用命令 d2j-dex2jar.bat classes.dex 得到 jar文件

使用 jd-gui.exe 打开jar文件看到代码

可以看到我们的代码

package com.example.androidrefirst;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
  private Button btn_verify;
  
  private EditText code;
  
  private void init() {
    this.code = (EditText)findViewById(2131230782);
    this.btn_verify = (Button)findViewById(2131230755);
    this.btn_verify.setOnClickListener(new View.OnClickListener() {
          public void onClick(View param1View) {
            if (MainActivity.this.code.getText().toString().trim().equals("2019")) {
              Intent intent = new Intent((Context)MainActivity.this, SuccessActivity.class);
              MainActivity.this.startActivity(intent);
            } else {
              Toast.makeText((Context)MainActivity.this, ", 1).show();
            } 
          }
        });
  }
  
  protected void onCreate(Bundle paramBundle) {
    super.onCreate(paramBundle);
    setContentView(2131427356);
    init();
  }
}

对照着自己的手写的代码,已经差不离十了,对于想要代码思路的我们来说,到这里已经基本可以摸透他的逻辑。

反编译res资源部分

apktool下载后会有两个文件,一个.jar(例如apktool_2.3.3.jar 需要把名字改成apktool.jar) 一个apktool.bat 。

apktool d

同刚才一样在cmd命令下进入刚才文件夹(同样可以新建一个),连同我们刚才那个后缀为apk的安装包一起放入,输入如下命令

apktool d app-release.apk  # 此处app-release为apk名称

得到一个新的app-release(对应apk名称)文件夹

这个app-release文件夹下会得到若干文件,主要内容介绍如下:

  • AndroidManifest.xml:描述文件
  • res:资源文件
  • smail:反编译出来的所有代码,语法与java不同,类似汇编,是Android虚拟机所使用的寄存器语言
    到此我们想要的都有了。下一步就是实现我们想法的时候了。

修改原代码逻辑

我们只需要修改if后面的判断条件,设置为否即可if (!MainActivity.this.code.…),这样就成功绕过了条件约束。

接下来还有一部很重要那就是修改smali文件,找到MainActivity$1.smali这个文件用代码查看工具打开

找到这个if-eqz 修改成if-nez (nez对应为非,符号“!”),到这里要修改的部分都成功了,最后一步要做的就是重新打包了。当然对smali语法感兴趣的可以一起探讨学习。

重新打包

在apktool文件夹路径的cmd下输入:

apktool b [文件夹] -o test2.apk   #(test2为新apk名称,[文件夹]为对应的有修改需要打包的文件夹)
#例如:我当前就可以这样写  apktool b [E:/tools/apktool/app-release] -o test2.apk

至此,我们的目标apk文件已经生成,当然如果你想装到你自己手机上还需要重新签名一下。

重新签名

首先我们需要一个用于签名的.keystore文件,生成命令如下(这里我们假设生成的是demo.keystore)。

keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore
# (cmd到apktool文件夹下跟待签名的apk放同个文件夹内便于操作)

这里我们利用Java JDK提供的一个jarsigner进行签名,在刚才的cmd下继续操作,输入:

jarsigner -verbose -keystore demo.keystore test2.apk demo.keystore

以上。我们目的apk已经可以投入使用,如果需要更快更好的体验还需要进行一次字节对齐的操作(后续分析)。

参考:

https://blog.csdn.net/micaaa/article/details/82426710

原文  http://blog.yahui.wang/2020/04/21/android-reverse-engineering-first/
正文到此结束
Loading...