apk伪造签名_如何反编译app

apk伪造签名_如何反编译app反编译apk过程反编译目的需要的环境和工具工具环境反编译流程apktool解包导出apk的源代码修改Smali代码无法选中文本框添加开机自启Smali源码Java源码apktool打包apk签名模拟器安装apk验证apk反编译目的反编译apk:1  对apk应用进行激活成功教程并重新打包,反编译就是逆向的过程。  Androidapk是用高级语言源代码,通常是Java,对apk的逆向智能转换成汇编语言,即Smali。  这次反编译的目的是为了学习apk的软件安全,了解apk的编译过程。现有一个apk的

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

反编译目的

反编译apk:1

  对apk应用进行激活成功教程并重新打包,反编译就是逆向的过程。
  Android apk是用高级语言源代码,通常是Java,对apk的逆向智能转换成汇编语言,即Smali
  这次反编译的目的是为了学习apk的软件安全,了解apk的编译过程。

现有一个apk的开启界面如下(夜神模拟器打开):
test.apk首页

实现:
1. 屏蔽"服务器地址"的文本框,让用户无法选中文本框。
2. 为该apk添加开机启动。

需要的环境和工具

工具

以上工具资源均已存网盘:https://pan.baidu.com/s/1z7R2w9_vCxspI5FNSUM2GQ  提取码:keu8

  注:夜神模拟器的安装目录下有自带的adb.exe,本案例将使用adb.exe模拟apk的安装,
  建议把adb.exe添加到环境变量里,方便运行

环境

  • Java
    Android逆向工程基本都要用到Java语言,并且jar文件的运行依赖于Java环境,所以需要安装Java的运行时环境。
     通常用到的Java分为两种,运行时环境JRE和开发工具JDK,在Oracle官网可下载。
     这里要明确需要哪种环境,如果需要运行Java程序,只需安装JRE就可以了。如果需要编写Java程序,需要安装JDK

     本案例只需要Java的运行时环境JRE,安装完成后需要手动给JRE目录添加到环境变量。

    配置环境变量参考:https://blog.csdn.net/iiiiiilikangshuai/article/details/80289268
    Java环境介绍:https://www.cnblogs.com/lsw9/p/8685623.html

  • Eclipse
    Eclipse是编写Java的编辑器(IDE),本案例使用Eclipse IDE来修改Smali代码片段
     官网下载地址:https://www.eclipse.org/downloads/packages/
     Eclipse支持多种编程语言,用的Java语言就下载Java EE IDE
    Java EE IDE下载地址

反编译流程

apk反编译大致过程如下:

   1. 用apktool对apk进行解包,解包后的文件夹更名为test,文件夹导入Eclipse
   
   2. test.apk用WinRAR打开,提取classes.dex文件到dex2jar文件夹

   3. 当前目录下打开cmd,执行d2j-dex2jar.bat classes.dex -o test.jar 得到test.jar 
   
   4. 使用jd-gui打开test.jar,  File -> Save All Sources  重命名test.src.zip,导出源文件
   
   5. 解压test.src.zip,将test.src文件夹导入Eclipse
   
   6. Eclipse对应 test(Smali汇编码) 和 test.src(Java源代码) , 修改Smali片段实现Android开机自启
   
   7. apktool对test重新打包,使用autosign工具或android_nixiang工具对test.apk进行签名
   
   8. 打开夜神模拟器测试安装test_sign.apk
   
   9. 使用adb.exe模拟发送Android开机的广播报文测试开机自启

apktool解包

将test.apk复制到apktool目录下执行cmd命令

apktool.bat d test.apk -o test
解析:apktool.bat  d:解包  test.apk:需要解包的apk文件  -o:新建目录  test:目录名称 

apktool解包
导入到Eclipse File -> Open Projects from File System
eclipse导入test

加壳或混淆过的apk提取出来的目录结构跟本案例的不同,本案例用的是没有加壳也没有混淆的apk。
本案例提取后的目录结构:(目录结构不完全相同,看apk的结构)

——— test
 |———— lib
 |———— original
 |———— res
 |———— smali
 |———— unknown
 |———— AndroidManifest.xml
 |———— apktool.yml

lib:
 存放.so后缀的库文件

original:
 存放软件的签名信息,保证apk包的完整性,META-INF/CERT.RSA文件存放apk的数字签名信息。

res:
 存放apk的所有静态资源,如图片、xml等。

smali:
 存放apk反编译后的汇编语言文件。修改apk的内容可直接在这里边修改。

unknown:
 存放一些txt文本文件和没有编译过的源文件等。

AndroidManifest.xml:
 项目的总配置文件,也是项目的入口文件,记录应用中所使用的各种组件。

apktool.yml:
 记录apk的版本号、文件名、资源文件数量等等信息。

导出apk的源代码

test.apk用WinRAR打开,提取里边的classes.dex文件到dex2jar目录,执行cmd命令

d2j-dex2jar.bat classes.dex -o test.jar
解析: d2j-dex2jar.bat  classes.dex:需要转换的文件  -o:新建文件  test.jar:文件名称

dex2jar转换
jd-gui打开test.jar

jd-gui打开test.jar
File -> Save All Sources 重命名test.src.zip,导出源文件

jd-gui导出源代码
jd-gui导出源代码
解压test.src.zip并导入到Eclipse   (图片省略)

修改Smali代码

打开Eclipse,test.src是apk的源代码,test是apk编译后的源代码。
apk伪造签名_如何反编译app

首先打开test目录的AndroidManifest.xml,找到以下代码片段,就是apk的入口文件。

<activity android:label="@string/app_name" android:name="com.test.ui.LoginActivity">
	<intent-filter>
		<action android:name="android.intent.action.MAIN"/>
		<category android:name="android.intent.category.LAUNCHER"/>
	</intent-filter>
</activity>

android:name字段的值就是该apk的入口文件
在Eclipse里按Ctrl+H查找LoginActivity, 选择File Search模式查找。
apk伪造签名_如何反编译app

Eclipse分屏打开.java.smali的文件, 双击文件隐藏Project Explorer
apk伪造签名_如何反编译app

无法选中文本框

让用户无法选中指定的文本框,我用的方法是在xml文件里找到对应的控件里添加android:focusable="false"属性。
apk的界面文件通常放在res/layout文件夹里。

通过全局查找"服务器地址"找到对应的<string name="server_address">服务器地址</string>标签。
再全局查找server_address字段,找到xml文件里对应的EditText控件。

<LinearLayout android:layout_gravity="center_horizontal" android:orientation="horizontal" android:layout_width="600.0dip" android:layout_height="wrap_content" android:layout_marginTop="20.0dip">
	<TextView android:textSize="23.0dip" android:textStyle="bold" android:textColor="@color/white" android:gravity="right" android:id="@id/hosturl_textview" android:layout_width="150.0dip" android:layout_height="wrap_content" android:text="@string/server_address" />
	<EditText android:textSize="23.0sp" android:textColor="@color/white" android:id="@id/hosturl_edittext" android:background="@color/color_666666" android:padding="5.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" />
</LinearLayout>

其中android:text="@string/server_address"就是EditText控件引用了<string name="server_address">服务器地址</string>标签的值。
EditText控件标签的最后添加android:focusable="false"属性,即可实现无法选中该文本框。

添加开机自启

当Android启动时,会发出一个系统广播,内容为ACTION_BOOT_COMPLETED,它的字符串常量表示为android.intent.action.BOOT_COMPLETED。只要在程序中“捕捉”到这个消息,再启动之即可。记住,Android框架说:Don’t call me, I’ll call you back。我们要做的是等到接收这个消息,而实现的手段就是实现一个BroadcastReceiver

实现BroadcastReveiver需要根据Java源码去分析Smali源码,并在合适的位置添加相应的Smali源码,实现开机自启。
首先在test的UI层,即LoginActivity所在的目录。添加StartBroadcastReceiver.smaliStartBroadcastReceiver$1.smali两个文件,源码如下:

Smali源码

StartBroadcastReceiver.smali

.class public Lcom/test/ui/StartBroadcastReceiver;
.super Landroid/content/BroadcastReceiver;
.source "StartBroadcastReceiver.java"


# instance fields
.field private mHandler:Landroid/os/Handler;


# direct methods
.method public constructor <init>()V
    .locals 2

    .prologue
    .line 17
    invoke-direct { 
   p0}, Landroid/content/BroadcastReceiver;-><init>()V

    .line 21
    new-instance v0, Landroid/os/Handler;

    invoke-static { 
   }, Landroid/os/Looper;->getMainLooper()Landroid/os/Looper;

    move-result-object v1

    invoke-direct { 
   v0, v1}, Landroid/os/Handler;-><init>(Landroid/os/Looper;)V

    iput-object v0, p0, Lcom/test/ui/StartBroadcastReceiver;->mHandler:Landroid/os/Handler;

    return-void
.end method


# virtual methods
.method public onReceive(Landroid/content/Context;Landroid/content/Intent;)V
    .locals 6
    .param p1, "context"    # Landroid/content/Context;
    .param p2, "intent"    # Landroid/content/Intent;

    .prologue
    const/4 v3, 0x0

    .line 26
    invoke-virtual { 
   p2}, Landroid/content/Intent;->getAction()Ljava/lang/String;

    move-result-object v2

    const-string v3, "android.intent.action.BOOT_COMPLETED"

    invoke-virtual { 
   v2, v3}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v2

    if-eqz v2, :cond_0

    .line 27
    iget-object v2, p0, Lcom/test/ui/StartBroadcastReceiver;->mHandler:Landroid/os/Handler;

    new-instance v3, Lcom/test/ui/StartBroadcastReceiver$1;

    invoke-direct { 
   v3, p0, p1}, Lcom/test/ui/StartBroadcastReceiver$1;-><init>(Lcom/test/ui/StartBroadcastReceiver;Landroid/content/Context;)V

    const-wide/16 v4, 0x2710

    invoke-virtual { 
   v2, v3, v4, v5}, Landroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z

    .line 36
    :cond_0
    return-void
.end method

StartBroadcastReceiver$1.smali

.class Lcom/test/ui/StartBroadcastReceiver$1;
.super Ljava/lang/Object;
.source "StartBroadcastReceiver.java"

# interfaces
.implements Ljava/lang/Runnable;


# annotations
.annotation system Ldalvik/annotation/EnclosingMethod;
    value = Lcom/test/ui/StartBroadcastReceiver;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = null
.end annotation


# instance fields
.field final synthetic this$0:Lcom/test/ui/StartBroadcastReceiver;

.field final synthetic val$context:Landroid/content/Context;


# direct methods
.method constructor <init>(Lcom/test/ui/StartBroadcastReceiver;Landroid/content/Context;)V
    .locals 0
    .param p1, "this$0"    # Lcom/test/ui/StartBroadcastReceiver;

    .prologue
    .line 31
    iput-object p1, p0, Lcom/test/ui/StartBroadcastReceiver$1;->this$0:Lcom/test/ui/StartBroadcastReceiver;

    iput-object p2, p0, Lcom/test/ui/StartBroadcastReceiver$1;->val$context:Landroid/content/Context;

    invoke-direct { 
   p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method


# virtual methods
.method public run()V
    .locals 3

    .prologue
    .line 34
    new-instance v0, Landroid/content/Intent;

    iget-object v1, p0, Lcom/test/ui/StartBroadcastReceiver$1;->val$context:Landroid/content/Context;

    const-class v2, Lcom/test/ui/LoginActivity;

    invoke-direct { 
   v0, v1, v2}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V

    .line 35
    .local v0, "mBootIntent":Landroid/content/Intent;
    const/high16 v1, 0x10000000

    invoke-virtual { 
   v0, v1}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;

    .line 36
    iget-object v1, p0, Lcom/test/ui/StartBroadcastReceiver$1;->val$context:Landroid/content/Context;

    invoke-virtual { 
   v1, v0}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V

    .line 37
    return-void
.end method

Java源码

StartBroadcastReceiver.java

package com.test.ui;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;

public class StartBroadcastReceiver extends BroadcastReceiver
{ 
   
  private Handler mHandler = new Handler(Looper.getMainLooper());

  public void onReceive(Context paramContext, Intent paramIntent)
  { 
   
    if (paramIntent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
    { 
   
      this.mHandler.postDelayed(new Runnable(paramContext)
      { 
   
        public void run()
        { 
   
          Intent localIntent = new Intent(this.val$context, LoginActivity.class);
          localIntent.setFlags(268435456);
          this.val$context.startActivity(localIntent);
        }
      }
      , 10000L);
    }
  }
}

/* Location: E:\apk反编译\jd-gui\test.src.jar * Qualified Name: com.test.ui.StartBroadcastReceiver * JD-Core Version: 0.6.0 */

apktool打包

添加好Smali代码后,使用apktool对test重新打包

apktool b test
解析: apktool  b:打包  test:需要打包的文件夹名称

apktool打包
打包之后会在test/dist目录下生成test.apk   (图片省略)

apk签名

本案例使用android_nixiang工具完成apk的签名
apk伪造签名_如何反编译app

autosign工具的使用需要.keystore .pk8 .pem三个文件,参考:https://blog.csdn.net/zhuweiming9202027/article/details/81501981

到这里就完成了apk的反编译,打包,签名过程了。。

模拟器安装apk

夜神模拟器参考命令如下

adb devices   				 			 # 查看连接的模拟器设备
adb kill-server							 # 删除已连接的所有设备端口
adb connect 127.0.0.1:62001  			 # 使用62001端口连接模拟器设备
adb root								 # 获取模拟器设备root权限
adb push [本地文件路径] [模拟器文件路径]   # 上传文件到模拟器设备
adb pull [模拟器文件路径] [本地文件路径]   # 下载模拟器设备文件到本地
adb shell 								 # 进入模拟器的shell
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED  # 模拟发送安卓的开机广播报文

验证apk

参考来源:
 Smali语法: https://www.cnblogs.com/lee0oo0/p/3728271.html
 apk反编译技巧: https://www.cnblogs.com/geeksongs/p/10864200.html
 apk反编译再打包: https://blog.csdn.net/sxk874890728/article/details/80486223
 android开机自启: https://blog.csdn.net/u012611644/article/details/80542119
 adb shell模拟发送开机广播: https://blog.csdn.net/mqdxiaoxiao/article/details/88854923


  1. 对apk应用进行激活成功教程并重新打包,反编译就是逆向的过程。 ↩︎

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/193083.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • intellij idea 控制台中文乱码_idea server控制台乱码

    intellij idea 控制台中文乱码_idea server控制台乱码本人下载了一开源工程,该工程采用的是maven进行编译,在导入到itellijidea后,按如下图配置好maven编译环境但是采用配置好的maven进行编译时,在run的控制台输出窗口中出现乱码,导致无法编译,由于工程是utf-8编码,所以按如下方式配置了工程的编码网上run控制台输出乱码的解决思路如下:1)参照上面配置工程编码的方式将GlobalEncoding/Proj…

    2022年8月29日
    3
  • pytest接口自动化测试框架_什么模块需要做接口自动化

    pytest接口自动化测试框架_什么模块需要做接口自动化pytest接口自动化完整框架思维导图

    2022年7月29日
    3
  • HTTP、HTTPS常用的默认端口号

    HTTP、HTTPS常用的默认端口号端口号标识了一个主机上进行通信的不同的应用程序。1.HTTP协议代理服务器常用端口号:80/8080/3128/8081/90982.SOCKS代理协议服务器常用端口号:10803.FTP(文件传输)协议代理服务器常用端口号:214.Telnet(远程登录)协议代理服务器常用端口号:23HTTP服务器,默认端口号为80/tcp(木马Executor开放此端口)HTTPS(securelytran…

    2022年6月14日
    71
  • 求生之路2ping高_DDS信号源

    求生之路2ping高_DDS信号源问答时间:2020年12月17日嘉宾简介:高少星:萌宝集团创始人、稻荷资本创始合伙人、《好玩的书》作者。曾任顺为资本董事总经理、百度高级投资经理,是好大夫、丁香园、一点资讯、宝宝巴士、I…

    2022年10月26日
    0
  • 整理了十五道为数不多的tomcat面试题,错过就没了!

    整理了十五道为数不多的tomcat面试题,错过就没了!当容器启动时,会读取在webapps目录下所有的web应用中的web.xml文件,然后对xml文件进行解析,并读取servlet注册信息。然后,将每个应用中注册的servlet类都进行加载,并通过反射的方式实例化。(有时候也是在第一次请求时实例化)在servlet注册时加上如果为正数,则在一开始就实例化,如果不写或为负数,则第一次请求实例化。

    2022年6月6日
    29
  • bi报表开发工具_三大报表的勾稽关系图

    bi报表开发工具_三大报表的勾稽关系图为什么需要电子表格国内目前的同类产品中都有报表工具,这些工具大部分都有一个类似Excel的操作界面:单元格、快捷键、工具栏等典型设计工具要求。这些工具要么需要有专业的背景,或者专业的工程师提供支持,要么学习成本高,调整报表样式十分麻烦。作为报表开发人员而言,花费大量时间去学习一个新工具是一件非常苦恼的事情,我们能否直接把exce作为报表设计的工具呢?基于这个思路,诞生了我们的Spreadsheet…

    2022年10月19日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号