import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity
extends AppCompatActivity
{
private String getFlag()
{
return getBaseContext().getString(2131427360);
}
private void showMsgToast(String paramString)
{
Toast.makeText(this, paramString, 1).show();
}
public void checkPassword(String paramString)
{
if (paramString.equals(new String(Base64.decode(new StringBuffer(getFlag()).reverse().toString(), 0))))
{
showMsgToast("Congratulations !");
return;
}
showMsgToast("Try again.");
}
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2131296283);
((Button)findViewById(2131165261)).setOnClickListener(new View.OnClickListener()
{
public void onClick(View paramAnonymousView)
{
paramAnonymousView = ((EditText)MainActivity.this.findViewById(2131165253)).getText().toString();
MainActivity.this.checkPassword(paramAnonymousView);
}
});
}
}`
可以看到代码逻辑很简单
public void checkPassword(String paramString)
{
if (paramString.equals(new String(Base64.decode(new StringBuffer(getFlag()).reverse().toString(), 0))))
{
showMsgToast("Congratulations !");
return;
}
showMsgToast("Try again.");
}
就是获取flag经过一系列操作然后和你输入的字符串作比较,让我们看一下smali代码
.class public Lre/sdnisc2018/sdnisc_apk1/MainActivity;
.super Landroid/support/v7/app/AppCompatActivity;
.source "MainActivity.java"
.method public constructor ()V
.registers 1
.line 20
invoke-direct { p0 }, Landroid/support/v7/app/AppCompatActivity;->()V
return-void
.end method
.method private getFlag()Ljava/lang/String;
.registers 3
.line 39
invoke-virtual { p0 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity;->getBaseContext()Landroid/content/Context;
move-result-object v0
const v1, 2131427360
invoke-virtual { v0, v1 }, Landroid/content/Context;->getString(I)Ljava/lang/String;
move-result-object v0
return-object v0
.end method
.method private showMsgToast(Ljava/lang/String;)V
.registers 3
const/4 v0, 1
.line 35
invoke-static { p0, p1, v0 }, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
invoke-virtual { p1 }, Landroid/widget/Toast;->show()V
return-void
.end method
.method public checkPassword(Ljava/lang/String;)V
.registers 5
.line 23
invoke-direct { p0 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity;->getFlag()Ljava/lang/String;
move-result-object v0
.line 24
new-instance v1, Ljava/lang/StringBuffer;
invoke-direct { v1, v0 }, Ljava/lang/StringBuffer;->(Ljava/lang/String;)V
invoke-virtual { v1 }, Ljava/lang/StringBuffer;->reverse()Ljava/lang/StringBuffer;
move-result-object v0
.line 25
new-instance v1, Ljava/lang/String;
invoke-virtual { v0 }, Ljava/lang/StringBuffer;->toString()Ljava/lang/String;
move-result-object v0
const/4 v2, 0
invoke-static { v0, v2 }, Landroid/util/Base64;->decode(Ljava/lang/String;I)[B
move-result-object v0
invoke-direct { v1, v0 }, Ljava/lang/String;->([B)V
.line 27
invoke-virtual { p1, v1 }, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result p1
if-eqz p1, :L0
const-string p1, "Congratulations !"
.line 28
invoke-direct { p0, p1 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity;->showMsgToast(Ljava/lang/String;)V
goto :L1
:L0
const-string p1, "Try again."
.line 30
invoke-direct { p0, p1 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity;->showMsgToast(Ljava/lang/String;)V
:L1
return-void
.end method
.method protected onCreate(Landroid/os/Bundle;)V
.registers 3
.line 44
invoke-super { p0, p1 }, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V
const p1, 2131296283
.line 45
invoke-virtual { p0, p1 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity;->setContentView(I)V
const p1, 2131165261
.line 47
invoke-virtual { p0, p1 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object p1
check-cast p1, Landroid/widget/Button;
.line 48
new-instance v0, Lre/sdnisc2018/sdnisc_apk1/MainActivity$1;
invoke-direct { v0, p0 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity$1;->(Lre/sdnisc2018/sdnisc_apk1/MainActivity;)V
invoke-virtual { p1, v0 }, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
return-void
.end method
首先获取加密后flag
invoke-direct { p0 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity;->getFlag()Ljava/lang/String;
然后通过虚方法reverse()将加密后flag字符反转
invoke-virtual { v1 }, Ljava/lang/StringBuffer;->reverse()Ljava/lang/StringBuffer;
然后base64解密
invoke-static { v0, v2 }, Landroid/util/Base64;->decode(Ljava/lang/String;I)[B
最后比较字符串
invoke-virtual { p1, v1 }, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
接着我们看一下getFlag()中的代码
.method private getFlag()Ljava/lang/String;
.registers 3
.line 39
invoke-virtual { p0 }, Lre/sdnisc2018/sdnisc_apk1/MainActivity;->getBaseContext()Landroid/content/Context;
move-result-object v0
const v1, 2131427360
invoke-virtual { v0, v1 }, Landroid/content/Context;->getString(I)Ljava/lang/String;
move-result-object v0
return-object v0
.end method
可以看出加密后的flag是十进制资源id为2131427360的字符串,将十进制转16进制得到7F0B0020,根据id找到字符串
991YiZWOz81ZhFjZfJXdwk3X1k2XzIXZIt3ZhxmZ
将991YiZWOz81ZhFjZfJXdwk3X1k2XzIXZIt3ZhxmZ反转解密后得到flag{Her3_i5_y0ur_f1ag_39fbc_}
附件下载