这道题反编译之后,除了某些jmp和call以外,都是mov......
这个很明显就是movfuscator 来加密的
这里就用一个神器,qira 来解这道题
这个工具记录整个运行的的过程每一个内存和寄存器的变化,我们可以随便看程序运行到某条指令时,某个内存或寄存器的内容
然后做0ctf的momo那道的时候找到了一个工具demovfuscator
这个工具可以将简化movfuscator后的程序,这样就能在ida里面反编译
虽然简化了之后一样还是看不太懂,但是还是能看出一些东西的
这里调用了memset
这里调用了strcpy
这里调用了strlen
可以看到调用了几个函数,但是除了调用以外的基本都看不太懂
因为库函数的位置是已知的,所以我们了解程序干了什么最简单的办法就是在各个函数的plt表处下断点
其他的就不放了,可以简单变为下面的c语言代码
memset(0x85fa960,0,0x400);
strcpy(0x85fa960,0x08052044);
int len=strlen(0x85fa960);
srand(0x00c0ffee);
for(int i=0;i<len;i++)
{
int num=rand();
}
printf("guess the flag: %s",0x85fa960)
因为程序没有输入,所以很难判断主要逻辑是什么
而且我们也不知道rand出来的数字干了什么
用qira跟踪了下
第一个rand出来的是0x16718b06
然后mov 转移到0x8052060
再从0x8052060转移到0x805206c
然后0x805206c->0x81fb090
0x81fb090->0x81fb004
然后这里就是对rand出来的东西进行操作
等价于
r=0x16718b06
r=r&0xffff
r=~r // r=0xffff-r
这里是
r=r+1
但是这样跟下去没完没了的
然后发现玄学只跟着0x8049B60这块内存的时候
会从四个字节的变为单个字节
把前四个字节记录下来,和bss段那些异或了下,发现是flag,然后就把24个字符全部dump出来,解密出来就是flag了
解密的脚本如下
b=[0x87,0x50,0x8d,0x5e,0x8d,0x53,0x48,0x4b,0x4d,0x7e,0x83,0x87,0x83,0x49,0x72,0x89,0x45,0x6e,0x8b,0x75,0x4e,0x56,0x49,0x50]
a=[0xE1, 0x3C, 0xEC, 0x39, 0xF6, 0x63, 0x30, 0x2F, 0x28, 0x1F,
0xE7, 0xE5, 0xE6, 0x2C, 0x14, 0xED, 0x20, 0x0F, 0xEF, 0x16,
0x7E, 0x32, 0x2C, 0x2D]
c=''
for i in range(24):
c+=chr(a[i]^b[i])
print(c)
得到flag是
flag{0xdeadbeefdeadc0de}
玄学re