众所周知,android 是开源的,现在市场上反编译别人的劳动果实的人也不少,所以我们也是有必要学习下smail语言,(就是android工程反编译后出的语法语音),看看改怎么给我们的代码 “埋雷” ,才能更好的保护好我们自己的劳动成果。
接下来就让我们来学习下吧~!(事先声明:本人也是初学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
.locals 0
.prologue
.line 20
invoke-direct {p0}, Landroid/app/Activity;->
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;->
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;->
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;->
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;->
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;->
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;->
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 =============================