参考wp[(41条消息) BUUCTF GKCTF 2021]app-debug_皮皮蟹!的博客-CSDN博客
就一个activity
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" android:compileSdkVersion="29" android:compileSdkVersionCodename="10" package="com.example.myapplication" platformBuildVersionCode="29" platformBuildVersionName="10"> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/> <application android:theme="@style/AppTheme" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:debuggable="true" android:allowBackup="true" android:supportsRtl="true" android:roundIcon="@mipmap/ic_launcher_round" android:appComponentFactory="androidx.core.app.CoreComponentFactory"> <activity android:name="com.example.myapplication.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
|
主函数就是调用了JNI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| package com.example.myapplication;
import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity { private Button mBtnLogin; private EditText mEtflag;
public native boolean check(String str);
static { System.loadLibrary("native-lib"); }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(C0273R.layout.activity_main); this.mBtnLogin = (Button) findViewById(C0273R.C0275id.btn_login); this.mEtflag = (EditText) findViewById(C0273R.C0275id.bEn_edittext); this.mBtnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MainActivity mainActivity = MainActivity.this; if (mainActivity.check(mainActivity.mEtflag.getText().toString())) { Toast.makeText(MainActivity.this, "You Are Right!flag is flag{md5(input)}", 0).show(); } else { Toast.makeText(MainActivity.this, "Sorry your flag is wrong!", 0).show(); } } }); } }
|
JNI函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| bool __fastcall Java_com_example_myapplication_MainActivity_check(__int64 a1, __int64 a2, __int64 a3) { int i; bool v5; char v6[24]; __int64 v7;
v7 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40); sub_3FE20(a1, a3, (__int64)v6); if ( sub_40040((__int64)v6) == 8 ) { for ( i = 0; i <= 6; ++i ) byte_C80E0[i] = *(_BYTE *)sub_40064((__int64)v6, i); v5 = sub_3ED8C((unsigned int *)byte_C80E0); } else { v5 = 0; } sub_3FC04((__int64)v6); _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)); return v5; }
|
为啥反编译不一样
![image-20230623181955999](/images/loading.svg)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| bool __fastcall sub_3ED8C(unsigned int *a1) { unsigned int i; int v3; unsigned int v4; unsigned int v5;
v5 = *a1; v4 = a1[1]; v3 = 0; for ( i = 0; i < 0x20; ++i ) { v3 += dword_C8010; v5 += (16 * v4 + dword_C8000) ^ (v4 + v3) ^ ((v4 >> 5) + dword_C8004); v4 += (16 * v5 + dword_C8008) ^ (v5 + v3) ^ ((v5 >> 5) + dword_C800C); } *a1 = v5; a1[1] = v4; return *a1 == 0xF5A98FF3 && a1[1] == 0xA21873A3; }
|
通过交叉引用发现有对key的修改key为{9,7,8,6}
![image-20230623182220976](/images/loading.svg)
1 2 3 4 5 6
| void sub_3EF18() { dword_C8004 = 7; dword_C8008 = 8; dword_C800C = 6; }
|
有个自启动的函数对值进行修改,自启动的一般都在.init_array表内
1 2 3 4 5 6 7
| .init_array:00000000000C0F98 ; Segment type: Pure data .init_array:00000000000C0F98 AREA .init_array, DATA, ALIGN=3 .init_array:00000000000C0F98 ; ORG 0xC0F98 .init_array:00000000000C0F98 off_C0F98 DCQ sub_3EF3C ; DATA XREF: LOAD:0000000000000088↑o .init_array:00000000000C0F98 ; LOAD:00000000000001D8↑o .init_array:00000000000C0F98 ; .init_array ends .init_array:00000000000C0F98
|
直接用之前写的tea算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include <stdio.h> #include <stdint.h> void teajiami (uint32_t* v, uint32_t* k) { uint32_t sum = 0; uint32_t v0 = v[0], v1 = v[1]; uint32_t delta = 0x458BCD42; uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (int i=0; i<32; i++) { sum += delta; v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); }
v[0]=v0; v[1]=v1; }
void teajiemi (uint32_t* v, uint32_t* k) { uint32_t v0 = v[0], v1 = v[1]; uint32_t delta = 0x458BCD42; uint32_t sum = delta * 32; uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (int i=0; i<32; i++) { v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3); v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1); sum -= delta; }
v[0]=v0; v[1]=v1; }
int main() { uint32_t v[2] = {0xF5A98FF3, 0xA21873A3}; uint32_t k[4]= {0x9, 0x7, 0x8, 0x6};
teajiemi(v, k); printf("Decrypted data is : %x %x\n", v[0], v[1]); puts((char*)v);
return 0; }
|
![image-20230623183849786](/images/loading.svg)
直接用md5
![image-20230623183945049](/images/loading.svg)