适合新手的虚拟机逆向----2019UNCTF easyvm
看题目知道这是一个虚拟机逆向题目,运行一下知道这是匹配字符串之后用IDA64进行分析,主函数的逻辑还是比较清楚的。先给s上的96字节置0,再给v3分配40字节空间。调用sub_400C1E初始化v3上的内容。用s接收32字符,如果不是32长度就失败,如果是,则调用 **v3函数指针所对应的函数,参数分别是v3, &unk_602080, &unk_6020A0, &s,最后的!=0可以猜测这个函数返回值是逻辑型。
这里的V3是一个函数指针,接着分析比较重要的初始化v3的函数sub_400C1E,注意到有个特别的地方:*(_QWORD *)a1 = off_4010A8
之后查看off_4010A8的内容,发现都是一些函数的偏移量。所以这里也可以知道**v3调用的就是sub_400806这个函数
接着就开始分析sub_400806这个函数(根据理解稍作改动)这个时候再看一下constvalue和checkcode
接下来重新分析sub_400806函数,函数首先将offset+8被赋值0xa9对应的地址
这样就可以看switch中值为0xA9的内容,发现执行offset+80函数指针对应的函数,参数为offset,之后(offset+8)-6,也就是下一个循环将执行0xA3的内容。这里就相当于执行一条命令之后,某个位置的值减去一个值。有点像IP,结合其他case也可以做出这个大胆的假设----offset+8相当于IP
接下来分析offset+80对应的函数,这里可以知道*(_BYTE *)(a1 + 16)=*(_BYTE *)(input+*(unsigned __int8 *)(a1 + 18))
接着执行0xA3处的代码
同样可以得到sub_400CD6的代码
依次类推。可以按照这个规则先推到处程序执行switch的顺序0xA9u 0xA3u 0xA5u 0xA6u 0xA4u 0xABu 0xA7u 0xAEu 0xA2u 0xADu 0xAFu同理也可以写出其执行的代码过程A9(){ *(_BYTE *)(a1 + 16)=*(_BYTE *)(input + *(unsigned __int8 *)(a1 + 18))} A3(){ *(_BYTE *)(a1 + 16) -= *(_BYTE *)(a1 + 18)} A5(){ *(_BYTE *)(a1 + 17) ^= *(_BYTE *)(a1 + 16)} A6(){ *(_BYTE *)(a1 + 16) = 0xCD} A4(){ *(_BYTE *)(a1 + 16) ^= *(_BYTE *)(a1 + 17)} AB(){ if ( *(_BYTE *)(a1 + 16) == *(_BYTE *)(*(_QWORD *)(a1 + 24) + *(unsigned __int8 *)(a1 + 18)) ) *(_DWORD *)(a1 + 20) = 0 else if ( *(_BYTE *)(a1 + 16) >= *(_BYTE *)(*(_QWORD *)(a1 + 24) + *(unsigned __int8 *)(a1 + 18)) ) *(_DWORD *)(a1 + 20) = 1 else *(_DWORD *)(a1 + 20) = -1} A7(){ ++*(_BYTE *)(a1 + 16)} AE(){ if ( *(_DWORD *)(a1 + 20) ) return 0 else goto A2()} A2(){ ++*(_BYTE *)(a1 + 18)} AD(){ if ( *(_BYTE *)(a1 + 18) > 0x1Fu ) *(_DWORD *)(a1 + 20) = 1 else *(_DWORD *)(a1 + 20) = 0} AF(){ if ( *(_DWORD *)(a1 + 20) != 1 ) goto A9() else return 1}
感谢楼主分享 会去试试看 段某人 发表于 2020-3-16 21:14
感谢楼主分享 会去试试看
第一次在吾爱发技术贴,图和文字的格式还不是很会弄。最后的链题和题目不知道为什么没显示。如果你要试,可以参考我在CSDN上的发帖子,是一样的,还有一些学习资料和题目
https://blog.csdn.net/weixin_43884935/article/details/104870414
页:
[1]