本帖最后由 shuaiyue 于 2019-5-6 23:47 编辑
下载:https://www.52pojie.cn/thread-804580-1-1.html
先声明不是诋毁,只是吐槽。。
----------------------------------------
这个cm坑爹啊。算法感觉是无解的。另外各种模拟器只能运行一次,然后闪退,肉疼TO无懈可击~
期间联系到作者,想窥视下流程来验证下我的判断,回复丢了。无奈~~有空的可以来帮忙验证下我的分析。
流程分析:JAVA->SO 。
JAVA层
[Java] 纯文本查看 复制代码
public static byte[] MD5(String paramString) //[color=#ff0000]获取32位MD5[/color]
{
try
{
paramString = paramString.getBytes();
MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
localMessageDigest.update(paramString);
paramString = localMessageDigest.digest();
return paramString;
}
catch (Exception paramString) {}
return (byte[])null;
}
public native byte[] getStr(byte[] paramArrayOfByte1, byte[] paramArrayOfByte2); [color=#ff0000]//动态函数[/color]
public byte[] xor(byte[] paramArrayOfByte) //[color=#ff0000]输入的字符串每一位和"52pojie"亦或[/color]
throws Exception
{
byte[] arrayOfByte1 = new byte[paramArrayOfByte.length];
byte[] arrayOfByte2 = "52pojie".getBytes("UTF-8");
int j = paramArrayOfByte.length;
int i = 0;
for (;;)
{
if (i >= j) {
return arrayOfByte1;
}
int k = arrayOfByte2[(i % arrayOfByte2.length)]; //[b]取模 [/b]
arrayOfByte1[i] = ((byte)(paramArrayOfByte[i] ^ k)); //[b]亦或[/b]
i += 1;
}
}
public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt)
{
try
{
HelloJni.input = this.val$et.getText().toString();
this.val$tv.setText(HelloJni.this.getStr(HelloJni.this.xor(HelloJni.MD5(HelloJni.input)), HelloJni.input.getBytes()).toString()); [b][color=#ff0000]//直接输出so返回的字符串[/color][/b]
return;
}
SO层
[C] 纯文本查看 复制代码 int __fastcall Java_com_wuaipojie_CCCM_HelloJni_getStr(JNIEnv *a1, int a2, int xor_md5_input, int input_byte)
{
int v4; // r10
int v5; // r6
JNIEnv *env; // r4
const char *v7; // r9
size_t len; // r7
char *inputStr; // r8
char *name; // r5
const char *mark; // r2
const char *v12; // ST0C_4
int v13; // r1
char *buffer; // r5
int v15; // r0
int jbyteArray; // r7
int ArrayLength; // r0
const char *v18; // r1
v4 = input_byte;
v5 = xor_md5_input;
env = a1;
v7 = ((*a1)->GetByteArrayElements)(xor_md5_input); // byte[] 输入的参数
len = strlen(v7); //长度
inputStr = malloc(len); //分配内存空间
memcpy(inputStr, v7, len); //拷贝输入参数到inputStr字符串中
name = inputStr;
mark = "52pojie";
while ( name != &inputStr[len] ) //循环的作用和JAVA层的XOR是一样的.取反回到最初JAVA层的MD5
{
v12 = mark;
sub_5B068930(name - inputStr, 7); //取模
mark = v12;
*name ^= v12[v13];
++name;
}
buffer = &name[-len]; // 指针重新指向
v15 = ((*env)->GetArrayLength)(env, v5, mark);// 0x10
jbyteArray = ((*env)->NewByteArray)(env, v15);// 初始化了一个数组并未赋值
ArrayLength = ((*env)->GetArrayLength)(env, v5);
((*env)->SetByteArrayRegion)(env, jbyteArray, 0, ArrayLength, buffer);// 操作将buffer拷贝到数组中
((*env)->ReleaseByteArrayElements)(env, v5, v7, 0);
free(buffer);
if ( jbyteArray == v4 ) // 比较 jbyteArray是上面循环得到的最初MD5 , V4 是什么,是JAVA层的第二个参数
v18 = "Congratulations!";
else
v18 = "incorrect";
return ((*env)->NewStringUTF)(env, v18);
}
这里有个问题: if ( jbyteArray == v4 ) 相等才是正确的没错。但是jbyteArray是MD5。V4也是个byte数组但是值是JAVA层传递的第二个参数。
[Java] 纯文本查看 复制代码
HelloJni.input = this.val$et.getText().toString(); //输入的字符串
this.val$tv.setText(HelloJni.this.getStr(HelloJni.this.xor(HelloJni.MD5(HelloJni.input)), HelloJni.input.getBytes()).toString());
可以看到V4是字符串的BYTE。如果条件为TRUE必须要输入的字符串等于MD5字符串,有这种可能么,百度一下有但是几率很小。
最开始我以为V4是个动态值,于是我决定还是动态调试看看吧。发现是并非我所愿。货真价实的JAVA层参数2。
所以暂且总结这个是个坑,只能爆破了。。 |