SangFor(深育杯)-Reverse(逆向) Press Write up

当你拥有一台液压机的时候,你将很快拥有液压机。

0x00 日常查壳

0x01 分析主函数

0x02 init_0

0x03 Brian函数的符号执行

于是那么一段

++++++++++[->++++++++++++++++->[-]+++++

其实等式很简单

首先是tmp里虽然那么长一个数组其实就用了3个字节

我把他们分别命名为t1 t2 t3 各位师傅看的时候可以画一下帮助理解

这个等式就是

当是第一个液压机的时候 ( i = 0 )

ef[i] = (160 - f[i]) * 5 + 2

之后的液压机 ( i > 0 )

ef[i] = ( (160 + ef[i - 1]) - f[i] ) * 5 + 2

PS:注意t1 t2 t3都只用了一个字节 可以动调看一下

0x04 GetFlag

本来想了半天&0xFF用C解bangzhu了半天 和队内pwn师傅了了一下突然想起z3可以很轻松解出来

from z3 import *
enflag = [0x60, 0xE1, 0x2F, 0x05, 0x79, 0x80, 0x5E, 0xE1, 0xC5, 0x57, 0x8B, 0xCC, 0x5C, 0x9A, 0x67, 0x26,
        0x1E, 0x19, 0xAF, 0x93, 0x3F, 0x09, 0xE2, 0x97, 0x99, 0x7B, 0x86, 0xC1, 0x25, 0x87, 0xD6, 0x0C,
        0xDD, 0xCF, 0x2A, 0xF5, 0x65, 0x0E, 0x73, 0x59, 0x1D, 0x5F, 0xA4, 0xF4, 0x65, 0x68, 0xD1, 0x3D,
        0xD2, 0x98, 0x5D, 0xFE, 0x5B, 0xEF, 0x5B, 0xCC]
input = [BitVec('input[%d]' % i, 8) for i in range(56)]
#yyj = BitVec('yyj', 8)
s = Solver()

s.add( ((160 - input[0]) * 5 + 2) == enflag[0] )	#第一台液压机
for i in range(1, 56):				#之后的液压机
    s.add( (((160 + enflag[i - 1]) - input[i]) * 5 + 2) == enflag[i] )
    
if sat == s.check():
    ans = s.model()
    
flag = ""
for i in range(56):
    flag += chr(ans[input[i]].as_long())   #as_long()转成整数
print(flag)

拿base64解一下

GetFlag!

昨日被师傅问了这道题,出了现新的想法,新的解法!

遍历解:

#include <stdio.h>

int main(void)
{
	int enflag[] = 
	{
		0x60, 0xE1, 0x2F, 0x05, 0x79, 0x80, 0x5E, 0xE1, 0xC5, 0x57,
		0x8B, 0xCC, 0x5C, 0x9A, 0x67, 0x26, 0x1E, 0x19, 0xAF, 0x93, 
		0x3F, 0x09, 0xE2, 0x97, 0x99, 0x7B, 0x86, 0xC1, 0x25, 0x87, 
		0xD6, 0x0C, 0xDD, 0xCF, 0x2A, 0xF5, 0x65, 0x0E, 0x73, 0x59, 
		0x1D, 0x5F, 0xA4, 0xF4, 0x65, 0x68, 0xD1, 0x3D, 0xD2, 0x98, 
		0x5D, 0xFE, 0x5B, 0xEF, 0x5B, 0xCC
	};
	int i, j;
	char flag[56] = { 0 };
	unsigned char t;		//本来直接在 & 0xFF这上纠结 但其实只需要给中间数8位即可 
	
	for ( i = 0; i < 56; i++ )
	{
		for ( j = 32; j < 127; j++)
		{	
			if ( i == 0 )	
			{
				t = (160 - j) * 5 + 2;
				if ( t == enflag[i] )	
				{
					flag[i] = j;
					break;
				}
			}	
			else
			{
				t = (160 + enflag[i - 1] - j) * 5 + 2;
				if ( t == enflag[i] )
				{
					flag[i] = j;
					break;
				}	
			}				
		}
		printf("%c", flag[i]);
	}
	
	return 0;
}

寻找正确数解:

#include <stdio.h>

int main(void)
{
	int enflag[] = 
	{
		0x60, 0xE1, 0x2F, 0x05, 0x79, 0x80, 0x5E, 0xE1, 0xC5, 0x57,
		0x8B, 0xCC, 0x5C, 0x9A, 0x67, 0x26, 0x1E, 0x19, 0xAF, 0x93, 
		0x3F, 0x09, 0xE2, 0x97, 0x99, 0x7B, 0x86, 0xC1, 0x25, 0x87, 
		0xD6, 0x0C, 0xDD, 0xCF, 0x2A, 0xF5, 0x65, 0x0E, 0x73, 0x59, 
		0x1D, 0x5F, 0xA4, 0xF4, 0x65, 0x68, 0xD1, 0x3D, 0xD2, 0x98, 
		0x5D, 0xFE, 0x5B, 0xEF, 0x5B, 0xCC
	};
	int i;
	char flag[56] = { 0 };
	unsigned int t;
	
	for ( i = 0; i < 56; i++ )
	{
		t = enflag[i] - 2;			
//		printf("%d ", t);
		while (t != ((t / 5) * 5))	
			t += 256;		
		t = t / 5;	/*思路  1. 因为直接除是有余数会导致回不到原来的数据 
							2. 根据一个字节的限制
							3. 所以每次+ 0xFF直到能整除为止 	
	什么是256 因为每次越界都是一个字节的限制 255也就是0xFF依然在一个字节之中 要做的是递增一个字节			*/	
//		printf("%d ", t);
		
		if (i == 0)
			flag[i] = 160 - t;
		else
			flag[i] = (160 + enflag[i - 1] - t) & 0x7F;
		
		printf("%c", flag[i]);
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值