当前位置:网站首页>[buuctf.reverse] 114_ [MRCTF2020]VirtualTree
[buuctf.reverse] 114_ [MRCTF2020]VirtualTree
2022-06-09 11:34:00 【Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi Shi】
This kind of question dares to directly give the original code is also really confident . But it's really difficult if you don't give the source code .
use ida Decompilation found a problem , There is some interference inside E8, This will be changed after transfer ida Yes call . The original code has been explained clearly .
_asm
{
xor eax,eax
jz label2
_emit 0xE8
label2:
}
Mr. program becomes a binary tree , And assign the node as A-P
int init()
{
tree *n[16];
for(int i=0;i<16;i++)
n[i]=(tree*)malloc(sizeof(tree));
for(int i=0;i<16;i++)
n[i]->data='A'+i;
n[0]->left=n[1];
n[0]->right=n[2];
n[1]->left=n[3];
n[1]->right=n[4];
n[2]->left=n[5];
n[2]->right=n[6];
n[3]->left=n[7];
n[3]->right=n[8];
n[4]->left=n[9];
n[4]->right=NULL;
n[5]->left=n[10];
n[5]->right=NULL;
n[6]->left=n[11];
n[6]->right=n[12];
n[7]->right=n[7]->left=NULL;
n[8]->left=NULL;
n[8]->right=n[13];
n[9]->left=n[9]->right=NULL;
n[10]->left=n[14];
n[10]->right=n[15];
n[11]->left=n[11]->right=n[12]->left=n[12]->right=NULL;
n[13]->left=n[13]->right=NULL;
n[14]->left=n[14]->right=n[15]->left=n[15]->right=NULL;
Tree=n[0];
return 1;
}
int inited=init();
And then I did something replace, Make a little change to the program , The first 1 Segment will point to 401510 fake The value of the function is changed to point to other functions , Other functions are placed in turn list in
void *list[15]={add,xors,add,sub,xors,sub,add,xors,sub,sub,xors,sub,xors,add};
int replace()
{
void *addr=doit;
int val=(int)addr;
DWORD old;
if(VirtualProtect(addr,512,PAGE_EXECUTE_READWRITE,&old)==NULL)
exit(0);
int count=0;
while(*((PBYTE)val)!=0x90)
{
if(*((PDWORD)val)==0x00401510)
*((PDWORD)val)=(DWORD)list[count++];
val=val+1;
}
addr=main;
val=(int)addr;
if(VirtualProtect(addr,512,PAGE_EXECUTE_READWRITE,&old)==NULL)
exit(0);
while(*((PBYTE)val)!=0x90)
{
if(*((PDWORD)val)==(DWORD)walkB)
{
*((PDWORD)val)=(DWORD)walkA;
break;
}
val=val+1;
}
}
int s=replace();
The second time will be main Inside walkB Change it to walkA
int main()
{
fake(0,0);
printf("Give Me Your Key:\n");
scanf_s("%s",&buff,30);
if(strlen((char*)buff)!=16)
{
printf("Wrong!\n");
exit(0);
}
char flag[20]="";
memcpy(flag,buff,16);
_asm push Tree;
_asm mov eax,walkB;
_asm call eax; // walkB(Tree) right,root,left
doit();
_asm nop;
for(int i=0;i<16;i++)
if(cmps[i]!=buff[i])
{
printf("Wrong!\n");
exit(0);
}
printf("Right!\n");
printf("your flag: MRCTF{%s}\n",flag);
system("pause");
return 0;
}
In this way, the general process is clear .
The program first uses... For the input walkA The first step is to put the right root in the order of the left root buff The root character of the input content in the first XOR .
And then execute doit Encrypt the input , The solution is list In the list
Then with cmps Compare .
The revised and procedures are as follows :
// re_revenge.cpp : This file contains "main" function . Program execution will start and end here .
//
#include <cstdio>
#include <cstdlib>
#include <windows.h>
//@_7r3e_f0r_fuNN!
struct tree
{
unsigned char data;
tree *right;
tree *left;
}*Tree;
unsigned char cmps[]={0x17,0x63,0x77,0x3,0x52,0x2E,0x4A,0x28,0x52,0x1B,0x17,0x12,0x3A,0xA,0x6C,0x62};
unsigned char buff[1000],size=0;
int main();
void walkA(tree *T);
void walkB(tree *T);
void add(int a,int b);
void xors(int a,int b);
void sub(int a,int b);
void* func[5]={NULL};
int init()
{
tree *n[16];
for(int i=0;i<16;i++)
n[i]=(tree*)malloc(sizeof(tree));
for(int i=0;i<16;i++)
n[i]->data='A'+i;
n[0]->left=n[1];
n[0]->right=n[2];
n[1]->left=n[3];
n[1]->right=n[4];
n[2]->left=n[5];
n[2]->right=n[6];
n[3]->left=n[7];
n[3]->right=n[8];
n[4]->left=n[9];
n[4]->right=NULL;
n[5]->left=n[10];
n[5]->right=NULL;
n[6]->left=n[11];
n[6]->right=n[12];
n[7]->right=n[7]->left=NULL;
n[8]->left=NULL;
n[8]->right=n[13];
n[9]->left=n[9]->right=NULL;
n[10]->left=n[14];
n[10]->right=n[15];
n[11]->left=n[11]->right=n[12]->left=n[12]->right=NULL;
n[13]->left=n[13]->right=NULL;
n[14]->left=n[14]->right=n[15]->left=n[15]->right=NULL;
Tree=n[0];
return 1;
}
int inited=init();
void *list[15]={add,xors,add,sub,xors,sub,add,xors,sub,sub,xors,sub,xors,add};
int idx=0;
void xors(int a,int b)
{
buff[a]=buff[a]^buff[b];
}
void sub(int a,int b)
{
buff[a]=abs(buff[a]-buff[b]);
}
void add(int a,int b)
{
buff[a]+=b;
}
void fake(int a,int b)
{
if(a==0 || b==0)
return;
for(int i=0;i<=b;i++)
{
buff[i]^=a;
buff[i]=(buff[i]>>b | buff[i]<<(8-b));
buff[i]=(1<<(i%8))^buff[i];
for(int j=1;j<15;j++)
{
buff[i]^=buff[j]&0xDF;
}
}
}
void walkA(tree *T)
{
if(T->data!=NULL)
{
if(T->right!=NULL)
walkA(T->right);
if(T->left!=NULL)
walkA(T->left);
buff[idx++]^=T->data;
}
}
void walkB(tree *T)
{
if(T->data!=NULL)
{
if(T->right!=NULL)
walkB(T->right);
buff[idx++]^=T->data;
if(T->left!=NULL)
walkB(T->left);
}
}
void doit();
void doit()
{
add(0,10); // stay replace Lieutenant general fake Change it to list The corresponding function in
xors(1,2);
add(2,7);
sub(3,7);
xors(4,5);
sub(6,1);
add(7,3);
xors(8,7);
sub(9,8);
sub(10,7);
xors(11,12);
sub(12,2);
xors(14,15);
add(15,2);
}
int replace() // This function is no longer used
{
void *addr=doit;
int val=(int)addr;
DWORD old;
if(VirtualProtect(addr,512,PAGE_EXECUTE_READWRITE,&old)==NULL)
exit(0);
int count=0;
while(*((PBYTE)val)!=0x90)
{
if(*((PDWORD)val)==0x00401510)
*((PDWORD)val)=(DWORD)list[count++]; // Press list take fake Change to the corresponding function
val=val+1;
}
addr=main;
val=(int)addr;
if(VirtualProtect(addr,512,PAGE_EXECUTE_READWRITE,&old)==NULL)
exit(0);
while(*((PBYTE)val)!=0x90)
{
if(*((PDWORD)val)==(DWORD)walkB)
{
*((PDWORD)val)=(DWORD)walkA; // take main Medium walkB Change it to walkA
break;
}
val=val+1;
}
}
//int s=replace();
int main()
{
fake(0,0);// It's useless
printf("Give Me Your Key:\n");
scanf_s("%s",&buff,30);
if(strlen((char*)buff)!=16)
{
printf("Wrong!\n");
exit(0);
}
char flag[20]="";
memcpy(flag,buff,16);
walkA(Tree); //replace Lieutenant general walkB Change it to walkA
// walkA(Tree) right,left,root buff: MLGPOKFCJENIHDBA The input values buff Exclusive or
doit();
for(int i=0;i<16;i++)
if(cmps[i]!=buff[i])
{
printf("Wrong!\n");
exit(0);
}
printf("Right!\n");
printf("your flag: MRCTF{%s}\n",flag);
system("pause");
return 0;
}Write reverse code from back to front in this way ( Draw the tree by hand , only 16 It is faster to manually write characters ):
cmps = [0x17,0x63,0x77,0x3,0x52,0x2E,0x4A,0x28,0x52,0x1B,0x17,0x12,0x3A,0xA,0x6C,0x62]
treexor = b'MLGPOKFCJENIHDBA'
cmps[15]-=2
cmps[14]^= cmps[15]
cmps[12] = cmps[2]- cmps[12]
cmps[11]^= cmps[12]
cmps[10] = cmps[7]- cmps[10]
cmps[9] = cmps[8] - cmps[9]
cmps[8]^= cmps[7]
cmps[7]-=3
cmps[6] = cmps[1]- cmps[6]
cmps[4]^= cmps[5]
cmps[3] = cmps[7]- cmps[3]
cmps[2]-=7
cmps[1]^=cmps[2]
cmps[0]-=10
flag = bytes([cmps[i]^treexor[i] for i in range(16)])
print(flag)
#pctf{s4d_chugg4_n01zez}
#flag{s4d_chugg4_n01zez}边栏推荐
猜你喜欢

Simple example of C # picture verification code

Document writing specification

企评家用杜邦分析法剖析:华东建筑集团股份有限公司企业财务状况

【Homeassistant驱动舵机servo】

图文并茂讲线程池

Jingzhida rushes to the scientific innovation board: the annual revenue is 458million, and the SME fund is the shareholder

哐哐英雄Clunky Hero v0.96中文版

Course design of network sniffer design based on C language

第二章应用层

Multi engine database management tool DataGrid 2022.1.5 Chinese version
随机推荐
This article takes you to understand gaussdb (DWS) [Gauss is not a mathematician this time]
电脑的选择1
Leetcode 2048. Next larger numerical balance number (interesting, solved)
[buuctf.reverse] 111 [b01lers2020] chugga Chugga
Introduction to automatic partition management of gaussdb (DWS)
Comparison and evaluation of code on cloud - devcloud
第三章运输层
一文详解光场深度估计
MySQL learning notes - Part 3 - indexes, stored procedures and functions, views, triggers
Cookies在XSS和CSRF防御中的作用
More than observation | Alibaba cloud observable Technology Summit officially launched
AudioTrack播放wav文件的一次问题记录
[buuctf.reverse] 109_[FlareOn6]FlareBear,110_[INSHack2018]Tricky-Part1
Post processing of wechat applet login failure
Be sincere and open with gold and stone
关于CSRF及其防御
[advanced MySQL] optimize SQL by using the execution plan explain (2)
图文并茂讲线程池
About CSRF and its defense
Use the five number generalization method to determine the outliers in the data set