apk
:每个android app都有对应的安装包,以.apk
为后缀 ,.apk文件类似压缩包,将后缀名改成.zip可以进行解压,里面的.dex文件可以用反编译工具
进行反编译获得源码;所以一般app都会加壳,将真正的源码隐藏起来反编译工具:jadx、JEB、Apktool
:因SSL Pinning导致无法正常抓包时,或则是抓包后要分析某个参数的生成逻辑时,需要反编译apk文件,还原成可读性高的java代码进一步分析
1.Android应用的逻辑代码是由java开发,所以第一层是java代码
2.java虚拟机jvm运行的是java文件编译过后的class文件
3.android虚拟机并不是执行java虚拟机编译后生成的class文件,而是执行再重新整合打包后生成的dex文件编译之后的smali文件
4.apk:是编译完成后的安卓应用程序安装包
5.dex文件:是class文件的打包文件
6.smali文件:是Dalvik字节码文件
7.class文件:是jvm字节码文件
第一步:把apk丢进apkide里(JEB也可以)
进去之后打开smali-com-example-findit-Mainactivity.smali
问题来了,Mainactivity.smali是啥?为啥看它?
MainActivity:
1、每个种语言都有一个程序入库(如:C#main函数),而Android程序的入口就是Main Actiivty函数。
2、Activity是Android的核心类(android.app.Activity),在Activity类有onCreate事件方法,一般用于对Activity进行初始化,并且通过setContentView方法将View放到Activity上,绑定后,Activity会显示View上的控件。
MainAcitvity.java文件下的MainActivity类:
a、 onCreate()是创建窗体的入口函数,
b、 onCreateOptionsMenu()是创建当前Activity的菜单函数,
c、 onOptionsItemSelected()是响应菜单按钮点击事件函数。
d、 PlaceolderFragment内部类是实现自定义fragment
说这么多,就相当于你用IDA主动找到main函数按F5反编译一个道理了,manactivity就是主函数。
第二步:分析代码
.class public Lcom/example/findit/MainActivity;
.super Landroid/support/v7/app/ActionBarActivity;
.source "MainActivity.java"
# direct methods
.method public constructor <init>()V
.locals 0
.prologue
.line 13
invoke-direct {p0}, Landroid/support/v7/app/ActionBarActivity;-><init>()V
return-void
.end method
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 7
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 17
invoke-super {p0, p1}, Landroid/support/v7/app/ActionBarActivity;->onCreate(Landroid/os/Bundle;)V
.line 18
const v0, 0x7f030018
invoke-virtual {p0, v0}, Lcom/example/findit/MainActivity;->setContentView(I)V
.line 19
const v0, 0x7f05003d
invoke-virtual {p0, v0}, Lcom/example/findit/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v6
check-cast v6, Landroid/widget/Button;
.line 20
.local v6, "btn":Landroid/widget/Button;
const v0, 0x7f05003e
invoke-virtual {p0, v0}, Lcom/example/findit/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v3
check-cast v3, Landroid/widget/EditText;
.line 21
.local v3, "edit":Landroid/widget/EditText;
const v0, 0x7f05003f
invoke-virtual {p0, v0}, Lcom/example/findit/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v5
check-cast v5, Landroid/widget/TextView;
.line 22
.local v5, "text":Landroid/widget/TextView;
const/16 v0, 0x11
new-array v2, v0, [C
fill-array-data v2, :array_0
.line 23
.local v2, "a":[C
const/16 v0, 0x26
new-array v4, v0, [C
fill-array-data v4, :array_1
.line 25
.local v4, "b":[C
new-instance v0, Lcom/example/findit/MainActivity$1;
move-object v1, p0
invoke-direct/range {v0 .. v5}, Lcom/example/findit/MainActivity$1;-><init>(Lcom/example/findit/MainActivity;[CLandroid/widget/EditText;[CLandroid/widget/TextView;)V
invoke-virtual {v6, v0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 76
return-void
.line 22
:array_0
.array-data 2
0x54s
0x68s
0x69s
0x73s
0x49s
0x73s
0x54s
0x68s
0x65s
0x46s
0x6cs
0x61s
0x67s
0x48s
0x6fs
0x6ds
0x65s
.end array-data
.line 23
nop
:array_1
.array-data 2
0x70s
0x76s
0x6bs
0x71s
0x7bs
0x6ds
0x31s
0x36s
0x34s
0x36s
0x37s
0x35s
0x32s
0x36s
0x32s
0x30s
0x33s
0x33s
0x6cs
0x34s
0x6ds
0x34s
0x39s
0x6cs
0x6es
0x70s
0x37s
0x70s
0x39s
0x6ds
0x6es
0x6bs
0x32s
0x38s
0x6bs
0x37s
0x35s
0x7ds
.end array-data
.end method
.method public onOptionsItemSelected(Landroid/view/MenuItem;)Z
.locals 2
.param p1, "item" # Landroid/view/MenuItem;
.prologue
.line 83
invoke-interface {p1}, Landroid/view/MenuItem;->getItemId()I
move-result v0
.line 84
.local v0, "id":I
const v1, 0x7f050040
if-ne v0, v1, :cond_0
.line 85
const/4 v1, 0x1
.line 87
:goto_0
return v1
:cond_0
invoke-super {p0, p1}, Landroid/support/v7/app/ActionBarActivity;->onOptionsItemSelected(Landroid/view/MenuItem;)Z
move-result v1
goto :goto_0
.end method
看到两串十六进制数字,非常可疑,转化成字符串试试看。
a = [0x54,
0x68,
0x69,
0x73,
0x49,
0x73,
0x54,
0x68,
0x65,
0x46,
0x6C,
0x61,
0x67,
0x48,
0x6F,
0x6D,
0x65,
]
x = ""
for i in a:
x += chr(i)
print(x)
a = [0x70,
0x76,
0x6b,
0x71,
0x7b,
0x6d,
0x31,
0x36,
0x34,
0x36,
0x37,
0x35,
0x32,
0x36,
0x32,
0x30,
0x33,
0x33,
0x6c,
0x34,
0x6d,
0x34,
0x39,
0x6c,
0x6e,
0x70,
0x37,
0x70,
0x39,
0x6d,
0x6e,
0x6b,
0x32,
0x38,
0x6b,
0x37,
0x35,
0x7d,
]
x = ""
for i in a:
x += chr(i)
print(x)
完了输进去发现不对,直觉就是把pvkq和flag比较一下?
发现pvkq是flag往后偏移10位,那不就凯撒密码解一下完事儿了。
CTF在线工具-在线凯撒密码加密|在线凯撒密码解密|凯撒密码算法|Caesar Cipher (hiencode.com)http://www.hiencode.com/caesar.html
flag{c164675262033b4c49bdf7f9cda28a75}