BUUCTF逆向题Transform

一、工具:

        1、IDA(64位)

二、解题思路:

①、载入IDA

②、通过字符串窗口找到关键字符串

BUUCTF逆向题Transform_第1张图片

双击,定位到关键位置,生成伪代码

BUUCTF逆向题Transform_第2张图片

括起来的是解题最关键的地方,接下来我们解读代码,由语句 if ( strlen(*(const char **)&argc) != 33 ) 可以知道,flag 的长度位 33 个字节,v6 保存的是正确的 flag ,而 for 循环通过对 v6 进行换位加异或的处理,最终得到的字符串与 aGyURsywBFbLwya 保存的字符串相同。

③、思路明确,接下来一步一步深入分析,首先双击 aGyURsywBFbLwya 查看它保存的字符串是什么

BUUCTF逆向题Transform_第3张图片

这个就是 aGyURsywBFbLwya 保存的字符串,往上分析,查看 dword_40F040 保存的内容得到:

BUUCTF逆向题Transform_第4张图片

这里的 8 dup(0)在写脚本时要注意,不是 8 ,是 0 ,我开始以为是 8 后面发现得出来的 flag 不对,我以为代码逻辑错了看半天,最后才发现是这里出了问题

BUUCTF逆向题Transform_第5张图片

根据这个 for 循环我们得知,v6保存的字符串以 dword_40F040[i] 所对应的值为下标依此取出 v6 的字符串保存到 byte_414040 中,从而实现换位,再让其每个字符与 dword_40F040 的值依此异或。

逆向思路:

1、与同一个值两次异或等于没异或,所以要得到异或前 byte_414040 保存的字符串,只需要再与 dword_40F040 的值异或一次即可

2、把 byte_414040 中的字符依此取出,保存回 v6 里该字符原来所在的位置,即可得到 flag

#include 
#include 

int main()
{
	char v;
	
	char ch[] = {
		'g','y','{',0x7F,'u','+','<','R','S','y','W','^',']','B','{','-','*','f','B','~','L','W','y','A','k','~','e','<','\\','E','o','b','M',
	};//flag加密过后的字符串 
	
	char ch1[] = "nsthr30TRiTO}_p31pFs_ClCr{z4N_slE";//异或前的字符串,两次异或得到
	
	char st[] = {
		0x9, 0x0A, 0x0F, 0x17, 0x7, 0x18 ,0x0C, 0x6, 0x1, 0x10, 0x3, 0x11, 0x20,0x1D, 0x0B, 0x1E, 0x1B, 0x16, 0x4, 0x0D, 0x13, 0x14, 0x15, 0x2, 0x19,0x5, 0x1F, 0x8, 0x12, 0x1A, 0x1C, 0x0E, 0
	};//dword_40F040
	
	char v6[33] = {};
	
	//printf("%d",strlen(st));
	
	for(int i = 0;i <= 32;i++)
	{
		ch[i] = ch[i] ^ st[i];
	}
	
	/*for(int i = 0;i < 33;i++)
	{
		printf("%c",ch[i]);
	}*/
	
	printf("\n");
	
	for(int i = 0;i < strlen(ch);i++)
	{
		v6[st[i]] = ch1[i];
	}
	
	for(int i = 0;i < strlen(ch1);i++)
	{
		printf("%c",v6[i]);
	}

结果(flag):

RCTF{Tr4nsp0sltiON_Clph3r_1s_3z}

代码写的有点乱,主要目的是这样我复盘的时候可以快速回想起做题时的思路。

三、收获:

dup是duplicate的缩写,重复的意思;
用来定义重复的字节、字、双字、结构等内存缓冲区;

db x dup()    x是重复的次数,()里是要重复的数

所以前面的8 dup(0)意思是定义8个字节的 0 ,即0 0 0 0 0 0 0 0 ,所以对象是 0 而不是 8 ,如果没搞清楚,就会导致得不到正确的 flag 

你可能感兴趣的:(CTF,reverse,算法,安全)