《攻防世界》MOBILE--easyjni
本帖最后由 HNHuangJingYU 于 2021-9-30 10:47 编辑1.将easyjni.apk拖进jeb分析代码,和常一样进入启动页分析(职业病了都)
2.这里介绍输入字符进行判断,往往,一看便知又是逆向算法的题目
3.核心函数,将输入的字符串传入a类中的a函数进行加密,点进来看就知道就是一个Base64加密,只不过换了码表,之后再将java加密后的字符串穿入so层加密并且进行判断,打开ida:
4.从这里知道memcmp函数就是将内存中的前0x20个字节数据进行对比相等则返回0,后面对v13进行了判断如果v13==0则这个函数返回true,分析下来很简单,就是我们输入的函数经过两层加密后要等于”MbT3sQgX039i3g==AQOoMQFPskB1Bsc7”,首先我们来正向分析下:
signed int __fastcall Java_com_a_easyjni_MainActivity_ncheck(_JNIEnv *env, int jclass, int string)
{
int v3; // r8
_JNIEnv *env_1; // r5
void *string_1; // r8
const char *data; // r6
int index; // r0
char *v8; // r2
char v9; // r1
int index2; // r0
bool v11; // nf
unsigned __int8 v12; // vf
int v13; // r1
signed int result; // r0
char s1; //
char v16; //
int v17; //
v17 = v3;
env_1 = env;
string_1 = string;
data = env->functions->GetStringUTFChars(&env->functions, string, 0);//分配内存存储字符串
if ( strlen(data) == 32 ) //java层加密后的数据必须为32长度的字符串
{
index = 0; //flag{just_ANot#er_@p3}
do
{
v8 = &s1;
s1 = data; //把data位 给 s1位
v9 = data; //把data位 给 s1位
v8 = v9;
}
while ( index != 16 ); //第一层循环是将data前16位和后16位换位置给s1
env_1->functions->ReleaseStringUTFChars(&env_1->functions, string_1, data); //清空jVM内存配合GetStringUTFChars使用
index2 = 0;
do
{
v12 = __OFSUB__(index2, 30);
v11 = index2 - 30 < 0;
v16 = s1;
s1 = s1;
s1 = v16;
index2 += 2;
}
while ( v11 ^ v12 ); //将s1索引处1,2换位置 3,4换位置依次类推
v13 = memcmp(s1, "MbT3sQgX039i3g==AQOoMQFPskB1Bsc7", 0x20u);
result = 0;
if ( !v13 )
result = 1;
}
else
{
env_1->functions->ReleaseStringUTFChars(&env_1->functions, string_1, data);
result = 0;
}
return result;
}
5.再进行逆向算法:@Test
public void demo6() {
//如果输入1234567890123456789012
//则加密后应该为:...9fH3T1Dd4coiKf==4f9GL1Cq91pKLfwW...........
//但是ida调试的时候显示这个字符串害我搞了半天:...9fH3T1Dd4coiKf==4f9GL1Cq91pKLfwWWb...........(求大佬解答)
System.out.println("----------------正向加密---------------");
String inputString = "1234567890123456789012";
System.out.println("输入的字符串:" + inputString);
inputString = new AClass().a(inputString.getBytes()); //这个就是apk中加密函数的a类只不过我换了个名字看的清楚点
System.out.println("java加密:" + inputString + "长度为:" + inputString.length());
char[] data = inputString.toCharArray();
char[] s1 = new char; //
char v9;
if (data.length == 32) {
int index = 0;
do {
s1 = data;
v9 = data;
s1 = v9;
index++;
}
while (index != 16);
//第二次循环
int index2 = 0;
char v16;
do {
v16 = s1;
s1 = s1;
s1 = v16;
index2 += 2;
}
while (index2 < 32);
System.out.println("so加密后:");
System.out.println(s1);
}
System.out.println("----------------逆向还原flag---------------");
String flag = "MbT3sQgX039i3g==AQOoMQFPskB1Bsc7";
StringBuilder sb = new StringBuilder();
char[] chars = flag.toCharArray();
for (int i = 0; i < chars.length; i += 2) {
char aChar = chars;
chars = chars;
chars = aChar;
}
List<Character> list = new ArrayList<>();
for (int i = 0; i < chars.length; i++) {
if (i < 16) {
list.add(chars);
chars = chars;
} else
chars = list.get(i - 16);
sb.append(chars);
}
System.out.println("so还原:");
System.out.println(sb);
System.out.println("java还原:");
new AClass().Base64Decode(sb.toString()); //java层逆向解码
}
6.再使用还原还原,这里就是easy_apk那题的向算法:public void Base64Decode(String enflag) {
StringBuilder flag = new StringBuilder();
String flag_temp = "";
for(int i = 0;i < enflag.length();i+=4)
{
String enf = enflag.substring(i,i+4);
byte flag1 = (byte)(((getIndex(enf.charAt(0)) & 255) << 2 | ((getIndex(enf.charAt(1)) & 255) >>> 4)));
byte flag2 = (byte)(((getIndex(enf.charAt(1)) & 255) << 4 | ((getIndex(enf.charAt(2)) & 255) >>> 2)));
byte flag3 = (byte)(((getIndex(enf.charAt(2)) & 255) << 6 | ((getIndex(enf.charAt(3)) & 255))));
flag_temp = "" + (char)flag1 + (char)flag2 + (char)flag3;
flag.append(flag_temp);
}
System.out.println(flag);
}
public byte getIndex(char x)
{
byte index = -1;
String talbe = new String(AClass.a);
if(x != '=') {
index = (byte) talbe.indexOf(x);
}
else {
index = 0;
}
return index;
}
最后打印结果:flag{just_ANot#er_@p3}
大佬,你是咋修复jni 结构的 Design 发表于 2021-9-30 10:31
大佬,你是咋修复jni 结构的
正常情况来说,如果是静态函数那么参数一是JNIEnv,参数二是jclass,参数三、四就是java传入的参数了,动态函数(JNIOnload)参数一就是JavaVm,参数二是jobject,参数三、四上同,明白了对应的参数类型用jni.h头文件进行转化就可以了 HNHuangJingYU 发表于 2021-9-30 10:38
正常情况来说,如果是静态函数那么参数一是JNIEnv,参数二是jclass,参数三、四就是java传入的参数了,动 ...
可以顺便上传样本吗 技术就是生产力呀
页:
[1]