1. apk安装到手机,随便输入点内容,提示错误
2. jadx打开apk
btn.setOnClickListener(new View.OnClickListener() { // from class: com.testjava.jack.pingan2.MainActivity.1
@Override // android.view.View.OnClickListener
public void onClick(View v) {
EditText et1 = (EditText) MainActivity.this.findViewById(R.id.editText);
String strIn = et1.getText().toString();
if (cyberpeace.CheckString(strIn) == 1) {
Toast.makeText(MainActivity.this, "验证通过!", 1).show();
} else {
Toast.makeText(MainActivity.this, "验证失败!", 1).show();
}
}
});
核心是这一行 cyberpeace.CheckString(strIn)
public class cyberpeace {
public static native int CheckString(String str);
static {
System.loadLibrary("cyberpeace");
}
}
那么算法在so中
3. IDA打开SO看一下
bool __fastcall Java_com_testjava_jack_pingan2_cyberpeace_CheckString(JNIEnv *env, jclass clz, jstring key)
{
const char *key_chars; // x20
__int64 key_len; // x0
signed int t_key_len; // w21
unsigned __int64 v6; // x22
_BYTE *v7; // x0
_BYTE *t_key_chars; // x19
size_t v9; // w2
unsigned __int64 v10; // x20
_BYTE *v11; // x8
char v12; // w9
char v13; // w10
char v14; // w9
__int64 v15; // x20
_BYTE *v16; // x8
char v17; // w10
unsigned __int64 v18; // x0
unsigned __int64 v19; // x8
key_chars = (*env)->GetStringUTFChars(env, key, 0LL);
key_len = strlen(key_chars);
t_key_len = key_len;
v6 = ((key_len << 32) + 0x100000000LL) >> 32;
v7 = malloc((unsigned __int64)((key_len << 32) + 0x100000000LL) >> 32);
t_key_chars = v7;
if ( v6 > t_key_len )
v9 = v6 - t_key_len;
else
v9 = 0;
memset(&v7[t_key_len], 0, v9);
memcpy(t_key_chars, key_chars, t_key_len);
if ( strlen(t_key_chars) >= 2uLL )
{
v10 = 0LL;
do
{
v11 = &t_key_chars[v10];
v12 = t_key_chars[v10 + 16];
v13 = t_key_chars[v10++];
*v11 = v12;
v11[16] = v13;
}
while ( (unsigned __int64)strlen(t_key_chars) >> 1 > v10 );
}
if ( *t_key_chars )
{
v14 = t_key_chars[1];
t_key_chars[1] = *t_key_chars;
*t_key_chars = v14;
if ( strlen(t_key_chars) >= 3uLL )
{
v15 = 0LL;
do
{
v16 = &t_key_chars[v15];
v17 = t_key_chars[v15 + 2];
v16[2] = t_key_chars[v15 + 3];
v16[3] = v17;
v18 = strlen(t_key_chars);
v19 = v15 + 4;
v15 += 2LL;
}
while ( v18 > v19 );
}
}
return strcmp(t_key_chars, "f72c5a36569418a20907b55be5bf95ad") == 0;
}
有点看不清,整理以下
i = 0;
do
{
v12 = t_key_chars[i + 16];
v13 = t_key_chars[i];
t_key_chars[i] = v12;
t_key_chars[i+16] = v13;
i++;
}
while ( strlen(t_key_chars) / 2 > i );
if ( *t_key_chars )
{
tmp = t_key_chars[1];
t_key_chars[1] = t_key_chars[0];
t_key_chars[0] = tmp;
if ( strlen(t_key_chars) >= 3uLL )
{
i = 0;
do
{
tmp = t_key_chars[i + 2];
t_key_chars[i+2] = t_key_chars[i + 3];
t_key_chars[i+3] = tmp;
v19 = i + 4;
i += 2;
}
while ( strlen(t_key_chars) > v19 );
}
}
可以看出,是先把32位字符串前十六位和后十六位换个位置,然后每两位互换位置
4 写出还原算法
key = 'f72c5a36569418a20907b55be5bf95ad'
def main():
print(key)
key_list = list(key)
t_len = len(key)
i = 0
v19 = 0
while v19 < t_len:
tmp = key_list[i+2]
key_list[i+2] = key_list[i+3]
key_list[i+3] = tmp
v19 = i+4
i += 2
tmp = key_list[1]
key_list[1] = key_list[0]
key_list[0] = tmp
print("after ======")
print(''.join(key_list))
i = 0
while i < t_len >> 1:
tmp = key_list[i+16]
key_list[i+16] = key_list[i]
key_list[i] = tmp
i += 1
print("after ======")
print(''.join(key_list))
main()
日志
f72c5a36569418a20907b55be5bf95ad
after ======
7fc2a5636549812a90705bb55efb59da
after ======
90705bb55efb59da7fc2a5636549812a # flag
成功获得flag
标签:tmp,__,easy,chars,list,len,so,key,Android From: https://www.cnblogs.com/gradyblog/p/17231279.html