【Android逆向】破解看雪 test1.apk
1. 获取apk,并安装至手机
apk 获取地址: https://www.kanxue.com/work-task_read-800624.htm
adb install -t test1.apk
# 这个apk必须加-t ,否则会报错
2. 只有一个输入框,随便输入内容,提示壮士继续加油
3. 将apk拖入到jadx中观察
public class MainActivity extends AppCompatActivity {
TextView message_tv;
EditText password_et;
EditText username_et;
public static native String doMath(byte[] bArr);
static {
System.loadLibrary("roysue");
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.username_et = (EditText) findViewById(R.id.editText);
this.message_tv = (TextView) findViewById(R.id.textView);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { // from class: com.roysue.easyso1.MainActivity.1
@Override // android.view.View.OnClickListener
public void onClick(View v) {
String res = MainActivity.doMath(MainActivity.this.username_et.getText().toString().getBytes());
if (res.compareTo("cjB5c3VlbGwwdmV5MHVzMG11Y2g=\n") == 0) {
MainActivity.this.message_tv.setText("恭喜你!");
} else {
MainActivity.this.message_tv.setText("壮士请继续加油!");
}
}
});
}
}
4. 从代码中疑似感觉这个字符串是个base64加密的字符串,看看native中的逻辑确定一下猜想
5. 加压apk将libroysue.so
拖入IDA中进行观察
【1】导出表中搜索 doMath
函数,发现没有,说明是动态注册,搜索JNI_OnLoad
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env; // [sp+10h] [bp-10h] BYREF
env = 0;
if ( _JavaVM::GetEnv(vm, (void **)&env, 65542) )
return -1;
if ( !env )
_assert2(
"/root/Desktop/202104test/easyso1/app/src/main/cpp/roysue.cpp",
60,
"jint JNI_OnLoad(JavaVM *, void *)",
"env != nullptr");
if ( registerMethods(env, "com/roysue/easyso1/MainActivity", method_table, 1) )
return 65542;
else
return -1;
}
说明关联的函数在 method_table
中,点击观察 method_table
.data:00004000 ; ===========================================================================
.data:00004000
.data:00004000 ; Segment type: Pure data
.data:00004000 AREA .data, DATA
.data:00004000 ; ORG 0x4000
.data:00004000 ; JNINativeMethod method_table[1]
.data:00004000 09 26 00 00 10 26 00 00 B1 09+_ZL12method_table JNINativeMethod <aDomath, aBLjavaLangStri, _Z3mmmP7_JNIEnvP7_jclassP11_jbyteArray+1>
.data:00004000 00 00 ; DATA XREF: JNI_OnLoad+56↑o
.data:00004000 ; JNI_OnLoad+58↑o
.data:00004000 ; .text:off_B74↑o
.data:00004000 ; mmm(_JNIEnv *,_jclass *,_jbyteArray *) ...
.data:0000400C ; unw_addr_space_t unw_local_addr_space
.data:0000400C 10 40 00 00 unw_local_addr_space DCD _ZN9libunwind17LocalAddressSpace17sThisAddressSpaceE ; libunwind::LocalAddressSpace::sThisAddressSpace
.data:0000400C ; .data ends
.data:0000400C
可以看到 Domath 关联的函数叫mmm
(aDomath,aBLjavaLangStri,_Z3mmmP7_JNIEnvP7_jclassP11_jbyteArray+1)
点击_Z3mmmP7_JNIEnvP7_jclassP11_jbyteArray,观察
jobject __fastcall mmm(JNIEnv *env, jclass clazz, jbyteArray bytearray)
{
_jmethodID *StaticMethodID; // r0
_jclass *clazza; // [sp+10h] [bp-18h]
clazza = _JNIEnv::FindClass(env, "android/util/Base64");
StaticMethodID = _JNIEnv::GetStaticMethodID(env, clazza, "encodeToString", "([BI)Ljava/lang/String;");
return _JNIEnv::CallStaticObjectMethod(env, clazza, StaticMethodID, bytearray, 0);
}
由此可得,确实是对传入的字符串进行base64处理,然后对结果进行比对,
于是解码可得flag为r0ysuell0vey0us0much
adb shell input text "r0ysuell0vey0us0much"
提交通过