SWPU 2019ThousandYearsAgo
先分析下Manifest.xml
只有一个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.thousandyearsago" platformBuildVersionCode="29" platformBuildVersionName="10"> <uses-sdk android:minSdkVersion="15" 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.thousandyearsago.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
|
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 55
| package com.example.thousandyearsago;
import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.Button; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener { final long a = 1000000000; private Handler handler;
public native String StringFromJNI();
public native String stringFromJNI();
static { System.loadLibrary("native-lib"); }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.handler = new Handler(); Button btn = (Button) findViewById(R.id.button); btn.setOnClickListener(this); Runnable r = new Inner(); this.handler.postDelayed(r, 1000000000L); }
@Override public void onClick(View v) { if (v.getId() == R.id.button) { Toast.makeText(this, "好像卡死了啊!!!", 0).show(); } }
class Inner implements Runnable { Inner() { }
@Override public void run() { if (1000000000 <= 1000000) { MainActivity mainActivity = MainActivity.this; Toast.makeText(mainActivity, mainActivity.StringFromJNI(), 1).show(); } } } }
|
通过动态调试得到提示
![image-20230609005321505](/images/loading.svg)
其调用了native类的StringFromJNI函数(下方的函数)
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
| int __cdecl Java_com_example_thousandyearsago_MainActivity_stringFromJNI(_JNIEnv *a1) { const char *v1; char *v3; char dest[43];
memcpy(dest, "flag{WeLcome_to-SWPU}}", 0x17u); v3 = (char *)decode(dest, 5); MD5Final(v3); v1 = (const char *)decode(dest, 5); return _JNIEnv::NewStringUTF(a1, v1); }
char *__cdecl decode(char *a1, int a2) { size_t i;
for ( i = 0; i < strlen(a1); ++i ) { if ( a1[i] < 65 || a1[i] > 90 ) { if ( a1[i] >= 97 && a1[i] <= 122 ) a1[i] = (a2 + a1[i] - 97) % 26 + 97; } else { a1[i] = (a2 + a1[i] - 65) % 26 + 65; } } return a1; }
|
decode不是解码吗,怎么就变成加密了(有点被误导了)
用python模拟了下decode的过程
1 2 3 4 5 6 7 8 9 10 11 12
| a=input() b=[0]*40 for i in range(len(a)): b[i]=ord(a[i]) if(ord(a[i])<65 or ord(a[i])>90): if(ord(a[i])>=97 and ord(a[i])<=122): b[i]=(5+ord(a[i])-97)%26+97 else: b[i]=(5+ord(a[i])-65)%26+65 print(bytes(b).decode())
|
没遇到过里面带大括号的flag,看了别人wp才知道得把kqfl{BjQhtrj_yt-XBUZ}}也用大括号包起来
flag就是flag{kqfl{BjQhtrj_yt-XBUZ}}} 非常奇特