android 逆向project smail 语法学习

众所周知,android 是开源的。如今市场上反编译别人的劳动果实的人也不少。所以我们也是有必要学习下smail语言,(就是androidproject反编译后出的语法语音),看看改怎么给我们的代码 “埋雷” 。才干更好的保护好我们自己的劳动成果。

接下来就让我们来学习下吧~!(事先声明:本人也是初学smail语言,有介绍不当的地方还请海涵,并请指出。大家一起学习)

package com.example.pushdemo;

import java.io.ByteArrayInputStream;

import java.security.cert.CertificateException;

import java.security.cert.CertificateFactory;

import java.security.cert.X509Certificate;

import android.app.Activity;

import android.content.pm.PackageInfo;

import android.content.pm.PackageManager;

import android.content.pm.Signature;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.Toast;

import com.sogou.udp.push.PushManager;

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initPush();

initViewId();

getSingInfo();

}

private void initViewId() {

Button btn= (Button) findViewById(R.id.btn);

btn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

Toast.makeText(getApplicationContext(), "hello word", Toast.LENGTH_SHORT).show();

}

});

}

public void btn(View v){

Toast.makeText(this, R.string.app_name, Toast.LENGTH_SHORT).show();

}

public void getSingInfo() {

try {

PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);

Signature[] signs = packageInfo.signatures;

Signature sign = signs[0];

parseSignature(sign.toByteArray());

} catch (Exception e) {

e.printStackTrace();

}

}

public void parseSignature(byte[] signature) {

try {

CertificateFactory certFactory = CertificateFactory.getInstance("X.509");

X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(signature));

String pubKey = cert.getPublicKey().toString();

String signNumber = cert.getSerialNumber().toString();

System.out.println("signName:" + cert.getSigAlgName());

System.out.println("pubKey:" + pubKey);

System.out.println("signNumber:" + signNumber);

System.out.println("subjectDN:" + cert.getSubjectDN().toString());

} catch (CertificateException e) {

e.printStackTrace();

}

}

private void initPush() {

PushManager.initialize(this.getApplicationContext());

PushManager.bindPushService(this.getApplicationContext());

}

@Override

protected void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

outState.putString("lastPath", "/sdcard/android123/cwj/test");

System.out.println("lastPath");

}

@Override

protected void onRestoreInstanceState(Bundle savedInstanceState) {

super.onRestoreInstanceState(savedInstanceState);

String cwjString = savedInstanceState.getString("lastPath");

System.out.println(cwjString);

}

}

--------------------------------上面是java 代码相应以下的smail语法------------------------------------

.class public Lcom/example/pushdemo/MainActivity;       、、在虚拟机中,找到这个MainActivity类文件

.super Landroid/app/Activity;                              、、相应的是super.onCreate(savedInstanceState); 在父类中找到Activity这个类

.source "MainActivity.java"                                、、资源文件。MainActivity.java

# direct methods                                        、、定义静态方法的标记

.method public constructor <init>()V                    、、空參数构造函数,看见constructor <init>()V 就要联想到,每个类都有默认的空參构造

.locals 0

.prologue

.line 20

invoke-direct {p0}, Landroid/app/Activity;-><init>()V            、、在每个空參构造里面的第一行也有类似   super()的代码

return-void                                            、、每个方法在最后的时候,都有一个return void 返回,仅仅是编译器省略不写了。事实上默认是有的

.end method                                                、、.end method  方法的结束。这里表示空參构造方法的结束

.method private initPush()V                                、、我自己的私有方法 initPush() 返回值为空 V

.locals 1                                            、、方法中非參寄存器的总数,出如今方法中的第一行。这里表示:寄存器的数量为 1

.prologue

.line 73

invoke-virtual {p0}, Lcom/example/pushdemo/MainActivity;->getApplicationContext()Landroid/content/Context;            、、p0 ==this,在com.example.pushdemo.MainActivity中找到上下文,返回值为Context对象。

move-result-object v0                                、、将上面找到的上下文对象。移动到v0寄存器,交给v0管理

================之后  com/sogou/udp/push/PushManager我都不写为  com.sogou.udp.push.PushManager了,我简写为 PushManager======================

invoke-static {v0}, Lcom/sogou/udp/push/PushManager;->initialize(Landroid/content/Context;)V                        、、在PushManager中,调用静态方法initialize(),将得到的结果值引用保存在v0 寄存器中,返回值为 V

.line 74

invoke-virtual {p0}, Lcom/example/pushdemo/MainActivity;->getApplicationContext()Landroid/content/Context;            、、p0==this,在MainActivity中。调用非静态方法getApplicationContext(),返回值为Context 对象

move-result-object v0                                、、将得到的上下文对象引用。移动到 v0寄存器。

invoke-static {v0}, Lcom/sogou/udp/push/PushManager;->bindPushService(Landroid/content/Context;)V                    、、在PushManager中,调用静态方法bindPushService() 将得到的结果值引用保存在v0 寄存器中的,返回值为 V  (空)

.line 75

return-void                                            、、 默认代码

.end method                                                、、 方法结束

.method private initViewId()V                            、、 调用私有方法 initViewId()返回值为空

.locals 2                                            、、 寄存器个数为2

.prologue

.line 32

const/high16 v1, 0x7f07                                、、 声明一个常量。将值的引用保存到寄存器 v1 中

invoke-virtual {p0, v1}, Lcom/example/pushdemo/MainActivity;->findViewById(I)Landroid/view/View;                    、、在MainActivity中,调用非静态方法findViewById(),參数为int型,返回值为View对象,而且将当前的值的引用保存在v1 寄存器中

move-result-object v0                                、、将v1寄存器中的引用值,移动到v0寄存器

check-cast v0, Landroid/widget/Button;                、、检查类型转换,假设类型转换失败抛出ClassCastException

.line 33

.local v0, btn:Landroid/widget/Button;                、、假设 v0寄存器中引用的值,和命名为常量btn 的值相应上。就将btn转为Button对象

new-instance v1, Lcom/example/pushdemo/MainActivity$1;                                                                、、创建一个内部类实例

invoke-direct {v1, p0}, Lcom/example/pushdemo/MainActivity$1;-><init>(Lcom/example/pushdemo/MainActivity;)V            、、调用类中的静态方法。返回值为V 空

invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V            、、调用非静态方法setOnClickListener(),返回值为V 空

.line 40

return-void                                            、、

.end method                                                、、

# virtual methods                                        、、描写叙述 非静态方法

.method public btn(Landroid/view/View;)V                、、公有方法 but() 返回值为 V

.locals 2                                            、、2 个寄存器

.parameter "v"                                        、、參数    "v"

.prologue

.line 43

const/high16 v0, 0x7f04                                、、声明变量,引用到寄存器 v0

const/4 v1, 0x0                                        、、声明变量,引用到寄存器 v1

invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast;        、、通过Toast。调用静态方法makeText(),须要3个參数。上下文,寄存器v0,v1中所引用的值对象。

move-result-object v0                                、、将调用结果的引用保存在v0寄存器中

invoke-virtual {v0}, Landroid/widget/Toast;->show()V                                                                、、通过寄存器中的对象。调用非静态方法show();

.line 44

return-void

.end method

.method public getSingInfo()V                            、、 调用公有的方法 getSingInfo()返回值为V

.locals 7                                            、、 声明寄存器的个数为 7个

.prologue

.line 48

:try_start_0                                        、、 開始捕获异常

invoke-virtual {p0}, Lcom/example/pushdemo/MainActivity;->getPackageManager()Landroid/content/pm/PackageManager;    、、通过MainActivity调用android.content.pm.PackageManager包中的非静态方法 getPackageManager()

move-result-object v4                                、、 将结果的引用保存在v4 寄存器中

invoke-virtual {p0}, Lcom/example/pushdemo/MainActivity;->getPackageName()Ljava/lang/String;                        、、调用非静态方法getPackageName() 返回值为 String

move-result-object v5                                、、 将当前值的引用保存在 v5寄存器中

const/16 v6, 0x40                                    、、 声明常量 0x40 而且将值的引用保存在 v6中

invoke-virtual {v4, v5, v6}, Landroid/content/pm/PackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;        、、调用非静态方法getPackageInfo(),须要2个參数。一个是寄存器 v5中的值。一个是寄存器 v6中的值,返回值为 PackageInfo对象

(忘了介绍,String是占用2个寄存器的所以这里有 v4,v5 ,v6 3个寄存器的)

move-result-object v1                                、、 将结果对象值的引用保存在 v1寄存器中。

.line 49

.local v1, packageInfo:Landroid/content/pm/PackageInfo;                                                                、、假设v1 寄存器中的值引用,和命名为packageInfo常量的常量,的值相等,就将packageInfo转为PackageInfo对象

iget-object v3, v1, Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature;                    、、通过v1寄存器中的值引用,调用PackageInfo中的常量signatures,将返回一个 Signature 数组。保存在v3中

.line 50

.local v3, signs:[Landroid/content/pm/Signature;    、、假设v3 寄存器中的值引用。和命名为signs的常量,的值相等,就将signs转为Signature对象

const/4 v4, 0x0                                        、、声明常量0x0将值的引用保存在v4寄存器中

aget-object v2, v3, v4                                、、获取一个对象引用数组V2的对象的參考价值。

该阵列由V3引用,并通过V4索引。

.line 51

.local v2, sign:Landroid/content/pm/Signature;        、、假设v2 寄存器中的值引用。和命名为sign的常量,的值相等,就将sign转为Signature对象

invoke-virtual {v2}, Landroid/content/pm/Signature;->toByteArray()[B                                                、、调用Signature的非静态方法toByteArray()返回值为byte[] 数组

move-result-object v4                                、、将结果值的引用保存在 v4 寄存器中

invoke-virtual {p0, v4}, Lcom/example/pushdemo/MainActivity;->parseSignature([B)V                                    、、 在当前MainActivity类中调用parseSignature()方法返回值为V。參数为 byet[] 对象

:try_end_0                                            、、 结束异常的捕获

.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0                                                    、、后面是异常捕获我就不翻译了

.line 55

.end local v1           #packageInfo:Landroid/content/pm/PackageInfo;

.end local v2           #sign:Landroid/content/pm/Signature;

.end local v3           #signs:[Landroid/content/pm/Signature;

:goto_0

return-void

.line 52

:catch_0

move-exception v0

.line 53

.local v0, e:Ljava/lang/Exception;

invoke-virtual {v0}, Ljava/lang/Exception;->printStackTrace()V

goto :goto_0

.end method                                                                                                                、、方法结束

.method protected onCreate(Landroid/os/Bundle;)V        、、onCreate() 方法的開始 返回值为V

.locals 1                                            、、1个寄存器

.parameter "savedInstanceState"                        、、參数为 savedInstanceState

.prologue

.line 24

invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V                                        、、调用父类的onCreate()方法,返回值为V

.line 25

const/high16 v0, 0x7f03                                、、声明常量 0x7f03    将值的引用 保存在 v0寄存器中

invoke-virtual {p0, v0}, Lcom/example/pushdemo/MainActivity;->setContentView(I)V                                    、、调用非静态方法 setContentView(參数,v0寄存器中的值 )

.line 26

invoke-direct {p0}, Lcom/example/pushdemo/MainActivity;->initPush()V                                                、、调用 initPush()方法

.line 27

invoke-direct {p0}, Lcom/example/pushdemo/MainActivity;->initViewId()V                                                、、调用 initViewId()方法

.line 28

invoke-virtual {p0}, Lcom/example/pushdemo/MainActivity;->getSingInfo()V                                            、、调用 getSingInfo()方法

.line 29

return-void

.end method                                                                                                                、、方法结束

.method protected onRestoreInstanceState(Landroid/os/Bundle;)V

.locals 2                                                                                                            、、2个寄存器

.parameter "savedInstanceState"

.prologue

.line 86

invoke-super {p0, p1}, Landroid/app/Activity;->onRestoreInstanceState(Landroid/os/Bundle;)V

.line 87

const-string v1, "lastPath"                                                                                            、、把lastPath的引用。 存放到寄存器 v1中

invoke-virtual {p1, v1}, Landroid/os/Bundle;->getString(Ljava/lang/String;)Ljava/lang/String;

move-result-object v0

.line 88

.local v0, cwjString:Ljava/lang/String;

sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;

invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

.line 89

return-void

.end method

--------------------------------------------------------------剩下的自己联系看吧---------------------------------------------------------

.method protected onSaveInstanceState(Landroid/os/Bundle;)V

.locals 2

.parameter "outState"

.prologue

.line 79

invoke-super {p0, p1}, Landroid/app/Activity;->onSaveInstanceState(Landroid/os/Bundle;)V

.line 80

const-string v0, "lastPath"

const-string v1, "/sdcard/android123/cwj/test"

invoke-virtual {p1, v0, v1}, Landroid/os/Bundle;->putString(Ljava/lang/String;Ljava/lang/String;)V

.line 81

sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

const-string v1, "lastPath"

invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

.line 82

return-void

.end method

.method public parseSignature([B)V

.locals 8

.parameter "signature"

.prologue

.line 59

:try_start_0                                                            、、异常開始

const-string v5, "X.509"

invoke-static {v5}, Ljava/security/cert/CertificateFactory;->getInstance(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;

move-result-object v1

.line 60

.local v1, certFactory:Ljava/security/cert/CertificateFactory;

new-instance v5, Ljava/io/ByteArrayInputStream;

invoke-direct {v5, p1}, Ljava/io/ByteArrayInputStream;-><init>([B)V

invoke-virtual {v1, v5}, Ljava/security/cert/CertificateFactory;->generateCertificate(Ljava/io/InputStream;)Ljava/security/cert/Certificate;                、、 smail语法中的返回值。通常情况下都是返回父节点对象

move-result-object v0

check-cast v0, Ljava/security/cert/X509Certificate;

.line 61

.local v0, cert:Ljava/security/cert/X509Certificate;                    、、真心认为这个是3目运算符

invoke-virtual {v0}, Ljava/security/cert/X509Certificate;->getPublicKey()Ljava/security/PublicKey;

move-result-object v5                                                    、、将引用存一份到 v5寄存器

invoke-virtual {v5}, Ljava/lang/Object;->toString()Ljava/lang/String;    、、将v5寄存器中的 值toString()

move-result-object v3

.line 62

.local v3, pubKey:Ljava/lang/String;

invoke-virtual {v0}, Ljava/security/cert/X509Certificate;->getSerialNumber()Ljava/math/BigInteger;

move-result-object v5

invoke-virtual {v5}, Ljava/math/BigInteger;->toString()Ljava/lang/String;

move-result-object v4

.line 63

.local v4, signNumber:Ljava/lang/String;

sget-object v5, Ljava/lang/System;->out:Ljava/io/PrintStream;

new-instance v6, Ljava/lang/StringBuilder;

const-string v7, "signName:"

invoke-direct {v6, v7}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

invoke-virtual {v0}, Ljava/security/cert/X509Certificate;->getSigAlgName()Ljava/lang/String;

move-result-object v7

invoke-virtual {v6, v7}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v6

invoke-virtual {v6}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v6

invoke-virtual {v5, v6}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

.line 64

sget-object v5, Ljava/lang/System;->out:Ljava/io/PrintStream;

new-instance v6, Ljava/lang/StringBuilder;

const-string v7, "pubKey:"

invoke-direct {v6, v7}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

invoke-virtual {v6, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v6

invoke-virtual {v6}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v6

invoke-virtual {v5, v6}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

.line 65

sget-object v5, Ljava/lang/System;->out:Ljava/io/PrintStream;

new-instance v6, Ljava/lang/StringBuilder;

const-string v7, "signNumber:"

invoke-direct {v6, v7}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

invoke-virtual {v6, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v6

invoke-virtual {v6}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v6

invoke-virtual {v5, v6}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

.line 66

sget-object v5, Ljava/lang/System;->out:Ljava/io/PrintStream;

new-instance v6, Ljava/lang/StringBuilder;

const-string v7, "subjectDN:"

invoke-direct {v6, v7}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

invoke-virtual {v0}, Ljava/security/cert/X509Certificate;->getSubjectDN()Ljava/security/Principal;

move-result-object v7

invoke-interface {v7}, Ljava/security/Principal;->toString()Ljava/lang/String;

move-result-object v7

invoke-virtual {v6, v7}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v6

invoke-virtual {v6}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v6

invoke-virtual {v5, v6}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

:try_end_0                                                                    、、异常结束

.catch Ljava/security/cert/CertificateException; {:try_start_0 .. :try_end_0} :catch_0                    、、捕获异常就不用看了

.line 70

.end local v0           #cert:Ljava/security/cert/X509Certificate;

.end local v1           #certFactory:Ljava/security/cert/CertificateFactory;

.end local v3           #pubKey:Ljava/lang/String;

.end local v4           #signNumber:Ljava/lang/String;

:goto_0

return-void

.line 67

:catch_0

move-exception v2

.line 68

.local v2, e:Ljava/security/cert/CertificateException;

invoke-virtual {v2}, Ljava/security/cert/CertificateException;->printStackTrace()V

goto :goto_0

.end method

========================最后附上一片文章  http://www.blogjava.net/midea0978/archive/2012/01/04/367847.html  =============================

时间: 2024-08-07 21:19:58

android 逆向project smail 语法学习的相关文章

android 逆向工程 smail 语法学习

众所周知,android 是开源的,现在市场上反编译别人的劳动果实的人也不少,所以我们也是有必要学习下smail语言,(就是android工程反编译后出的语法语音),看看改怎么给我们的代码 "埋雷" ,才能更好的保护好我们自己的劳动成果. 接下来就让我们来学习下吧~!(事先声明:本人也是初学smail语言,有介绍不当的地方还请海涵,并请指出,大家一起学习) ========================最后附上一片文章  http://www.blogjava.net/midea09

android smail 语法学习之二

下面是if 语句 for 语句在smali中写法: 条件跳转分支: "if-eq vA, vB, :cond_**"   如果vA等于vB则跳转到:cond_**"if-ne vA, vB, :cond_**"   如果vA不等于vB则跳转到:cond_**"if-lt vA, vB, :cond_**"    如果vA小于vB则跳转到:cond_**"if-ge vA, vB, :cond_**"   如果vA大于等于vB则

Android Cocos2dx引擎 prv.ccz/plist/so等优化缓存文件,手把手ida教你逆向project反编译apk库等文件

前段时间在 Android play 上看到一个非常牛逼的 3D 动态天气预报,效果真的非常炫.二话不说动手 dex2jar.bat/apktool 发现这并没 有什么卵用,在核心的地方看见 native 字段果断放弃了治疗,立刻转向 so 的逆向project.发现了cocos2dx so 引擎,搜噶.我就说 嘛这么炫酷的效果, Android 源代码是做不了的.即使达到了这样的程度,预计性能也特别不好.由于那个动态效果是不会循环播放 的,也就是不会反复.是自己绘制的依据资源文件,在反编译的

Android开发project师,前行路上的14项技能

导读: 你是否曾渴望回到宋朝? 或者什么朝,反正就是男耕女织的古代. 哦,那时的首都在汴梁(开封),房价想必没有如今这么高,工作?无非就是给你把锄头,去,种地去.夕阳西下了,麦子垛后,你和翠姑搂抱在一起,那时的你,生活的简单而美好. 看看如今的你,一个刚入门的安卓开发project师,没有信用卡,没有她,没有24小时热水的家.你想念你的锄头和翠姑(或麦垛),可你回不去了.你握在手中的安卓手机,冰冷如铁,你不知道怎样在这4寸屏的小东西上创出一片天地. 你不用感到不知所措和困惑,技术就是你安身立命的

Android逆向之旅---静态分析技术来破解Apk

一.前言 从这篇文章开始我们开始我们的破解之路,之前的几篇文章中我们是如何讲解怎么加固我们的Apk,防止被别人破解,那么现在我们要开始破解我们的Apk,针对于之前的加密方式采用相对应的破解技术,Android中的破解其实大体上可以分为静态分析和动态分析,对于这两种方式又可以细分为Java层(smail和dex)和native层(so).所以我们今天主要来讲解如何通过静态分析来破解我们的apk,这篇文章我们会通过破解Java层和native层的例子来讲解. 二.准备工作 在开始今天的文章之前,我们

Android 逆向初探(一)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Helvetica; color: #000000 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Helvetica; color: #000000; min-height: 13.0px } span.s1 { } span.Apple-tab-span { white-space: pre } 逆向分析是一门技术,也是一门艺

Android逆向分析初体验

一.    准备知识 1.             懂Java Android开发. 2.             懂NDK ,C 语言 Android 动态链接库.SO开发. 3.             懂Android反编译Smali 语法. 4.             懂adb 和 jdb 等等工具使用. 5.             懂IDA 调试(远程动态调试APK和本地静态调试.SO文件) 6.             懂Arm汇编语法(因为移动设备芯片是Arm架构的,不是Int

android逆向入门及工具下载

本文所用到的工具下载: 链接:http://pan.baidu.com/s/1i3uw4NN 密码:8hz5 最近在研究如何逆向android的app,于是就有了这篇android逆向入门的总结回馈互联网. 由于Android的.apk文件实际上就是一个zip文件,修改文件后缀后直接可以打开,效果如下图所示: 里面包含了的文件有: META-INF:这个文件夹是用于保存签名文件,确保包的完整性的 res:apk所要用的资源文件,都是原封不动地保存,我们可以直接提取出来,做汉化时就可以直接阅读st

Android逆向从未如此简单

哈,又标题党了..不过我一定竭尽所能,写一篇最亲民的入门文章. 本文仅供学习交流之用,切勿用于非法用途,读者若运用所学知识,进行非法任何商业目的或者非法牟利,一切责任由操作者自行承担,与本人无关.希望读者仅仅从了解原理,保护自身APP尽量减少危害出发来阅读本文. 本文发布自wing的地方酒馆,转载请注明出处. 本文以一个最简单的例子,来教给大家Android逆向入门的一些知识.所以首先我们需要准备一个APK,做的简单一些,就是一个EditText,已经一个按钮,模拟验证注册码. 当验证码填写正确