查壳
显示无壳,然后拖进IDA
IDA分析
实际上程序运行会首先弹出个string:
,我们搜索字符串,然后ctrl+x
找到read
函数位置,
从unk_403040地址开始作为int数组赋值给v4,由于intel是小端存储,所以每四个字节,从后往前查看字节,也可以在IDA,选中后按D
键,不勾选dup。
查看一下主要的函数vm_operad()
1 | int __cdecl vm_operad(int *a1, int a2) |
首先第一次是执行case 10, 这个指令就是read
函数操作:读取输入并且检测字符长度是否为15,这个输入就是正确的flag。然后再进行一系列操作,然后在case 7的时候将v4中的值一个一个地与unk_403040的下一个比特一个个比较(**我们可以打印出v10的值去对比一下a1数组中的值:)**)
把代码修改一下
调代码的时候可以看到v4的值其实都是v5的值,v5是由flag和unk_403040算出来的,所以反着算就知道flag啦
1 | int decode(int * opcode, int len_114) |
flag{757515121f3d478}
小tips:
sub/subs汇编指令是进行减法运算指令。一般在函数内部第一句就是sub指令,是用来开辟内存空间。之前就说过栈空间是从高地址向低地址扩展的,而且是一块连续的空间,sp之前介绍寄存器的时候就说过是栈顶,所以第一条指令就是sp向低地址移动一段距离,也就是开辟一块栈空间。比如
sub esp,10h
就是在栈上分配0x10个字节的空间。
我们再说一下IDA7.5和7.0的区别,在分析的时候遇到这样的情况,第一张图是7.5,第二张是7.0,汇编代码都是一样的,都是先取一个数组地址然后将ebp + var_18
的值加上(相当于取数组下标),7.5是解析成为一个数组,前100字节和后100字节分别用来存储不同数据,所以意思都一样,注意理解就好。