一道CTF逆向题的逆向与学习
2020-05-23 11:36:53 Author: bbs.pediy.com(查看原文) 阅读量:406 收藏

一道CTF逆向题,首先查壳为无壳,运行程序如下图,

直接用OD动态分析,

首先在地址0X401047处接收输入的flag,地址0X401050处计算输入flag的长度,保存在寄存器EAX。地址0X401058处判断flag的长度,只有小于0X1E才正确,这里大胆猜测flag的长度应该为0X1D位。

在地址OX4010F5处循环4次比较输入的flag前四位是否为"EIS{",循环4次后在0X4010DA处跳转到OX401120处,所以得知flag前四位为"EIS{"。


在地址0X401124处比较flag的第0X1D位是否ASCII码是否为0X7D,即‘}’,所以可以得知flag的长度为0X1D,即十进制的29位。可以看出在地址0X40115E处若跳转则显示正确(congratulations!)。所以地址0X40114F处为关键算法函数,

以下反汇编是将输入的字符串字符进行大小写转换大写转小写,小写转大写。

地址0X4013C0处函数对字符串进一步处理,将字符与55进行异或,然后再加48,地址0X401397处将被处理的字符串与"GONDPHyGjPEKruv{{pj]X@rF"进行比较。相同则正确。

知道了算法,然后用C语言编写了代码来计算flag:

#include<stdio.h>
int main()
{
	int a,b,c;
	int x[38]={0x47,0x4f ,0x4E ,0x44 ,0x50 ,0x48 ,0x79 ,0x47 ,0x6A ,0x50 ,0x45 ,0x4B ,0x72 ,0x75 ,0x76 ,0x7B,0x7B ,0x70 ,0x6A ,0x5D ,0x58 ,0x40 ,0x72 ,0x46};
	int y[38]={0xd,0x13 ,0x17 ,0x11 ,0x02 ,0x01 ,0x20 ,0x1D ,0x0C ,0x02 ,0x19 ,0x2F ,0x17 ,0x2B ,0x24 ,0x1F ,0x1E ,0x16 ,0x09  ,0x0F ,0x15 ,0x27 ,0x13 ,0x26};
printf("EIS{");
for(int i=0;i<=23;i++)
{
	c=x[i]^y[i];
	b=c-0x48;
	b=b^0x55;
	if((b>=0x61)&&(b<=0x7a))
	printf("%c\n",b-0x20);
	else if((b>=0x41)&&(b<=0x5a))
		printf("%c",b+0x20);
	else
		printf("%c",b);
}
printf("}");
return 0;
}

在IDA中找到函数然后F5分析伪代码看看:

其实我这里对于IDA中的伪代码看起来很费劲,感觉没有OD动态分析来得清楚,都说IDA强大,不知道各位有没有什么技巧看这个伪代码呢?

[培训]科锐逆向工程师培训班38期--远程教学预课班将于 2020年5月28日 正式开班!


文章来源: https://bbs.pediy.com/thread-259638.htm
如有侵权请联系:admin#unsafe.sh