- Dex2jar: transfer DEX file to jar file, download address: https://sourceforge.net/projects/dex2jar/files/
- JD GUI: used to convert jar files into java code. Download address: http://jd.benow.ca/
- APKTool: APK reverse tool, download address: http://ibotpeaches.github.io/Apktool/install/
annotation # annotations .annotation [ Annotation Properties ] < Annotation class name> [ Annotation field = value] .end annotation
Private method # direct methods / / comments added .method <Access rights> [ Modifier keyword] < Method prototype> <.locals> //Specifies the number of local variables to use [.parameter] //Specifies the parameters of the method [.prologue] //The beginning of the code is specified, and the confused code may remove the instruction [.line] //Specifies the line number of the instruction in the source code <Code body> .end method
example # instance fields .field < Access rights> [ Modifier keyword] < Field name>:< Field type>
package/name/ObjectName;->methodName(III)Z package/name/ObjectName:A class methodName: Method name III: Parameter type Z: Return value
What you can do:
1. Skip login by modifying smali
2. Get the token in the code
3. Sinicization
This can be done by modifying the language in the values folder or directly replacing the Unicode code in smali.
4. Go advertising
Skip the ad page or set the ad layout to 0dp
package com.jxd.pangolinadtest; import android.content.Intent; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.View; import android.widget.LinearLayout; import androidx.annotation.MainThread; import androidx.appcompat.app.AppCompatActivity; import com.bytedance.sdk.openadsdk.AdSlot; import com.bytedance.sdk.openadsdk.TTAdNative; import com.bytedance.sdk.openadsdk.TTAdSdk; import com.bytedance.sdk.openadsdk.TTSplashAd; /** * Open screen advertising */ public class SplashActivity extends AppCompatActivity { private LinearLayout mSplashContainer = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); initViews(); initData(); } private void initViews() { mSplashContainer = findViewById(R.id.splash_container); } private void initData() { //To create a TTAdNative object, createadnative (context) context needs to pass in an Activity object TTAdNative mTTAdNative = TTAdSdk.getAdManager().createAdNative(this); DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); AdSlot adSlot = new AdSlot.Builder() .setCodeId("887446435") .setImageAcceptedSize(displayMetrics.widthPixels, displayMetrics.heightPixels) .build(); mTTAdNative.loadSplashAd(adSlot, new TTAdNative.SplashAdListener() { //Failed to request advertisement @Override @MainThread public void onError(int code, String message) { //The developer handles the logic of jumping to the APP main page gotoMain(); } //Request advertisement timeout @Override @MainThread public void onTimeout() { //The developer handles the logic of jumping to the APP main page gotoMain(); } //Ad request succeeded @Override @MainThread public void onSplashAdLoad(TTSplashAd ad) { if (ad == null) { return; } ad.setSplashInteractionListener(new TTSplashAd.AdInteractionListener() { //Click callback @Override public void onAdClicked(View view, int type) { } //Show callback @Override public void onAdShow(View view, int type) { } //skip callback @Override public void onAdSkip() { //The developer handles the logic of jumping to the APP main page gotoMain(); } //Timeout countdown end @Override public void onAdTimeOver() { //The developer handles the logic of jumping to the APP main page gotoMain(); } }); //Get SplashView View view = ad.getSplashView(); if (view != null && mSplashContainer != null && !SplashActivity.this.isFinishing()) { mSplashContainer.removeAllViews(); //Add SplashView to the ViewGroup, and note that the open screen advertisement view: width = screen width; Height > = 75% screen height mSplashContainer.addView(view); //Set not to turn on the countdown function of open screen advertising and not to display the skip button. If so, you need to customize the countdown logic //ad.setNotAllowSdkCountdown(); }else { //The developer handles the logic of jumping to the APP main page gotoMain(); } } }, 4000); } private void gotoMain() { startActivity(new Intent(SplashActivity.this,MainActivity.class)); } }
=============================================================================================
Take the login page as an example:
You can see that after clicking the login button, if the password is wrong, you will be prompted that the login fails. The corresponding Unicode code is \ u767b\u5f55\u5931\u8d25,
Search in the project to find the corresponding code
//essential information .class public Lsun/sundy/signinapp/LoginActivity; .super Landroidx/appcompat/app/AppCompatActivity; .source "LoginActivity.java" //static const # static fields .field private static final TAG:Ljava/lang/String; = "LoginActivity" # instance fields .field btnRegisterLogin:Landroid/widget/Button; .annotation runtime Lbutterknife/BindView; value = 0x7f090057 .end annotation .end field .field cbTeacherOrStudent:Landroidx/appcompat/widget/AppCompatCheckBox; .annotation runtime Lbutterknife/BindView; value = 0x7f09005c .end annotation .end field .field etPassword:Landroid/widget/EditText; .annotation runtime Lbutterknife/BindView; value = 0x7f09009e .end annotation .end field .field etPasswordSecond:Landroid/widget/EditText; .annotation runtime Lbutterknife/BindView; value = 0x7f09009f .end annotation .end field .field etUserName:Landroid/widget/EditText; .annotation runtime Lbutterknife/BindView; value = 0x7f0900a0 .end annotation .end field .field private isLogin:Z .field llUserName:Landroid/widget/LinearLayout; .annotation runtime Lbutterknife/BindView; value = 0x7f0900d4 .end annotation .end field .field llUserPassword:Landroid/widget/LinearLayout; .annotation runtime Lbutterknife/BindView; value = 0x7f0900d5 .end annotation .end field .field llUserPasswordSecond:Landroid/widget/LinearLayout; .annotation runtime Lbutterknife/BindView; value = 0x7f0900d6 .end annotation .end field .field private studentOrTeacherEntityDao:Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao; .field tvPassword:Landroid/widget/TextView; .annotation runtime Lbutterknife/BindView; value = 0x7f0901a0 .end annotation .end field .field tvPasswordSecond:Landroid/widget/TextView; .annotation runtime Lbutterknife/BindView; value = 0x7f0901a1 .end annotation .end field .field tvRegisterOrLogin:Landroid/widget/TextView; .annotation runtime Lbutterknife/BindView; value = 0x7f0901a2 .end annotation .end field .field tvTitle:Landroid/widget/TextView; .annotation runtime Lbutterknife/BindView; value = 0x7f0901a4 .end annotation .end field .field tvUserName:Landroid/widget/TextView; .annotation runtime Lbutterknife/BindView; value = 0x7f0901a5 .end annotation .end field .field viewDividerOne:Landroid/view/View; .annotation runtime Lbutterknife/BindView; value = 0x7f0901ab .end annotation .end field .field viewDividerThree:Landroid/view/View; .annotation runtime Lbutterknife/BindView; value = 0x7f0901ac .end annotation .end field .field viewDividerTwo:Landroid/view/View; .annotation runtime Lbutterknife/BindView; value = 0x7f0901ad .end annotation .end field # direct methods .method public constructor <init>()V .locals 1 .line 29 invoke-direct {p0}, Landroidx/appcompat/app/AppCompatActivity;-><init>()V .line 64 const/4 v0, 0x1 iput-boolean v0, p0, Lsun/sundy/signinapp/LoginActivity;->isLogin:Z return-void .end method .method static synthetic access$000(Lsun/sundy/signinapp/LoginActivity;)Z .locals 1 .param p0, "x0" # Lsun/sundy/signinapp/LoginActivity; .line 29 iget-boolean v0, p0, Lsun/sundy/signinapp/LoginActivity;->isLogin:Z return v0 .end method .method static synthetic access$002(Lsun/sundy/signinapp/LoginActivity;Z)Z .locals 0 .param p0, "x0" # Lsun/sundy/signinapp/LoginActivity; .param p1, "x1" # Z .line 29 iput-boolean p1, p0, Lsun/sundy/signinapp/LoginActivity;->isLogin:Z return p1 .end method .method static synthetic access$100(Lsun/sundy/signinapp/LoginActivity;)V .locals 0 .param p0, "x0" # Lsun/sundy/signinapp/LoginActivity; .line 29 invoke-direct {p0}, Lsun/sundy/signinapp/LoginActivity;->submitRegister()V return-void .end method .method static synthetic access$200(Lsun/sundy/signinapp/LoginActivity;)V .locals 0 .param p0, "x0" # Lsun/sundy/signinapp/LoginActivity; .line 29 invoke-direct {p0}, Lsun/sundy/signinapp/LoginActivity;->submitLogin()V return-void .end method .method private initData()V .locals 3 .line 158 nop .line 159 invoke-static {p0}, Lkr/co/namee/permissiongen/PermissionGen;->with(Landroid/app/Activity;)Lkr/co/namee/permissiongen/PermissionGen; move-result-object v0 .line 160 const/16 v1, 0x13 invoke-virtual {v0, v1}, Lkr/co/namee/permissiongen/PermissionGen;->addRequestCode(I)Lkr/co/namee/permissiongen/PermissionGen; move-result-object v0 const-string v1, "android.permission.WRITE_EXTERNAL_STORAGE" const-string v2, "android.permission.READ_EXTERNAL_STORAGE" filled-new-array {v1, v2}, [Ljava/lang/String; move-result-object v1 .line 161 invoke-virtual {v0, v1}, Lkr/co/namee/permissiongen/PermissionGen;->permissions([Ljava/lang/String;)Lkr/co/namee/permissiongen/PermissionGen; move-result-object v0 .line 165 invoke-virtual {v0}, Lkr/co/namee/permissiongen/PermissionGen;->request()V .line 166 invoke-static {}, Lsun/sundy/signinapp/database/utils/BizDaoManager;->getInstance()Lsun/sundy/signinapp/database/utils/BizDaoManager; move-result-object v0 invoke-virtual {v0}, Lsun/sundy/signinapp/database/utils/BizDaoManager;->getDaoSession()Lsun/sundy/signinapp/database/gen/DaoSession; move-result-object v0 invoke-virtual {v0}, Lsun/sundy/signinapp/database/gen/DaoSession;->getStudentOrTeacherEntityDao()Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao; move-result-object v0 iput-object v0, p0, Lsun/sundy/signinapp/LoginActivity;->studentOrTeacherEntityDao:Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao; .line 167 return-void .end method .method private initListener()V .locals 2 .line 84 iget-object v0, p0, Lsun/sundy/signinapp/LoginActivity;->tvRegisterOrLogin:Landroid/widget/TextView; new-instance v1, Lsun/sundy/signinapp/LoginActivity$1; invoke-direct {v1, p0}, Lsun/sundy/signinapp/LoginActivity$1;-><init>(Lsun/sundy/signinapp/LoginActivity;)V invoke-virtual {v0, v1}, Landroid/widget/TextView;->setOnClickListener(Landroid/view/View$OnClickListener;)V .line 104 iget-object v0, p0, Lsun/sundy/signinapp/LoginActivity;->btnRegisterLogin:Landroid/widget/Button; new-instance v1, Lsun/sundy/signinapp/LoginActivity$2; invoke-direct {v1, p0}, Lsun/sundy/signinapp/LoginActivity$2;-><init>(Lsun/sundy/signinapp/LoginActivity;)V invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V .line 131 return-void .end method //Take this as an example .method private initView()V .locals 2 .line 79 iget-object v0, p0, Lsun/sundy/signinapp/LoginActivity;->llUserPasswordSecond:Landroid/widget/LinearLayout; const/16 v1, 0x8 invoke-virtual {v0, v1}, Landroid/widget/LinearLayout;->setVisibility(I)V .line 80 iget-object v0, p0, Lsun/sundy/signinapp/LoginActivity;->cbTeacherOrStudent:Landroidx/appcompat/widget/AppCompatCheckBox; invoke-virtual {v0, v1}, Landroidx/appcompat/widget/AppCompatCheckBox;->setVisibility(I)V .line 81 return-void .end method //Take this as an example .method private submitLogin()V .locals 5 .line 134 iget-object v0, p0, Lsun/sundy/signinapp/LoginActivity;->studentOrTeacherEntityDao:Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao; invoke-virtual {v0}, Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao;->queryBuilder()Lorg/greenrobot/greendao/query/QueryBuilder; move-result-object v0 .line 135 .local v0, "queryBuilder":Lorg/greenrobot/greendao/query/QueryBuilder;, "Lorg/greenrobot/greendao/query/QueryBuilder<Lsun/sundy/signinapp/entity/StudentOrTeacherEntity;>;" sget-object v1, Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao$Properties;->Name:Lorg/greenrobot/greendao/Property; iget-object v2, p0, Lsun/sundy/signinapp/LoginActivity;->etUserName:Landroid/widget/EditText; invoke-virtual {v2}, Landroid/widget/EditText;->getText()Landroid/text/Editable; move-result-object v2 invoke-virtual {v2}, Ljava/lang/Object;->toString()Ljava/lang/String; move-result-object v2 invoke-virtual {v2}, Ljava/lang/String;->trim()Ljava/lang/String; move-result-object v2 invoke-virtual {v1, v2}, Lorg/greenrobot/greendao/Property;->eq(Ljava/lang/Object;)Lorg/greenrobot/greendao/query/WhereCondition; move-result-object v1 const/4 v2, 0x1 new-array v2, v2, [Lorg/greenrobot/greendao/query/WhereCondition; sget-object v3, Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao$Properties;->Password:Lorg/greenrobot/greendao/Property; iget-object v4, p0, Lsun/sundy/signinapp/LoginActivity;->etPassword:Landroid/widget/EditText; .line 136 invoke-virtual {v4}, Landroid/widget/EditText;->getText()Landroid/text/Editable; move-result-object v4 invoke-virtual {v4}, Ljava/lang/Object;->toString()Ljava/lang/String; move-result-object v4 invoke-virtual {v4}, Ljava/lang/String;->trim()Ljava/lang/String; move-result-object v4 invoke-virtual {v3, v4}, Lorg/greenrobot/greendao/Property;->eq(Ljava/lang/Object;)Lorg/greenrobot/greendao/query/WhereCondition; move-result-object v3 const/4 v4, 0x0 aput-object v3, v2, v4 .line 135 invoke-virtual {v0, v1, v2}, Lorg/greenrobot/greendao/query/QueryBuilder;->where(Lorg/greenrobot/greendao/query/WhereCondition;[Lorg/greenrobot/greendao/query/WhereCondition;)Lorg/greenrobot/greendao/query/QueryBuilder; .line 137 invoke-virtual {v0}, Lorg/greenrobot/greendao/query/QueryBuilder;->build()Lorg/greenrobot/greendao/query/Query; move-result-object v1 invoke-virtual {v1}, Lorg/greenrobot/greendao/query/Query;->unique()Ljava/lang/Object; move-result-object v1 check-cast v1, Lsun/sundy/signinapp/entity/StudentOrTeacherEntity; .line 138 .local v1, "entity":Lsun/sundy/signinapp/entity/StudentOrTeacherEntity; if-eqz v1, :cond_0 .line 139 new-instance v2, Landroid/content/Intent; const-class v3, Lsun/sundy/signinapp/MainActivity; invoke-direct {v2, p0, v3}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V .line 140 .local v2, "intent":Landroid/content/Intent; invoke-virtual {v1}, Lsun/sundy/signinapp/entity/StudentOrTeacherEntity;->getName()Ljava/lang/String; move-result-object v3 const-string v4, "loginName" invoke-virtual {v2, v4, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent; .line 141 invoke-virtual {v1}, Lsun/sundy/signinapp/entity/StudentOrTeacherEntity;->getIsTeacher()I move-result v3 const-string v4, "isTeacher" invoke-virtual {v2, v4, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent; .line 142 invoke-virtual {p0, v2}, Lsun/sundy/signinapp/LoginActivity;->startActivity(Landroid/content/Intent;)V .line 143 .end local v2 # "intent":Landroid/content/Intent; goto :goto_0 .line 144 :cond_0 const-string v2, "\u767b\u5f55\u5931\u8d25\uff0c\u7528\u6237\u4e0d\u5b58\u5728\u6216\u5bc6\u7801\u9519\u8bef\uff01" invoke-static {v2}, Lsun/sundy/signinapp/utils/ToastUtils;->showToast(Ljava/lang/String;)V .line 146 :goto_0 return-void .end method .method private submitRegister()V .locals 2 .line 149 new-instance v0, Lsun/sundy/signinapp/entity/StudentOrTeacherEntity; invoke-direct {v0}, Lsun/sundy/signinapp/entity/StudentOrTeacherEntity;-><init>()V .line 150 .local v0, "entity":Lsun/sundy/signinapp/entity/StudentOrTeacherEntity; iget-object v1, p0, Lsun/sundy/signinapp/LoginActivity;->etUserName:Landroid/widget/EditText; invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable; move-result-object v1 invoke-virtual {v1}, Ljava/lang/Object;->toString()Ljava/lang/String; move-result-object v1 invoke-virtual {v1}, Ljava/lang/String;->trim()Ljava/lang/String; move-result-object v1 invoke-virtual {v0, v1}, Lsun/sundy/signinapp/entity/StudentOrTeacherEntity;->setName(Ljava/lang/String;)V .line 151 iget-object v1, p0, Lsun/sundy/signinapp/LoginActivity;->etPassword:Landroid/widget/EditText; invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable; move-result-object v1 invoke-virtual {v1}, Ljava/lang/Object;->toString()Ljava/lang/String; move-result-object v1 invoke-virtual {v1}, Ljava/lang/String;->trim()Ljava/lang/String; move-result-object v1 invoke-virtual {v0, v1}, Lsun/sundy/signinapp/entity/StudentOrTeacherEntity;->setPassword(Ljava/lang/String;)V .line 152 iget-object v1, p0, Lsun/sundy/signinapp/LoginActivity;->cbTeacherOrStudent:Landroidx/appcompat/widget/AppCompatCheckBox; invoke-virtual {v1}, Landroidx/appcompat/widget/AppCompatCheckBox;->isChecked()Z move-result v1 invoke-virtual {v0, v1}, Lsun/sundy/signinapp/entity/StudentOrTeacherEntity;->setIsTeacher(I)V .line 153 iget-object v1, p0, Lsun/sundy/signinapp/LoginActivity;->studentOrTeacherEntityDao:Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao; invoke-virtual {v1, v0}, Lsun/sundy/signinapp/database/gen/StudentOrTeacherEntityDao;->insertOrReplace(Ljava/lang/Object;)J .line 154 const-string v1, "\u6ce8\u518c\u6210\u529f\uff01" invoke-static {v1}, Lsun/sundy/signinapp/utils/ToastUtils;->showToast(Ljava/lang/String;)V .line 155 return-void .end method # virtual methods .method public doFailSomething()V .locals 2 .annotation runtime Lkr/co/namee/permissiongen/PermissionFail; requestCode = 0x13 .end annotation .line 179 const-string v0, "LoginActivity" const-string v1, "doSomething: \u6743\u9650\u83b7\u53d6\u5931\u8d25" invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I .line 180 invoke-virtual {p0}, Lsun/sundy/signinapp/LoginActivity;->finish()V .line 181 return-void .end method .method public doSomething()V .locals 2 .annotation runtime Lkr/co/namee/permissiongen/PermissionSuccess; requestCode = 0x13 .end annotation .line 172 const-string v0, "LoginActivity" const-string v1, "doSomething: \u6743\u9650\u83b7\u53d6\u6210\u529f" invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I .line 173 invoke-static {}, Lsun/sundy/signinapp/database/utils/BizDaoManager;->getInstance()Lsun/sundy/signinapp/database/utils/BizDaoManager; move-result-object v0 invoke-virtual {v0}, Lsun/sundy/signinapp/database/utils/BizDaoManager;->init()Lorg/greenrobot/greendao/database/Database; .line 174 return-void .end method .method protected onCreate(Landroid/os/Bundle;)V .locals 1 .param p1, "savedInstanceState" # Landroid/os/Bundle; .annotation system Ldalvik/annotation/MethodParameters; accessFlags = { 0x0 } names = { "savedInstanceState" } .end annotation .line 70 invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V .line 71 const v0, 0x7f0c001c invoke-virtual {p0, v0}, Lsun/sundy/signinapp/LoginActivity;->setContentView(I)V .line 72 invoke-static {p0}, Lbutterknife/ButterKnife;->bind(Landroid/app/Activity;)Lbutterknife/Unbinder; .line 73 invoke-direct {p0}, Lsun/sundy/signinapp/LoginActivity;->initView()V .line 74 invoke-direct {p0}, Lsun/sundy/signinapp/LoginActivity;->initData()V .line 75 invoke-direct {p0}, Lsun/sundy/signinapp/LoginActivity;->initListener()V .line 76 return-void .end method
Recompile package:
apktool b D:\WorkForLlaria\AndroidHack\HackOutput\SignAppForShowDebug
Prompt error
apk cannot be installed at this time because of the signature problem.
Re sign with jarsigner in JDK tool:
jarsigner -keystore D:\WorkForLlaria\AndroidHack\HackOutput\SignAppForShowDebug\dist\debug.jks -signedjar D:\WorkForLlaria\AndroidHack\HackOutput\SignAppForShowDebug\dist\android_sign.apk D:\WorkForLlaria\AndroidHack\HackOutput\SignAppForShowDebug\dist\SignInAppForShowDebug.apk debugkey
In fact, many apk s will also be shelled and key code packaged into so
Shelling and so decompilation:
https://blog.csdn.net/xiangzhihong8/article/details/93738211