SCTF-RE200破解笔记
来源:互联网 发布:李小璐遭网络诈骗 编辑:程序博客网 时间:2024/06/08 15:18
菜鸟一个,主要是学习Android破解,记录提高自己。
1. 准备环境
- IDA Pro 6.1以上版本
- Android 虚拟机或一部root的手机
- 安卓改之理(apktool与jeb也行)
- JD-Gui
2. 分析过程
首先利用ApkIDE将apk文件解压,获得以下结构,如何调用JD-Gui查看代码
从代码中可以看到,程序做了反调试的操作。输入的字符串为flag时,弹出来一个Toast提示,所以关键代码在libeasy中。
用IDA 打开libeasy,查找导出函数Java_com_syc_kitkat_func(为什么是这样子?请查找相关资料,JNI编程),但是找了半天没有发现此函数,顿时没了方向。
后来记起来,so文件申明注册函数,可以在JNI_Onload中注册。dex文件加载so文件时,首先会在导出函数中查找JNI_Onload函数,JNI_Onload的默认情况下,不需要我们去声明与定义,但是我们可以重写JNI_Onload,来注册func函数。
查看JNI_Onload函数,由于对arm不是很熟,直接用IDA+f5 arm插件
可以看出,真正处理字符串的函数为cxa_begin_match函数。
查看cxa_begin_match函数
这里先说明下,主办方给了提示:反调试,代码在.init段
我们查看.init段,发现定义了个函数,_cxa_chk_fail函数。
该函数创建了一个线程执行某些任务。
void __fastcall sub_1A74(){ __pid_t v0; // r4@2 int v1; // r6@2 FILE *v2; // r2@2 signed int v3; // r5@4 int v4; // r0@6 unsigned int v5; // r4@8 const char *v6; // r0@12 signed int v7; // r3@14 const char *v8; // r0@15 struct timeval tv; // [sp+Ch] [bp-ECh]@2 struct timeval v10; // [sp+14h] [bp-E4h]@10 char command; // [sp+1Ch] [bp-DCh]@2 char s; // [sp+5Ch] [bp-9Ch]@2 int v13; // [sp+DCh] [bp-1Ch]@1 v13 = _stack_chk_guard; while ( 1 ) { gettimeofday(&tv, 0); v0 = getpid(); v1 = sub_1880();//判断pid中,status的状态 memset(&s, 0, 0x80u); memset(&command, 0, 0x40u); sprintf(&command, "cat /proc/%d/wchan", v0); v2 = popen(&command, "r"); if ( v2 ) fgets(&s, 128, v2); v3 = 17; if ( strncasecmp(&s, "sys_epoll_wait", 0xEu) ) v3 = (unsigned int)strncasecmp(&s, "ptrace_stop", 0xBu) <= 0; v4 = sub_1910(v0);//判断TracePid的值,一般为0 if ( v3 == 1 || v1 == 2 ) v5 = 0; else v5 = (v4 | (unsigned int)(v4 - 1)) >> 31; gettimeofday(&v10, 0); if ( v5 ) { if ( !tempabc[0] )//如果为空,赋值为syc { v6 = (const char *)gun_Unwind1("u{e");//syc strcpy(tempabc, v6); } if ( !m_y ) { v7 = 6;LABEL_20: m_y = v7;//m_y=9 goto LABEL_21; } } else { v8 = (const char *)gun_Unwind1("zevh");tempabc等于"xctf" if ( strcmp(tempabc, v8) ) strcpy(tempabc, "xctf"); if ( m_y == 6 || !m_y ) { v7 = 9; goto LABEL_20; } }LABEL_21: sleep(0xFu); }}
也就是,共享so初始化了几个内容,最终初始化tempabc=“xctf”或“syc”(根据环境),m_y=9或6。
之后,当点击wa按钮后,cxa_begin_match函数执行,做了很多的判断,判断进程的运行状态等。最终的字符串处理也在这。
if ( (signed int)v6 <= 32 && (j = v6 <= 0, str1 = str, v6 > 0) ) { while ( j < (signed int)v6 ) // 字符串与自己所在位置进行异或 { ++j; *(_BYTE *)str1 ^= j; str1 = (char *)str1 + 1; } sleep(1u); getpid(); v9 = getppid(); if ( !aeabi_unwind_pr0(v4, v9, &s1) ) exit(0); v10 = (const char *)jiemi(v4, "hec"); // gdb if ( !strcmp(&s1, v10) || (v11 = (const char *)jiemi(v4, "tusbdf"), !strcmp(&s1, v11)) )// strace gun_Unwind_Resume(v4, str); // exit(0) imp_Unwind_k(v4, (const char *)str, m_y); // 将字符串位置交换,向左交换m_y 放到tempstr中 v12 = gun_armfini_33(v4, tempStr, tempabc, (int)&s);// 简单的字符串交换,并且判断字符串条件,正确返回1 if ( v12 ) { v12 = 0; if ( v16 > 15 ) { strcpy(dest, &v21); strncpy((char *)&seed, &src, 3u); // src存的是输入的字符串变换后的24个字符 gun_armfini_21(v4, tempabc, dest); // 计算出dest字符串 v13 = 0; for ( i = 0; i < strlen(dest); ++i ) // 字符串转化为16进制形式表示,放到v23中 { sprintf(&v18, "%x", (unsigned __int8)dest[i]); v14 = strlen(&v18); strncpy(&v23[v13], &v18, v14); v13 += strlen(&v18); } v12 = gun_arm_ldiv0(v4, v23) & 0xFF; // 比对字符串是否为a8e5588f7e3f758 } } }
其中imp_Unwind_k的处理如下,其中v5为字符串长度
while ( v8 < v5 ) // 以v12为单位进行字符串移位,往左移 { v9 = (v8 + v12) % v5; v10 = v4[v8++]; s[v9] = v10; } result = strncpy(tempStr, s, v5);
gun_armfini_33对字符串做单表替换,然后比较比较前11位字符,通过四个方程及其它位数进行计算得出前11位字符为GoodCrack3R,然后后5位字符,与(tempabc计算生成的值)dest进行异或,然后再与a8e5588f7e3f758进行比较。
最终的逆向的程序为:
import binasciidata="GoodCracK3R;{0jN|B6"tmp=""key="syc"print len(data)for i in range(0,len(data)): if ord(data[i])>=65 and ord(data[i])<=90 : tmp = tmp + chr(65+ (ord(data[i])-65 - (ord(key[i%len(key)])-97))%26) print tmp elif ord(data[i])>=97 and ord(data[i])<=122 : tmp = tmp + chr(97+ (ord(data[i])-97 - (ord(key[i%len(key)])-97))%26) print tmp else: tmp = tmp + data[i] print tmpprint tmpdata = tmptmp=range(len(data))for i in range(0,len(data)): tmp[(i-6)%len(data)]=data[i]data = ''.join(tmp)print datatmp=""for i in range(0,len(data)): tmp=tmp+chr(ord(data[i])^(i+1))print tmp
0 0
- SCTF-RE200破解笔记
- 【SCTF&&CCTF 2016】 PWN_WRITEUP
- sctf 2014 pwn300
- 171108 逆向-SWPU(re200)
- 171218 逆向-TPCTF(re200)
- 破解/汇编学习笔记
- 简单破解教程 笔记
- 破解教程笔记
- Polyforge破解笔记
- sourceInsight4 破解笔记
- LoadRunner11安装+破解 笔记
- sourceInsight4破解笔记
- 破解笔记 -- 黑鹰 1、破解工具介绍
- 破解学习笔记-----不脱壳破解
- [破解]Shark恒破解基础教程笔记
- sourceInsight4 破解笔记(完美破解)
- sourceInsight4 破解笔记(完美破解)
- sourceInsight4 破解笔记(完美破解)
- Find Peak Element
- CUGB14年校赛 C黄焖鸡与矩阵[粉色]
- 采用反射处理多重if else
- 【学习ios之路:C语言】字符串溢出情况分析.
- Cocoapods
- SCTF-RE200破解笔记
- smb
- 什么是JUKI多功能贴片机
- C++视频教程:C++实战水果忍者游戏
- JS操作JSON总结
- Servlet调用流程
- 不可重入函数和可重入函数 线程安全性
- 绑定自定义类到Runtime(Lua-binding)
- android Intent机制详解