Jarvis OJ部分逆向题解
很久没有写博客了,前天上Jarvis OJ刷了几道逆向,保持了一下感觉。都是简单题目,写个writeup记录一下。
easycrackme
int __cdecl main(int argc, const char **argv, const char **envp) { __int64 v3; // rdi char v5; // [rsp+0h] [rbp-38h] char v6; // [rsp+1h] [rbp-37h] char v7; // [rsp+2h] [rbp-36h] char v8; // [rsp+3h] [rbp-35h] char v9; // [rsp+4h] [rbp-34h] char v10; // [rsp+5h] [rbp-33h] unsigned __int8 v11; // [rsp+10h] [rbp-28h] _BYTE v12[7]; // [rsp+11h] [rbp-27h] v5 = -85; v6 = -35; v7 = 51; v8 = 84; v9 = 53; v10 = -17; printf((unsigned __int64)"Input your password:"); _isoc99_scanf((unsigned __int64)"%s"); if ( strlen((const char *)&v11) == 26 ) // 这里的strlen函数被去符号表解析了 { v3 = 0LL; if ( (v11 ^ 0xAB) == list1 ) // 输入的第一个字母:"P",list1这里有关键数据 { while ( (v12[v3] ^ (unsigned __int8)*(&v5 + ((signed int)v3 + 1) % 6)) == byte_6B41D1[v3] ) { if ( ++v3 == 25 ) { printf((unsigned __int64)"Congratulations!"); return 0; } } } } printf((unsigned __int64)"Password Wrong!! Please try again."); return 0; }
静态分析找到代码,把byte_6841D1和list1那里的关键数据提取出来,直接逆向算法。
ch=[171,221,51,84,53,239] list1=[0x9E,0x67,0x12,0x4E,0x9D,0x98,0xAB,0,6,0x46,0x8A,0xF4,0xB4,6,0x0B,0x43,0xDC,0xD9,0xA4,0x6C,0x31,0x74,0x9C,0xD2,0xA0] print(len(list1)) temp,temp_ch=0,'' flag='' flag+='P' for i in range(25): temp=list1[i]^ch[(i+1)%6] temp_ch=chr(temp) print(temp_ch) flag+=temp_ch print(flag)
Baby's Crack
int __cdecl main(int argc, const char **argv, const char **envp) { int result; // eax char Dest; // [rsp+20h] [rbp-80h] FILE *v5; // [rsp+88h] [rbp-18h] FILE *File; // [rsp+90h] [rbp-10h] char v7; // [rsp+9Fh] [rbp-1h] const char **v8; // [rsp+B8h] [rbp+18h] v8 = argv; if ( argc <= 1 ) { printf("Usage: %s [FileName] ", *argv, envp); printf("FileName是待加密的文件"); exit(1); } File = fopen(argv[1], "rb+"); if ( File ) { v5 = fopen("tmp", "wb+"); // v5是文件操作符 while ( feof(File) == 0 ) { v7 = fgetc(File); if ( v7 != -1 && v7 ) // -1表示读取到文件末尾EOF { if ( v7 > 47 && v7 <= 96 ) { v7 += 53; } else if ( v7 <= 46 ) { v7 += v7 % 11; } else { v7 = 61 * (v7 / 61); } fputc(v7, v5); } } fclose(v5); fclose(File); sprintf(&Dest, "del %s", v8[1]); system(&Dest); sprintf(&Dest, "ren tmp %s", v8[1]); system(&Dest); result = 0; } else { printf("无法打开文件%s ", v8[1]); result = -1; } return result; }
这里提供了flag的加密文件flag.enc,从关键代码这里来看,我们只要在字母表中找准对应的映射就可以了。脚本如下:
# -*- coding: utf-8 -* import string with open("C://Users//wolf//Desktop//babyscrack//flag.enc",'rb+') as f: flag_info=f.read() print(flag_info) def encrypto(a): if a!='xff' and a: if ord(a)>47 and ord(a)<=96: a=chr(ord(a)+53) elif ord(a)<=46: a=chr(ord(a)+ord(a)%11) else: a=chr(61*(ord(a)/61)) return a enc='jeihjiiklwjnk{ljj{kflghhj{ilk{k{kij{ihlgkfkhkwhhjgly' print(string.printable) flag="" for i in enc: for j in string.printable: if i==encrypto(j): flag+=j break print(flag.decode('hex'))
stheasy
这道题有一个小坑点在int8那里,表明是取后8位做抑或。
signed int __cdecl check(int a1) { int v1; // eax int v3; // edx if ( a1 ) { v1 = sub_804849C(a1); if ( v1 ) { if ( v1 == 29 ) { v3 = 0; while ( *(_BYTE *)(a1 + v3) == byte_8049AE0[(unsigned __int8)((unsigned __int8)byte_8049B15[v3] / 3u - 2)] ) { if ( ++v3 == 29 ) return 1; } } } } return 0; }
s="k2j9Gh}AgfY4ds-a6QW1#k5ER_T[cvLbV7nOm3ZeX{CMt8SZo]U" flag_info=[0x48,0x5D,0x8D,0x24,0x84,0x27,0x99,0x9F,0x54,0x18,0x1E,0x69,0x7E,0x33, 0x15,0x72,0x8D,0x33,0x24,0x63,0x21,0x54,0x0C,0x78,0x78,0x78,0x78,0x78,0x1B] print(len(flag_info)) print(len(s)) index,temp,flag,idx=0,"","",[] for i in flag_info: temp=bin(i/3-2) if len(temp)>=10: temp=temp[-8:] else: temp=temp[2:] index=int(temp,2) idx.append(index) for i in idx: flag+=s[i-1] print(flag)
1.Hello
这题有个反调试,但是不影响,静态分析就能出。start函数和dummy函数地址相减的地方注意一下,逻辑写正确即可。
int __cdecl main(int argc, const char **argv, const char **envp) { int result; // eax signed int v4; // [rsp+1Ch] [rbp-14h] int v5; // [rsp+24h] [rbp-Ch] v5 = ((unsigned __int64)((char *)start - (char *)dummy) >> 2) ^ flag_data[0]; result = anti_debug(); if ( !(result & 1) ) { v4 = 0; while ( v4 < 55 ) { flag_data[v4] -= 2; flag_data[v4] ^= v5; ++v4; ++v5; } result = printf(" Final output is %s ", &flag_data[1]); } return result; }
flag_data=[0x41, 0x10, 0x11,0x11,0x1B, 0x0A, 0x64, 0x67, 0x6A, 0x68, 0x62, 0x68, 0x6E, 0x67, 0x68, 0x6B, 0x62, 0x3D, 0x65, 0x6A,0x6A, 0x3D, 0x68, 0x4, 0x5, 0x8, 0x3, 0x2,0x2, 0x55, 8, 0x5D, 0x61, 0x55, 0xA, 0x5F, 0x0D, 0x5D, 0x61, 0x32, 0x17, 0x1D, 0x19, 0x1F, 0x18, 0x20, 0x4, 0x2, 0x12, 0x16, 0x1E, 0x54,0x20,0x13,0x14] print(len(flag_data)) v5=((0xcb0-0xc90)>>2)^flag_data[0] v4,flag=0,"" while(v4<55): flag_data[v4]-=2 flag_data[v4]^=v5 flag+=chr(flag_data[v4]) v4+=1 v5+=1 print(flag)
Classical Crackme
这道题去了符号表,加了返混淆,好像还是C#写的,但是没关系,直接去找字符串常量,发现有一串字符串
一看就是base64加密的,解密之后就是flag。
findkey
这是一道python逆向的题目,直接用IDA看显示的就是字节码。在linux下用file查一下,发现应该是一个pyc,这时候用在线网站进行一步反汇编,拿到源码之后,逆向算法,exp如下所示。
lookup = [196,153,149,206,17,221,10,217,167,18,36,135,103,61,111,31,92,152,21,228,105,191, 173,41,2,245,23,144,1,246,89,178,182,119,38,85,48,226,165,241,166,214,71,90,151,3, 109,169,150,224,69,156,158,57,181,29,200,37,51,252,227,93,65,82,66,80,170,77,49,177, 81,94,202,107,25,73,148,98,129,231,212,14,84,121,174,171,64,180,233,74,140,242,75, 104,253,44,39,87,86,27,68,22,55,76,35,248,96,5,56,20,161,213,238,220,72,100,247,8, 63,249,145,243,155,222,122,32,43,186,0,102,216,126,15,42,115,138,240,147,229,204,117, 223,141,159,131,232,124,254,60,116,46,113,79,16,128,6,251,40,205,137,199,83,54,188,19, 184,201,110,255,26,91,211,132,160,168,154,185,183,244,78,33,123,28,59,12,210,218,47, 163,215,209,108,235,237,118,101,24,234,106,143,88,9,136,95,30,193,176,225,198,197,194, 239,134,162,192,11,70,58,187,50,67,236,230,13,99,190,208,207,7,53,219,203,62,114,127, 125,164,179,175,112,172,250,133,130,52,189,97,146,34,157,120,195,45,4,142,139] pwda = [188,155,11,58,251,208,204,202,150,120,206,237,114,92,126,6,42] pwdb = [53,222,230,35,67,248,226,216,17,209,32,2,181,200,171,60,108] flag,temp="",0 for i in range(0,17): temp=lookup[i+pwdb[i]]-pwda[i]&255 flag+=chr(temp) flag=flag[::-1] print(flag)
软件密码破解-1
这道题肯定用strip把符号表全部都去掉了。静态分析的时候,修复符号表当然是一种思路,但是还是不够,我修复了大概7000个函数,还是很难找到关键代码,而且在IDA中找不到程序运行过程中出现过的一些字符串。这种时候,直接用OD的中文搜索引擎去找一些特殊的字符串,找到“你赢了”,然后很快地就可以定位到关键代码段。
脚本如下。
array_1=[0x1b,0x1c,0x17,0x46,0xf4,0xfd,0x20,0x30,0xb7,0xc,0x8e,0x7e,0x78,0xDE] array_2=[0xff,0x1a,0x4e,0xe4,0x53,0xe3,0x51,0x65,0x8f,0x93,0x6B,0x64,0x57,0x28] array_2=array_2[::-1] flag,temp="",0 for i in range(14): temp=array_1[i]^array_2[i] flag+=chr(temp) print(flag)