这个题目出的还行,不错。。。。比赛中做出了三题,刷了1000分,却被两个150 200分的签到题难住了。。。太菜了
#include
#include
int main()
{int u;
unsigned char op[]="WASD";
unsigned char q;
int i =144;
int l=0;
int o=0;
int r;
unsigned char C[] =
{
0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00,
0x41, 0x42, 0x42, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00,
0x41, 0x42, 0x42, 0x41, 0x42, 0x41, 0x0, 0x0, 0x42, 0x42, 0x41, 0x41, 0x00,
0x41, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x42, 0x41, 0x00,
0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x42, 0x41, 0x00,
0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x42, 0x42, 0x42, 0x41, 0x0, 0x0, 0x00,
0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x0, 0x42, 0x42, 0x00,
0x42, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x41, 0x0, 0x00,
0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00,
0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00,
0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x42, 0x41, 0x42, 0x42, 0x41, 0x42, 0x00,
0x42, 0x42, 0x42, 0x0, 0x0, 0x41, 0x41, 0x41, 0x42, 0x42, 0x41, 0x45, 0x00
};
unsigned char s[200];
for( r=0;r<150;++r)
s[r]=0;
s[0]=1;
while(i--)
{
int tmp1 = l;
int tmp2 = o;
if((tmp1<11)&& (s[13*(tmp1+1)+tmp2]==0))
{
if(C[13*(tmp1+1)+tmp2]==0x41||C[13*(tmp1+1)+tmp2]==0x45)
{
printf("%c",op[2]);
char v0 = op[1];
op[1] = op[3];
op[3] = v0;
char v1 = op[0];
op[0] = op[2];
op[2] = v1;
l++;
s[13*l+o]=1;
continue;
}
}
if((tmp1>0)&&(s[13*(tmp1-1)+tmp2]==0))
if(C[13*(tmp1-1)+tmp2]==0x41||C[13*(tmp1-1)+tmp2]==0x45)
{ printf("%c",op[0]);
char v1 = op[0];
op[0] = op[2];
op[2] = v1;
l--;
s[13*l+o]=1;
continue;
}
if((tmp2>0)&&(s[13*(tmp1)+tmp2-1]==0))
if(C[13*tmp1+tmp2-1]==0x41||C[13*tmp1+tmp2-1]==0x45)
{
printf("%c",op[1]);
char v0 = op[0];
op[0] = op[1];
op[1] = op[2];
op[2] = op[3];
op[3] = v0;
o--;
s[13*l+o]=1;
continue;
}
if((tmp2<11)&&(s[13*(tmp1)+tmp2+1]==0))
if(C[13*tmp1+tmp2+1]==0x41||C[13*tmp1+tmp2+1]==0x45)
{
printf("%c",op[3]);
char v1 = op[3];
op[3] = op[2];
op[2] = op[1];
op[1] = op[0];
op[0] =v1;
o++;
s[13*l+o]=1;
continue;
}
}
}
之后换成MD5j就可以了
于是 察觉 或许是将我的数加密然后比较 于是对我的输入下一个硬件断点 发现了对比的数 和 加密的方法。。。(放的怎么近真的好吗。。。。)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200615210236535.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NDM5MjI5,size_16,color_FFFFFF,t_70`
>>> a = [0x50 , 0x7b , 0x66, 0x71,0x5e, 0x4f,0x60,0x72,0x67,0x50,0x7b,0x66,0x71,0x5e,0x4b,0x42,0x59,0x4b,0x75,0x5f,0x4b,0x5f,0x7b,0x4b,0x71,0x6d,0x5f,0x65,0x2d,0x69]
>>> s = ""
>>> for i in range(len(a)):
... d= (a[i]-0xfc)&0xff
... d = d^0x10
... s+=chr(d)
...
>>> print s
DozerCtf{Dozer_VM_is_so_easy!}
代码太长了。。。就放两张) 之后出题人给了提示题目使用位运算表达加减乘除
百度一下后知道
int add(int a,int b) {
int carry,add;
do{
add = a^b;
carry = (a&b)<<1;
a = add;
b=carry;
}while(carry!=0);
return add; } 表示+
int subtract(int a,int b){
return add(a,add(~b,1));}
表示减
使用z3解方程
>>> from z3 import *
>>> v0 = Int('v0')
>>> v1 = Int('v1')
>>> a3 = Int('a3')
>>> s = Solver()
>>> s.add(a3*2+a3+4*v0-0x13cc==v1)
>>> s.add(8*v0+v0+a3+8*v1-2*v1==0x3518)
>>> s.add(0x1759==2*(v0+a3)+(v0+a3)+v1)
>>> if s.check()==sat:
... print(s.model())
...
[v0 = 833, v1 = 871, a3 = 869]
知道07加起来为833,60xf为871,0x10~0x18为869
之后就慢慢解方程了。。。。。。。
不过cutter反编译出来的运算过程是对的,但但参与的数不对,得对应参照看看mips指令找到对应的数才行
方程得一个个解,但都比较简单,大多数都是使用xor的恒等式和位运算的加减乘除,我就说说解的过程中比较特殊的几个函数
fcn.0041a4e4我猜是strcmp事实证明我猜的差不多 比较的字符串有ctf is
比较的位置没看出了于是靠蒙,结果蒙对了。。。。
fcn.0041a4e4
经过测试是比较两个字符是否相等
接下来的都是一个个解,
最后得到flag Dozerctf{num_is_so_good}