@TOC
刮开有奖 运行发现有点劣质的刮奖卡片的感觉 查壳无壳32位ida打开 ctrl+F搜索主函数只看到这个 于是shift+F12查看字符串发现这个 双击过去交叉引用发现是函数DialogFunc
刚好对应主函数里调用的函数完美 最后有个判断然后得出结果,所以看一下v7之类的是什么 可以知道输入的String是8个字符,然后v7-v17经过了函数sub_4010F0
的处理 看一下这个函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 int __cdecl sub_4010F0 (int a1, int a2, int a3) { int result; int i; int v5; int v6; result = a3; for ( i = a2; i <= a3; a2 = i ) { v5 = 4 * i; v6 = *(_DWORD *)(4 * i + a1); if ( a2 < result && i < result ) { do { if ( v6 > *(_DWORD *)(a1 + 4 * result) ) { if ( i >= result ) break ; ++i; *(_DWORD *)(v5 + a1) = *(_DWORD *)(a1 + 4 * result); if ( i >= result ) break ; while ( *(_DWORD *)(a1 + 4 * i) <= v6 ) { if ( ++i >= result ) goto LABEL_13; } if ( i >= result ) break ; v5 = 4 * i; *(_DWORD *)(a1 + 4 * result) = *(_DWORD *)(4 * i + a1); } --result; } while ( i < result ); } LABEL_13: *(_DWORD *)(a1 + 4 * result) = v6; sub_4010F0(a1, a2, i - 1 ); result = a3; ++i; } return result; }
参数齐全很清晰,可以改一下数组然后用C语言跑出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <stdio.h> void main () { int v7[11 ]; int sub_4010F0 (int a1[], int a2, int a3) ; v7[0 ] = 90 ; v7[1 ] = 74 ; v7[2 ] = 83 ; v7[3 ] = 69 ; v7[4 ] = 67 ; v7[5 ] = 97 ; v7[6 ] = 78 ; v7[7 ] = 72 ; v7[8 ] = 51 ; v7[9 ] = 110 ; v7[10 ] = 103 ; sub_4010F0(v7, 0 , 10 ); for (int i=0 ;i<11 ;i++) { printf ("%d " ,v7[i]); } } int __cdecl sub_4010F0 (int a1[], int a2, int a3) { int result; int i; int v5; int v6; result = a3; for ( i = a2; i <= a3; a2 = i ) { v5 = i; v6 = a1[i]; if ( a2 < result && i < result ) { do { if ( v6 > a1[result] ) { if ( i >= result ) break ; ++i; a1[v5] = a1[result]; if ( i >= result ) break ; while ( a1[i] <= v6 ) { if ( ++i >= result ) goto LABEL_13; } if ( i >= result ) break ; v5 = i; a1[result] = a1[i]; } --result; } while ( i < result ); } LABEL_13: a1[result] = v6; sub_4010F0(a1, a2, i - 1 ); result = a3; ++i; } return result; }
运行结果: 可以使用Python改成字符
1 2 3 4 5 arr = [51 ,67 ,69 ,72 ,74 ,78 ,83 ,90 ,97 ,103 ,110 ] x = "" for i in range (0 , len (arr)): x+=chr (arr[i]) print(x)
这就是新的v7到v17的值3CEHJNSZagn 我们回到函数DialogFunc
,接着往后面看 双击v23,v25之类的发现都会跳到这里 可知v23为string[5],快捷键N依次修改 后面的if判断有v4,v5,这里可以看到v4,v5经过了函数sub_4010001的处理,分析sub_401000函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 _BYTE *__cdecl sub_401000 (int *a1, int a2) { int v2; int v3; size_t v4; _BYTE *v5; _BYTE *v6; int v7; _BYTE *v8; int v9; signed int v10; int v11; signed int v12; signed int v13; _BYTE *result; _BYTE *v15; _BYTE *v16; int v17; int v18[4 ]; v2 = a2 / 3 ; v3 = 0 ; if ( a2 % 3 > 0 ) ++v2; v4 = 4 * v2 + 1 ; v5 = malloc (v4); v6 = v5; v15 = v5; if ( !v5 ) exit (0 ); memset (v5, 0 , v4); v7 = a2; v8 = v6; v16 = v6; if ( a2 > 0 ) { while ( 1 ) { v9 = 0 ; v10 = 0 ; v18[0 ] = 0 ; do { if ( v3 >= v7 ) break ; ++v10; v9 = *(a1 + v3++) | (v9 << 8 ); } while ( v10 < 3 ); v11 = v9 << 8 * (3 - v10); v12 = 0 ; v17 = v3; v13 = 18 ; do { if ( v10 >= v12 ) { *(v18 + v12) = (v11 >> v13) & 63 ; v8 = v16; } else { *(v18 + v12) = 64 ; } *v8++ = byte_407830[*(v18 + v12)]; v13 -= 6 ; ++v12; v16 = v8; } while ( v13 > -6 ); v3 = v17; if ( v17 >= a2 ) break ; v7 = a2; } v6 = v15; } result = v6; *v8 = 0 ; return result; }
再看byte_407830
的值,刚好是 符合base64加密规律 所以将 base64解密为jMp和WP1
再推上面的 而且是8位 所以对比可知道string = “UJWP1jMp”
flag:flag{UJWP1jMp}
[GXYCTF2019]luck_guy ida64 将用户输入的字符串存到v4中,然后作为函数patch_me()
的参数 查看函数get_flag()
取0~199的随机数,case1 case4 case5
才是有效路径,并且需要按照一定顺序才能得出结果。 根据判断顺序应该为case4 case5 case1
flag是由f1和f2拼接而成,f1已知,f2在case4中,但是f2形式不太对,观察case5的代码,是对长度为8的字符串进行操作,f2(0x7F666F6067756369两位一划分)的长度正好也是8,猜测用来与f1进行拼接形成flag的字符串是f2进行了case5操作后的数据。 分一下f2,再考虑小端序存储,
1 f2=[0x7F ,0x66 ,0x6F ,0x60 ,0x67 ,0x75 ,0x63 ,0x69 ][::-1 ]
写脚本
1 2 3 4 5 6 7 8 9 flag="GXY{do_not_" f2=[0x7F ,0x66 ,0x6F ,0x60 ,0x67 ,0x75 ,0x63 ,0x69 ][::-1 ] for j in range (8 ): if j%2 ==1 : s=chr (f2[j]-2 ) else : s=chr (f2[j]-1 ) flag+=s print (flag)
解出来是GXY{do_not_hate_me}
由于题目要求,所以最后的flag是:flag{do_not_hate_me}
findit 题目叙述的有点好笑,看题 APK逆向,上JEB,看主函数有一段可疑的字符串 第五个数据是“{”的asscii,最后一个是“}”的ascii,所以这串数据很可能和flag有关,用脚本跑出字符串。
1 2 3 4 5 6 7 8 9 10 a=[ 0x70 ,0x76 ,0x6B ,0x71 ,0x7B ,0x6D ,0x31 , 0x36 ,0x34 ,0x36 ,0x37 ,0x35 ,0x32 ,0x36 , 0x32 ,0x30 ,0x33 ,0x33 ,0x6C ,0x34 ,0x6D , 0x34 ,0x39 ,0x6C ,0x6E ,0x70 ,0x37 ,0x70 , 0x39 ,0x6D ,0x6E ,0x6B ,0x32 ,0x38 ,0x6B , 0x37 ,0x35 ,0x7D ] s='' for i in a: s+=chr (i) print(s)
pvkq{m164675262033l4m49lnp7p9mnk28k75}
跑出来是上面这个,观察一下特别像凯撒 f->p 10位 后面都是flag移动10位是pvkq 使用在线工具移动一下
flag{c164675262033b4c49bdf7f9cda28a75}
简单注册机 APK逆向,上JEB tab键反编译,核心代码为这一部分 按照JAVA代码写Python脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 str =['d' ,'d' ,'2' ,'9' ,'4' ,'0' ,'c' ,'0' ,'4' ,'4' ,'6' ,'2' ,'b' ,'4' ,'d' ,'d' ,'7' ,'c' ,'4' ,'5' ,'0' ,'5' ,'2' ,'8' ,'8' ,'3' ,'5' ,'c' ,'c' ,'a' ,'1' ,'5' ]str [2 ]=chr (ord (str [2 ])+ord (str [3 ])-50 )str [4 ]=chr ( ord (str [2 ])+ord (str [5 ])-0x30 )str [30 ]=chr ( ord (str [0x1f ])+ord (str [9 ])-0x30 )str [14 ]=chr ( ord (str [27 ])+ord (str [28 ])-97 )for i in range (16 ): x=str [0x1f -i] str [0x1f -i]=str [i] str [i]=x for i in str : print (i,end="" )
flag:flag{59acc538825054c7de4b26440c0999dd}
[BJDCTF2020]JustRE ida打开,搜素main函数价值不大,搜索字符串,发现一个类似flag的字符串 交叉引用过去看函数 第14行代码,sprintf补齐,查看aBjdDD2069a4579
刚好补充19999 和 0 flag是:flag{1999902069a45792d233ac}