逆向驿站
-
网络安全咨询
-
日常生活中的网络安全案例解析
-
逆向反汇编学习资料
-
渗透测试学习资料
-
实战病毒分析、软件逆向研究
-
相关基本功知识速查工具
-
区块链相关基础知识
网盘链接
https://pan.baidu.com/s/1YZqr9kFVu2R6R4rbgpepjQ
提取码: q8tc
如果失效,获取最新链接,请公众号内回复:网盘
前言
看了道青龙组的reverse,难度适中,反正我花了一个多小时手算的,真比赛估计动态分打折的也厉害。
准备
【环境和工具】
-
win7/xp/2003虚拟机环境
-
olldbg
-
IDA
图文分析
查壳
-
无壳
观察程序字符串入手定位代码
-
报错字符串
-
字符串入手很快可以定位长度
动态跟踪关键代码
IDA定位并F5翻译伪C码
G快捷输入函数入口地址
F5翻译(学习不建议,考试建议)
那么到底是如何快速的看到case1和case7是关键的,分析如下
分析过程
-
首先看到不一样的case是case7,很简单就可以看到程序判断逻辑
-
如果想让程序不羞辱你(what a shame),那么只有两个办法,要么不进入case7,要么进入case7并且满足条件
-
然而根据考试逻辑,不进入的概率极低
-
case7条件关键值比较值是v4数组和a1数组
-
a1数组在整个程序段均为右侧值(这点很基础也很重要),即不会背这个程序段赋值,即相对不变
-
v4数组值的赋值(黄色),仅仅case1中的右侧值v5
-
而v5作为左侧被赋值的地方就多了,先忽略是怎么赋值的,但观察来全是可逆运算,即简单的加减乘除和异或,除了有个取byte的可能存在数据丢失(丢失范围可控)
-
其他case给v5赋值→v5给case1中v4数组赋值→v4数组在case7中跟相对不变的数组a1作比较
-
所以重点关注case1,case7,a1,v4即可
-
重中之重是a1数组,因为switch的条件就是a1
OD动态调试看a1数组
-
可见a1数组十分有规律
-
我们重点关注1,7(分别用红黄标记了)
-
更发现1间隔大体规律出现共16个
-
7最后出现,间隔固定规律出现共15个
-
flag长度要求15
-
截至到此,基本程序逻辑结合上面代码就已经可以猜个大概了
-
也就是每个字符位经过几个case最终等于v5,v5在case1中给v4数组赋值
-
赋值完毕后(15轮),分别在case7中跟a1数组7后的那个数字比较
-
15轮比较都相等就程序就不报错退出羞辱你
知道了逻辑,动态调试一下验证一下(如果正在考试,这个过程咋快咋来,否则也许直接损失100-200分),因为只有15个逐位计算,那么代码功底好的可以考虑直接复制伪C源码,逐位爆破出结果。
最终我的选择,修改复制伪C源码,放入VS动态调试逐位计算,其实也挺快,因为运行两组就基本发现X8X1,即一个或两个别的case,然后一个case8(等于是中间值的迷惑写法),然后一个其他case,然后在case1。
源码如下
int vm_operad(int *a1, int a2)
{
int result; // eax@2
char Str[]="123456789012345"; // [sp+13h] [bp-E5h]@4
char v4[100]; // [sp+77h] [bp-81h]@5
char v5; // [sp+DBh] [bp-1Dh]@5
int v6; // [sp+DCh] [bp-1Ch]@1
int v7; // [sp+E0h] [bp-18h]@1
int v8; // [sp+E4h] [bp-14h]@1
int v9; // [sp+E8h] [bp-10h]@1
int v10; // [sp+ECh] [bp-Ch]@1
v10 = 0;
v9 = 0;
v8 = 0;
v7 = 0;
v6 = 0;
while ( 1 )
{
result = v10;
if ( v10 >= a2 )
return result;
switch ( a1[v10] )
{
case 10:
// read(Str);
++v10;
break;
case 1:
v4[v7] = v5;
++v10;
++v7;
++v9;
break;
case 2:
v5 = a1[v10 + 1] + Str[v9];
v10 += 2;
break;
case 3:
v5 = Str[v9] - LOBYTE(a1[v10 + 1]);
v10 += 2;
break;
case 4:
v5 = a1[v10 + 1] ^ Str[v9];
v10 += 2;
break;
case 5:
v5 = a1[v10 + 1] * Str[v9];
v10 += 2;
break;
case 6:
++v10;
break;
case 7:
if ( v4[v8] != a1[v10 + 1] )
{
printf("what a shame...");
exit(0);
}
++v8;
v10 += 2;
break;
case 11:
v5 = Str[v9] - 1;
++v10;
break;
case 12:
v5 = Str[v9] + 1;
++v10;
break;
case 8:
Str[v6] = v5;
++v10;
++v6;
break;
default:
continue;
}
}
}
int main()
{
int a[]={0x0A,0x04,0x10,0x08,0x03,0x05,0x01,0x04,0x20,0x08,0x05,0x03,0x01,0x03,0x02,0x08,0x0B,0x01,0x0C,0x08,0x04,0x04,0x01,0x05,0x03,0x08,0x03,0x21,0x01,0x0B,0x08,0x0B,0x01,0x04,0x09,0x08,0x03,0x20,0x01,0x02,0x51,0x08,0x04,0x24,0x01,0x0C,0x08,0x0B,0x01,0x05,0x02,0x08,0x02,0x25,0x01,0x02,0x36,0x08,0x04,0x41,0x01,0x02,0x20,0x08,0x05,0x01,0x01,0x05,0x03,0x08,0x02,0x25,0x01,0x04,0x09,0x08,0x03,0x20,0x01,0x02,0x41,0x08,0x0C,0x01};
int *p = a;
return vm_operad(p,90);
}
另外,经常会遇到OD中二进制粘贴出来的数据,要变成十六进制的数组格式,可以自己写个小工具来提高效率,我自己就写了个python的小工具来提高效率
strod = '''0A 04 10 08 03 05 01 04
20 08 05 03 01 03 02 08
0B 01 0C 08 04 04 01 05
03 08 03 21 01 0B 08 0B
01 04 09 08 03 20 01 02
51 08 04 24 01 0C 08 0B
01 05 02 08 02 25 01 02
36 08 04 41 01 02 20 08
05 01 01 05 03 08 02 25
01 04 09 08 03 20 01 02
41 08 0C 01 '''
strod=strod.replace("n"," ")
hexlists = strod.split(" ")
laststr=""
conut = 0
s=''
for hexlist in hexlists:
#byte
if(tpye == '1'):
laststr=laststr+"0x"+hexlist+","
#word
if(tpye == '2'):
if (conut%2==0):
s = hexlist
else:
laststr=laststr+"0x"+hexlist + s +","
s = ''
conut = conut +1
print(laststr)
这个难度适中,去网盘中下载,试试吧
最后,喜欢这里的请推荐给你身边的朋友吧(渗透测试、逆向破解、病毒分析、信息安全等)
网盘链接
https://pan.baidu.com/s/1YZqr9kFVu2R6R4rbgpepjQ
提取码: q8tc
如果失效,获取最新链接,请公众号内回复:网盘
● CrackMe-8.9.10精解-VB反汇编特点汇总
End
本公众号关注网络安全最新咨讯
逆向反汇编、病毒分析教学等
常按二维码关注
原文始发于微信公众号(逆向驿站):网鼎2020-Reverse-Signal详解
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论