# BUUCTF-Reverse —— 第二页的题目集合

## [MRCTF2020]hello_world_go

gdb hello_world_go //调试程序
b *0x49a400 //在0x49a400处下断点
r //运行程序
find "flag{" //内存搜索字符串


## [FlareOn4]IgniteMe

byte_403000 = '0D 26 49 45 2A 17 78 44 2B 6C 5D 5E 45 12 2F 17 2B 44 6F 6E 56 09 5F 45 47 73 26 0A 0D 13 17 48 42 01 40 4D 0C 02 69'.split(' ')
byte_403000 = [int(i, 16) for i in byte_403000]
v4 = 4
byte_403000[-1] ^= v4
print(byte_403000)
print(len(byte_403000))
for i in range(len(byte_403000)-1, 0, -1):#老是忘记加-1
byte_403000[i-1] ^= byte_403000[i]

print(''.join(chr(i) for i in byte_403000))


## [GWCTF 2019]xxor

### 解密

#include <stdio.h>

int main(){

unsigned int v7[6] = {3746099070, 550153460, 3774025685, 1548802262, 2652626477, 2230518816};

unsigned int a2[] = {2,2,3,4};
unsigned int v6[6] = {0};

for(int i=0;i<6;i+=2){

unsigned int v3 = v7[i];
unsigned int v4 = v7[i+1];
int v5 = 0x458BCD42*64;

for (int j = 0; j < 64; ++j ){
v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + a2[0]) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
v5 -= 0x458BCD42;
}

v6[i] = v3;
v6[i+1] = v4;

}

//数据小端存储,每一个int：4字节，转成4个字符，顺序是反过来的
//然而实际上以十六进制打印出来只有3字节有效，最高字节为0
//	for(int i=0;i<6;i++) {
//		printf("%x ",v6[i]);
//	}

for(int i=0;i<6;i++) {
printf("%c%c%c",*((char*)&v6[i]+2),*((char*)&v6[i]+1),*((char*)&v6[i]+0));
}

return 0;

}


## [FlareOn6]Overlong

unk_402008变量存储的是一个很长的字符串。

#include <stdio.h>

int sub_401000(char* a1,char* a2){

int v3;
char v4;

if ( (int)(unsigned __int8)*a2 >> 3 == 30 ){
v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6);
v3 = 4;
}
else if ( (int)(unsigned __int8)*a2 >> 4 == 14 ){
v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6);
v3 = 3;
}
else if ( (int)(unsigned __int8)*a2 >> 5 == 6 ){
v4 = a2[1] & 0x3F | ((*a2 & 0x1F) << 6);
v3 = 2;
}
else{
v4 = *a2;
v3 = 1;
}

printf("%c",v4);

*a1 = v4;
return v3;

}

int main(){

char text[250]={0};
unsigned char unk_402008[] ={
0xE0, 0x81, 0x89, 0xC0, 0xA0, 0xC1, 0xAE, 0xE0, 0x81, 0xA5,
0xC1, 0xB6, 0xF0, 0x80, 0x81, 0xA5, 0xE0, 0x81, 0xB2, 0xF0,
0x80, 0x80, 0xA0, 0xE0, 0x81, 0xA2, 0x72, 0x6F, 0xC1, 0xAB,
0x65, 0xE0, 0x80, 0xA0, 0xE0, 0x81, 0xB4, 0xE0, 0x81, 0xA8,
0xC1, 0xA5, 0x20, 0xC1, 0xA5, 0xE0, 0x81, 0xAE, 0x63, 0xC1,
0xAF, 0xE0, 0x81, 0xA4, 0xF0, 0x80, 0x81, 0xA9, 0x6E, 0xC1,
0xA7, 0xC0, 0xBA, 0x20, 0x49, 0xF0, 0x80, 0x81, 0x9F, 0xC1,
0xA1, 0xC1, 0x9F, 0xC1, 0x8D, 0xE0, 0x81, 0x9F, 0xC1, 0xB4,
0xF0, 0x80, 0x81, 0x9F, 0xF0, 0x80, 0x81, 0xA8, 0xC1, 0x9F,
0xF0, 0x80, 0x81, 0xA5, 0xE0, 0x81, 0x9F, 0xC1, 0xA5, 0xE0,
0x81, 0x9F, 0xF0, 0x80, 0x81, 0xAE, 0xC1, 0x9F, 0xF0, 0x80,
0x81, 0x83, 0xC1, 0x9F, 0xE0, 0x81, 0xAF, 0xE0, 0x81, 0x9F,
0xC1, 0x84, 0x5F, 0xE0, 0x81, 0xA9, 0xF0, 0x80, 0x81, 0x9F,
0x6E, 0xE0, 0x81, 0x9F, 0xE0, 0x81, 0xA7, 0xE0, 0x81, 0x80,
0xF0, 0x80, 0x81, 0xA6, 0xF0, 0x80, 0x81, 0xAC, 0xE0, 0x81,
0xA1, 0xC1, 0xB2, 0xC1, 0xA5, 0xF0, 0x80, 0x80, 0xAD, 0xF0,
0x80, 0x81, 0xAF, 0x6E, 0xC0, 0xAE, 0xF0, 0x80, 0x81, 0xA3,
};

char* a1 = text;
int a2 = (int)unk_402008;
int a3 = 28;
for(int i=0;i<sizeof(unk_402008);i++){
a2 += sub_401000(a1, (char*)a2);
a1 += 1;
}

return 0;

}


## [FlareOn3]Challenge1

main函数中，代码流程是接收我们输入的字符串，进行加密，然后与已知字符串比较。

## [ACTF新生赛2020]Oruga

’w’(-16, 向上)、‘E’(+1, 向右)、‘M’(+16, 向下)、‘J’(-1, 向左)控制方向，‘!’(0x21)始终点。下面那个循环就是沿某个方向一直走到底。

256个字符，根据+16，-16，估计是16×16的迷宫。打印出迷宫地图，绘制路径就得到flag。

MEWEMEWJMEWJM


## 特殊的 BASE64

std::string::string
std::operator<<<std::char_traits<char>>


## [BJDCTF2020]BJD hamburger competition

C#编写的主逻辑模块代码静态编辑之后存储于Assembly-CSharp.dll文件中。

flag{B8C37E33DEFDE51CF91E}


sub_860函数，一堆等式，用z3-solver求解就行了。

from z3 import *

v1, v2, v3, v4, v5, v6, v7, v8, v9, v11 = Ints('v1 v2 v3 v4 v5 v6 v7 v8 v9 v11')
solver = Solver()
solver.add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613)
solver.add(30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400)
solver.add(-103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - v6*2**6 - 120 * v9 == -10283)
solver.add(71 * v6 + v7*2**7 + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855)
solver.add(5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944)
solver.add(-54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222)
solver.add(-83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258)
solver.add(81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559)
solver.add(101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308)
solver.add(99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697)
if solver.check() == sat:
result = solver.model()
print(result)
else:
print(solver.check())

a1 = [result[v2], result[v1], result[v3], result[v4], result[v5], result[v7], result[v6], result[v8], result[v9], result[v11]]

print(''.join(chr(i.as_long()) for i in a1))
#F0uRTy_7w@


## [Zer0pts2020]easy strcmp

• main: 应用程序的主函数。
• argc: 命令行参数数量。
• ubp_av: 指向命令行参数字符串的指针数组。
• init: 构造函数会在 main() 函数之前被调用。
• fini: 析构函数在 main() 函数退出之前被调用。
• rtld_fini: 在卸载动态库时调用的析构函数。
• stack_end: 当前线程堆栈的结束地址。

from binascii import hexlify, unhexlify

qword_201060 = [0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B]
encflag = b'********CENSORED********'
flag = b''
for i in range(3):
eachpart = encflag[i*8:(i+1)*8][::-1]
deceachpart = int(hexlify(eachpart), 16) + qword_201060[i]
flag += unhexlify(hex(deceachpart)[2:])[::-1]

print(flag)


## [WUSTCTF2020]level4

### init分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pjMpCJYh-1688436961075)([WUSTCTF2020]level4/1.png)]

for循环中，每隔24字节赋值一个字符。然后将一系列unk的地址给qword值得注意的是，这些unk之间正好是隔24字节，而这些qword正好是在每24字节的最后面，一般都有两个，记录unk的地址，我们可以猜测，这是一个结构体，并且结构体中的变量qword存储了其他结构体的地址。

### type1和type2分析

__int64 __fastcall type1(char *a1)
{
__int64 result; // rax

if ( a1 )
{
type1(*((_QWORD *)a1 + 1));
putchar(*a1);
return type1(*((_QWORD *)a1 + 2));
}
return result;
}

int __fastcall type2(char *a1)
{
int result; // eax

if ( a1 )
{
type2(*((_QWORD *)a1 + 1));
type2(*((_QWORD *)a1 + 2));
return putchar(*a1);
}
return result;
}


(_QWORD *)a1 + 1指向的是结构体存储的第一个qword(_QWORD *)a1 + 2指向的是结构体存储的第二个qword，这两个作为参数进行递归。在分析init函数中，我们分析到了qword存储的是其他结构体的地址，再结合代码的书写，很有可能这个结构体是二叉树，type1是中序遍历，type2是后序遍历。那么很有可能这个flag是前序存储的，所以我们需要根据中序、后序遍历还原前序遍历。

### 方法一

#include <iostream>

using namespace std;
char post[] = "20f0Th{2tsIS_icArE}e7__w";
char mid[] = "2f0t02T{hcsiI_SwA__r7Ee}";

//root是后序列表中代表根节点的点的下标,start，end是中序遍历中当前处理的树的开始与结尾
void pre(int root, int start, int end) {
if(start > end)
return;
int i = start;
while(i < end && mid[i] != post[root]) //定位根在中序的位置
i++;
cout << mid[i];  //访问当前处理的树的根
//中序(左根右)end-i 则是右子树的大小
//后序(左右根)root-1-(end-i)则是左子树的大小
pre(root-1-(end-i), start, i - 1);  //递归处理左子树
pre(root-1, i + 1, end);  //递归处理右子树
}

int main(){
pre(24, 0, 24);
return 0;
}


## [网鼎杯 2020 青龙组]singal

#include <stdio.h>
#include <string.h>
#include <windows.h>

unsigned char a1[] =
{
0x0A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00,
0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x41, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3F, 0x00,
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00,
0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xA7, 0xFF, 0xFF, 0xFF,
0x07, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0xF1, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x84, 0xFF,
0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xC1, 0xFF, 0xFF, 0xFF,
0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x7A, 0x00, 0x00, 0x00
};

int a2 = 114;

char str[200] = {0};

int result; // eax
char Str[200]; // [esp+13h] [ebp-E5h] BYREF
char v4; // [esp+DBh] [ebp-1Dh]
int v5; // [esp+DCh] [ebp-1Ch]
int v6; // [esp+E0h] [ebp-18h]
int v7; // [esp+E4h] [ebp-14h]
int v8; // [esp+E8h] [ebp-10h]
int v9; // [esp+ECh] [ebp-Ch]

v9 = 0;
v8 = 0;
v7 = 0;
v6 = 0;
v5 = 0;
int caselist[200] = {0},casepos=0;
while ( 1 ){
result = v9;
if ( v9 >= a2 )
return result;

caselist[casepos++] = a1[v9];
printf("v9 = %d, v8 = %d ,v7 = %d, v6 = %d, v5 = %d\n",v9,v8,v7,v6,v5);
switch ( a1[v9] )
{
case 1:
Str[v6 + 100] = v4;
++v9;
++v6;
++v8;
break;
case 2:
v4 = a1[v9 + 1] + Str[v8];
v9 += 2;
break;
case 3:
v4 = Str[v8] - LOBYTE(a1[v9 + 1]);
v9 += 2;
break;
case 4:
v4 = a1[v9 + 1] ^ Str[v8];
v9 += 2;
break;
case 5:
v4 = a1[v9 + 1] * Str[v8];
v9 += 2;
break;
case 6:
++v9;
break;
case 7:
for(int i=0;i<casepos;i++){
printf("%d ",caselist[i]);
}
printf("\n");
if ( Str[v7 + 100] != a1[v9 + 1] )
{
printf("what a shame...");
exit(0);
}
++v7;
v9 += 2;
break;
case 8:
Str[v5] = v4;
++v9;
++v5;
break;
case 10:
strcpy(str,"flag{123456789}");
++v9;
break;
case 11:
v4 = Str[v8] - 1;
++v9;
break;
case 12:
v4 = Str[v8] + 1;
++v9;
break;
default:
continue;
}
}

}
int main(){

return 0;

}


v9 = 79, v8 = 14 ,v7 = 0, v6 = 14, v5 = 14
v9 = 81, v8 = 14 ,v7 = 0, v6 = 14, v5 = 14
v9 = 82, v8 = 14 ,v7 = 0, v6 = 14, v5 = 15
v9 = 83, v8 = 14 ,v7 = 0, v6 = 14, v5 = 15
v9 = 84, v8 = 15 ,v7 = 0, v6 = 15, v5 = 15
10 4 8 3 1 4 8 5 1 3 8 11 1 12 8 4 1 5 8 3 1 11 8 11 1 4 8 3 1 2 8 4 1 12 8 11 1 5 8 2 1 2 8 4 1 2 8 5 1 5 8 2 1 4 8 3 1 2 8 12 1 7
what a shame...


unsigned char Str100[15] = {0};

int v9 = 84,v7 = 15;

for(int i=0;i<v7;i++){
Str100[i] = *((int*)a1+v9+1);
v9 += 2;
}


unsigned char a1[] =
{
...
};
int a2 = 114;
unsigned char Str100[15] = {0};
int order[] = {1, 12, 8, 2, 1, 3, 8, 4, 1, 2, 8, 5, 1, 5, 8, 2, 1, 4, 8, 2, 1, 2, 8, 5, 1, 11, 8, 12, 1, 4, 8, 2, 1, 3, 8, 4, 1, 11, 8, 11, 1, 3, 8, 5, 1, 4, 8, 12, 1, 11, 8, 3, 1, 5, 8, 4, 1, 3, 8, 4,10};
int dec_vm_operad(unsigned int* a1,int a2) {
unsigned char Str[200]; // [esp+13h] [ebp-E5h] BYREF
unsigned char v4; // [esp+DBh] [ebp-1Dh]
int v5; // [esp+DCh] [ebp-1Ch]
int v6; // [esp+E0h] [ebp-18h]
int v7; // [esp+E4h] [ebp-14h]
int v8; // [esp+E8h] [ebp-10h]
int v9; // [esp+ECh] [ebp-Ch]

v9 = 84;
v8 = 15;
v7 = 0;
v6 = 15;
v5 = 15;

char sstr[20] = {0};
int sstrpos = 15;
int orderpos = 0;
while ( 1 ){
switch ( order[orderpos++] )
{
case 1:
--v9;
--v6;
--v8;
v4 = Str100[v6];
break;
case 2:
v9 -= 2;
Str[v8] = v4 - a1[v9 + 1];
break;
case 3:
v9 -= 2;
Str[v8] = v4 + LOBYTE(a1[v9 + 1]);
break;
case 4:
v9 -= 2;
Str[v8] = a1[v9 + 1] ^ v4;
break;
case 5:
v9 -= 2;
Str[v8] = v4 / a1[v9 + 1];
break;
case 6:
--v9;
break;
case 8:
--v9;
--v5;
v4 = Str[v5];
break;
case 10:
--v9;
//	      	printf("v9 = %d, v8 = %d ,v7 = %d, v6 = %d, v5 = %d\n",v9,v8,v7,v6,v5);
for(int i=0;i<15;i++){
printf("%c",Str[i]);
}
exit(0);
case 11:
--v9;
Str[v8] = v4 + 1;
break;
case 12:
--v9;
Str[v8] = v4 - 1;
break;
default:
printf("error!\n");
continue;
}
}

}

int main(){

int v9 = 84,v7 = 15;

for(int i=0;i<v7;i++){
Str100[i] = *((int*)a1+v9+1);
v9 += 2;
}

return 0;

}
#757515121f3d478


## crackMe

### sub841090分析

sub841090函数主要是根据输入的v11（即账号）对byte_856050进行处理，这部分可以通过运行该块代码获动态调试获取。

### loc_4011A0分析

sub8411A0函数原本是loc_4011A0。该函数点进去后，本身无法反编译，问题出在下面这个地方

jbe跳转指令的地址是有误的，所以将该指令nop掉。从loc_4011A0标签开始，选到retn指令，按p定义为函数，F5反汇编。

### 解密

#include <stdio.h>
#include <windows.h>

unsigned char byte_856050[272] = {0};

void sub_401090(BYTE *a1)
{
BYTE *result; // eax
int v2; // [esp+Ch] [ebp-18h]
int v3; // [esp+10h] [ebp-14h]
BYTE *v4; // [esp+14h] [ebp-10h]
int i; // [esp+18h] [ebp-Ch]
char v7; // [esp+20h] [ebp-4h]
char v8; // [esp+22h] [ebp-2h]
unsigned __int8 v9; // [esp+23h] [ebp-1h]

for ( i = 0; i < 256; ++i )
byte_856050[i] = i;

v2 = 0;
v9 = 0;
v3 = 0;
result = a1;
v4 = a1;

do
;
while ( *v4++ );
while ( v2 < 256 ){
v8 = byte_856050[v2];
v9 += v8 + a1[v3];
v7 = byte_856050[v9];
++v3;
byte_856050[v9] = v8;
byte_856050[v2] = v7;
result = (BYTE *)v3;
if ( v3 >= v4 - (a1 + 1) )
v3 = 0;
++v2;
}

}

int main(){

int v14 = 0xAB94;
char v17[] = "dbappsec";
char user[] = "welcomebeijing";
char v15[8] = {0} ;
//计算出byte_416050
sub_401090((BYTE*)user);

int v4; // [esp+18h] [ebp-22Ch]
signed int v5; // [esp+1Ch] [ebp-228h]
signed int v6; // [esp+28h] [ebp-21Ch]
unsigned int v7; // [esp+30h] [ebp-214h]
unsigned char v8; // [esp+36h] [ebp-20Eh]
unsigned char v9; // [esp+37h] [ebp-20Dh]
unsigned char v10; // [esp+38h] [ebp-20Ch]
unsigned __int8 v11; // [esp+39h] [ebp-20Bh]
unsigned __int8 v12; // [esp+3Ah] [ebp-20Ah]
char v13; // [esp+3Bh] [ebp-209h]

v5 = 0;
v6 = 0;
v12 = 0;
v11 = 0;
v10 = 0;
v7 = 0;
v4 = 0;

//计算出v15
while(v6 < 8){

v11 += byte_856050[++v12];
v13 = byte_856050[v12];
v8 = byte_856050[v11];
byte_856050[v11] = v13;
byte_856050[v12] = v8;

//sub_401710
v17[v6] = user[v6] ^ v17[v6];

v15[v6] = byte_856050[(256 + v8 + v13)%256] ^ v17[v6];
//		printf("v8 + v13=%d, %x\n",(v8 + v13+256)%256,byte_856050[(256 + v8 + v13)%256]);
v6++;

}
//根据v15，反推出偏移量
for(int i=0;i<8;i++){
//		BYTE pre_v8 = HIBYTE(v15[i]);
//		BYTE now_v8 = LOBYTE(v15[i]);
printf("%02x",(BYTE)v15[i]);
}

return 0;

}


(4条消息) BUUCTF crackMe 题解___lifanxin的博客-CSDN博客

## [GUET-CTF2019]number_game

main函数分析如下

### sub_400758分析

v6是一个24字节的结构体，第一个字节存储字符。根据下面两个递归调用以及函数返回值是结构体地址，可以认为这是一个二叉树。再仔细分析参数2*a2+12*(a2+1)，说明字符串是以前序方式存储的。那么整个二叉树就如下图所示

### sub_400807分析

7381940526


### sub_400917分析

unk_601060正是那块25字节的空间。根据5*i等，猜测应该是将25个字节分成5×5的矩阵。两个if语句简化一下

unk_601060[i][j] != unk_601060[i][k]//同一行中，任意两个值不能相等
unk_601060[j][i] != unk_601060[k][i]//同一列中，任意两个值不能相等


### 解密

1 4 # 2 3
3 0 # 1 #
0 # 2 3 #
# 3 # # 0
4 2 # # 1
=>
0421421430


7381940526


字符排列：0421421430



## [羊城杯 2020]easyre

main函数分析如图所示

import base64

enc3 = 'EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG'
enc2 = ''
enc1 = ''
print(len(enc3))
for i in range(len(enc3)):
if 'a' <= enc3[i] <= 'z':
enc2 += chr((ord(enc3[i]) - 97 - 3) % 26 + 97)
elif 'A' <= enc3[i] <= 'Z':
enc2 += chr((ord(enc3[i]) - 65 - 3) % 26 + 65)
elif '0' <= enc3[i] <= '9':
enc2 += chr((ord(enc3[i]) - 48 - 3) % 10 + 48)
else:
enc2 += enc3[i]

print(f'enc2 = {enc2}')

enc1 += enc2[13:26]
enc1 += enc2[39:52]
enc1 += enc2[:13]
enc1 += enc2[26:39]

print(f'enc1 = {enc1}')

flag = base64.b64decode(enc1.encode())
print(flag)


## findKey

Str = "0kkd1a55k222k2a776jbfgd06cjjb"
md5 = ''
for i in range(len(Str)):
md5 += chr(ord(Str[i]) ^ ord('S'))
print(md5)
#md5拿到网站上解密得到123321
v18 = '123321'
v10 = [
0x57, 0x5E, 0x52, 0x54, 0x49, 0x5F, 0x01, 0x6D, 0x69, 0x46,
0x02, 0x6E, 0x5F, 0x02, 0x6C, 0x57, 0x5B, 0x54, 0x4C
]

v5 = len(v18)
flag = ''
for i in range(len(v10)):
flag += chr(v10[i] ^ ord(v18[i % v5]))
print(flag)


## [网鼎杯 2020 青龙组]jocker

virtualProtect 函数 (memoryapi.h) - Win32 apps | Microsoft Learn

WinNT.h (内存保护常量) - Win32 apps | Microsoft Learn

#include <stdio.h>

unsigned char v2[] =
{
0x66, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0x63, 0x00,
0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x61, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x64, 0x00,
0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
0x6B, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x7B, 0x00,
0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x5F, 0x00,
0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00,
0x71, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x37, 0x00,
0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

int main(){

int Str[24] = {0};

for(int i=0;i<=23;i++){
if ( (i & 1) != 0 )
Str[i] = *((int*)(v2)+i) + i;
else
Str[i] = *((int*)(v2)+i) ^ i;
}

for(int i=0;i<=23;i++){
printf("%c",Str[i]);
}

return 0;

}
//flag{fak3_alw35_sp_me!!}


IDA启动动态调试后，输入flag（24bytes，所以直接输入假的flag），断点起作用之后，在IDA View-EIP界面按快捷键Tab就可以得到伪代码，再按一次就可以将光标所在伪代码转成汇编代码

#include <stdio.h>

unsigned char v2[] =
{
0x0E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x09, 0x00,
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x56, 0x00,
0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x1F, 0x00,
0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x6B, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x59, 0x00,
0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

char Buffer[] = "hahahaha_do_you_find_me?";

int main(){

int Destination[24] = {0};

for(int i=0;i<=18;i++){
Destination[i] = *((int*)(v2)+i) ^ Buffer[i];
}

for(int i=0;i<=23;i++){
printf("%c",Destination[i]);
}

return 0;

}
//flag{d07abccf8a410c


v3[0] != a1[0] == v4
=> 1 == v4


int main(){
char v3[] = "%tp&:";
int key = v3[4] ^ '}';
for(int i=0;i<5;i++){
printf("%c",key ^ v3[i]);
}
}
//b37a}


## [FlareOn5]Minesweeper Championship Registration

jadx工具打开class文件

flag已经很明显了！

## [ACTF新生赛2020]SoulLike

main函数分析如上图所示。关键函数sub_83A无法进入，提示too big function，需要修改配置文件IDA\cfg\hexrays.cfg，将MAX_FUNCSIZE = 64修改成MAX_FUNCSIZE = 1024

IDA反编译失败总结ida无法反编译 寻梦&之璐的博客-CSDN博客

## firmware

./extract-firmware.sh xxxx.bin


## [GWCTF 2019]re3

mportectdword_400000开始的0xF000大小的内存的权限改为可读可写可执行。

15行的for循环说明sub_402219函数一开始被加密，然后运行时解密。所以我们进行IDA动态调试。动态调试ELF文件时debugger的配置参考如下：

【reverse IDA使用技巧】IDA动态调试Linux_ELF配置+例题：SCUCTF新生赛2021-DebugMe - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

### sub_40207B

v5 = 0x67452301;
v6 = 0xEFCDAB89;
v8 = 0x10325476;
v15 = v11 ^ (v10 | ~v12)
v15 = v12 ^ v11 ^ v10
v15 = v10 & v12 | v11 & ~v12
v15 = v11 & v10 | v12 & ~v10


md5算法一致(MD5算法解析 - 知乎 (zhihu.com))。

0xCB, 0x8D, 0x49, 0x35, 0x21, 0xB4, 0x7A, 0x4C, 0xC1, 0xAE, 0x7E, 0x62, 0x22, 0x92, 0x66, 0xCE


### sub_402219

from Crypto.Cipher import AES
from binascii import hexlify,unhexlify

key = unhexlify('CB8D493521B47A4CC1AE7E62229266CE')
print(c)
print(key)
# 从IDA中导出string literal如下，会出问题
# key = '\x6EBF1\x8DI5!\xB4zL\x35BF4\xAE~b"\x92f\x35BF4'
aes = AES.new(key, AES.MODE_ECB)
m = aes.decrypt(c)
print(m)


## [MRCTF2020]PixelShooter

apk文件，拖到模拟器上，玩了一下，是个飞机打陨石的游戏。

## [FlareOn1]Bob Doge

btnDecode_Click函数顾名思义，显然是点击decode按钮触发的事件。整个函数的功能是将dat_sercet进行三次解密，得到的text3就是我们点击decode按钮后所看到的字符。此时，我们并不清楚哪个字符串才是我们想要的，所以这里我们直接动调。

## [GXYCTF2019]simple CPP

from z3 import *
from binascii import unhexlify

v14, v13, v12, v11 = BitVecs('v14 v13 v12 v11', 64)
solver = Solver()
solver.add((v12 & ~v13) & v14 | v12 & ((v13 & v14) | v13 & ~v14 | ~(v13 | v14)) == 0x8020717153E3013)
solver.add((v12 & ~v14) | (v13 & v14) | (v12 & ~v13) | (v14 & ~v13) == 0x3E3A4717373E7F1F)
solver.add((((v12 & ~v14) | (v13 & v14) | (v12 & ~v13) | (v14 & ~v13)) ^ v11) == 0x3E3A4717050F791F)
solver.add(((v12 & ~v14) | (v13 & v14) | v13 & v12) == (~v14 & v12 | 0xC00020130082C0C) and 1)

if solver.check() == sat:
result = solver.model()

_v14 = result[v14].as_long()
_v13 = result[v13].as_long()
_v12 = result[v12].as_long()
_v11 = result[v11].as_long()

v5 = hex(_v14)[2:].rjust(16, '0') + hex(_v13)[2:].rjust(16, '0') + hex(_v12)[2:].rjust(16, '0') + hex(_v11)[2:].rjust(3)
v5 = unhexlify(v5)[:27]

v10 = 'i_will_check_is_debug_or_not'

block = ''
for i in range(len(v5)):
block += chr(v5[i] ^ ord(v10[i]))

print(block)
# We1l_D0ndeajoa_Slgebra_am_i


## [FlareOn5]Ultimate Minesweeper

this.RevealedCells.Add(row * MainForm.VALLOC_NODE_LIMIT + column);


AllocateMemory()函数就是对地图进行初始化。雷区的标志就是true，非雷区的标志就是false。而判断是否是非雷区的条件就是

this.VALLOC_TYPES.Contains(this.DeriveVallocType(r, c)


DeriveVallocType()正好在图中的下面

~(r * MainForm.VALLOC_NODE_LIMIT + c)


#include <stdio.h>

int main(){

int result[] = {4294966400,4294966657,4294967026};
int row[3] = {0};
int colum[3] = {0};

for(int i=0;i<3;i++){
int tmp = (~result[i]) - 31;
row[i] = tmp / 30;
colum[i] = tmp % 30;
}

for(int i=0;i<3;i++){
printf("%d %d\n",row[i],colum[i]);
}

return 0;

}


## [CFI-CTF 2018]IntroToPE

Exeinfo PE查看，发现是c#编写的程序，使用dnspy工具打开。

## [2019红帽杯]xx

v20v30进行比对，但需要注意数据在内存以小端模式存储，所以我们要将数据反过来。

from Crypto.Util.number import *
import struct
from binascii import unhexlify
_DELTA = 0x9E3779B9

def _long2str(v, w):
n = (len(v) - 1) << 2
if w:
m = v[-1]
if (m < n - 3) or (m > n): return ''
n = m
s = struct.pack('<%iL' % len(v), *v)
return s[0:n] if w else s

def _str2long(s, w):
n = len(s)
m = (4 - (n & 3) & 3) + n
s = s.ljust(m, b"\0")
v = list(struct.unpack('<%iL' % (m >> 2), s))
if w: v.append(n)
return v

def decrypt(str, key):
if str == '': return str
v = _str2long(str, False)
k = _str2long(key.ljust(16, b"\0"), False)
n = len(v) - 1
z = v[n]
y = v[0]
q = 6 + 52 // (n + 1)
sum = (q * _DELTA) & 0xffffffff
while (sum != 0):
e = sum >> 2 & 3
for p in range(n, 0, -1):
z = v[p - 1]
v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff
y = v[p]
z = v[n]
v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffff
y = v[0]
sum = (sum - _DELTA) & 0xffffffff
return _long2str(v, True)

v20 = 'CE BC 40 6B 7C 3A 95 C0 EF 9B 20 20 91 F7 02 35 23 18 02 C8 E7 56 56 FA'.split(' ')
v20 = [int(i, 16) for i in v20]
print(v20)
v18 = len(v20)

# 逆异或
for v21 in range(23, 0, -1):
v23 = 0
if v21 // 3 > 0:
v24 = v20[v21]
while v23 < v21 // 3:
v24 ^= v20[v23]
v23 += 1
v20[v21] = v24

print(v20)

# 弄好顺序
v19 = [0 for i in range(24)]
for i in range(0, 24, 4):
v19[i] = v20[i+1]
v19[i+1] = v20[i+3]
v19[i+2] = v20[i]
v19[i+3] = v20[i+2]

print(v19)

# xxtea解密
enc = 0
for each in v19:
enc = (enc << 8) + each
enc = long_to_bytes(enc)
print(enc)

key = 'flag'.encode() + b'\x00'*12
print(key)
Code = decrypt(enc, key)
print(Code)
#b'flag{CXX_and_++tea}'


## equation

if语句中由!+[]()构成的就是jsfuck加密了。

from z3 import *

estring = "l['40'] + l['35'] + l['34'] - l[0] - l['15'] - l['37'] + l[7] + l[6] - l['26'] + l['20'] + l['19'] + l[8] - l['17'] - l['14'] - l['38'] + l[1] - l[9] + l['22'] + l['41'] + l[3] - l['29'] - l['36'] - l['25'] + l[5] + l['32'] - l['16'] + l['12'] - l['24'] + l['30'] + l['39'] + l['10'] + l[2] + l['27'] + l['28'] + l['21'] + l['33'] - l['18'] + l[4] == 861 && l['31'] + l['26'] + l['11'] - l['33'] + l['27'] - l[3] + l['12'] + l['30'] + l[1] + l['32'] - l['16'] + l[7] + l['10'] - l['25'] + l['38'] - l['41'] - l['14'] - l['19'] + l['29'] + l['36'] - l[9] - l['28'] - l[6] - l[0] - l['22'] - l['18'] + l['20'] - l['37'] + l[4] - l['24'] + l['34'] - l['21'] - l['39'] - l['23'] - l[8] - l['40'] + l['15'] - l['35'] == -448 && l['26'] + l['14'] + l['15'] + l[9] + l['13'] + l['30'] - l['11'] + l['18'] + l['23'] + l[7] + l[3] + l['12'] + l['25'] - l['24'] - l['39'] - l['35'] - l['20'] + l['40'] - l[8] + l['10'] - l[5] - l['33'] - l['31'] + l['32'] + l['19'] + l['21'] - l[6] + l[1] + l['16'] + l['17'] + l['29'] + l['22'] - l[4] - l['36'] + l['41'] + l['38'] + l[2] + l[0] == 1244 && l[5] + l['22'] + l['15'] + l[2] - l['28'] - l['10'] - l[3] - l['13'] - l['18'] + l['30'] - l[9] + l['32'] + l['19'] + l['34'] + l['23'] - l['17'] + l['16'] - l[7] + l['24'] - l['39'] + l[8] - l['12'] - l['40'] - l['25'] + l['37'] - l['35'] + l['11'] - l['14'] + l['20'] - l['27'] + l[4] - l['33'] - l['21'] + l['31'] - l[6] + l[1] + l['38'] - l['29'] == -39 && l['41'] - l['29'] + l['23'] - l[4] + l['20'] - l['33'] + l['35'] + l[3] - l['19'] - l['21'] + l['11'] + l['26'] - l['24'] - l['17'] + l['37'] + l[1] + l['16'] - l[0] - l['13'] + l[7] + l['10'] + l['14'] + l['22'] + l['39'] - l['40'] + l['34'] - l['38'] + l['32'] + l['25'] - l[2] + l['15'] + l[6] + l['28'] - l[8] - l[5] - l['31'] - l['30'] - l['27'] == 485 && l['13'] + l['19'] + l['21'] - l[2] - l['33'] - l[0] + l['39'] + l['31'] - l['23'] - l['41'] + l['38'] - l['29'] + l['36'] + l['24'] - l['20'] - l[9] - l['32'] + l['37'] - l['35'] + l['40'] + l[7] - l['26'] + l['15'] - l['10'] - l[6] - l['16'] - l[4] - l[5] - l['30'] - l['14'] - l['22'] - l['25'] - l['34'] - l['17'] - l['11'] - l['27'] + l[1] - l['28'] == -1068 && l['32'] + l[0] + l[9] + l['14'] + l['11'] + l['18'] - l['13'] + l['24'] - l[2] - l['15'] + l['19'] - l['21'] + l[1] + l['39'] - l[8] - l[3] + l['33'] + l[6] - l[5] - l['35'] - l['28'] + l['25'] - l['41'] + l['22'] - l['17'] + l['10'] + l['40'] + l['34'] + l['27'] - l['20'] + l['23'] + l['31'] - l['16'] + l[7] + l['12'] - l['30'] + l['29'] - l[4] == 939 && l['19'] + l['11'] + l['20'] - l['16'] + l['40'] + l['25'] + l[1] - l['31'] + l['28'] - l['23'] + l['14'] - l[9] - l['27'] + l['35'] + l['39'] - l['37'] - l[8] - l['22'] + l[5] - l[6] + l[0] - l['32'] + l['24'] + l['33'] + l['29'] + l['38'] + l['15'] - l[2] + l['30'] + l[7] + l['12'] - l[3] - l['17'] + l['34'] + l['41'] - l[4] - l['13'] - l['26'] == 413 && l['22'] + l[4] - l[9] + l['34'] + l['35'] + l['17'] + l[3] - l['24'] + l['38'] - l[5] - l['41'] - l['31'] - l[0] - l['25'] + l['33'] + l['15'] - l[1] - l['10'] + l['16'] - l['29'] - l['12'] + l['26'] - l['39'] - l['21'] - l['18'] - l[6] - l['40'] - l['13'] + l[8] + l['37'] + l['19'] + l['14'] + l['32'] + l['28'] - l['11'] + l['23'] + l['36'] + l[7] == 117 && l['32'] + l['16'] + l[3] + l['11'] + l['34'] - l['31'] + l['14'] + l['25'] + l[1] - l['30'] - l['33'] - l['40'] - l[4] - l['29'] + l['18'] - l['27'] + l['13'] - l['19'] - l['12'] + l['23'] - l['39'] - l['41'] - l[8] + l['22'] - l[5] - l['38'] - l[9] - l['37'] + l['17'] - l['36'] + l['24'] - l['21'] + l[2] - l['26'] + l['20'] - l[7] + l['35'] - l[0] == -313 && l['40'] - l[1] + l[5] + l[7] + l['33'] + l['29'] + l['12'] + l['38'] - l['31'] + l[2] + l['14'] - l['35'] - l[8] - l['24'] - l['39'] - l[9] - l['28'] + l['23'] - l['17'] - l['22'] - l['26'] + l['32'] - l['11'] + l[4] - l['36'] + l['10'] + l['20'] - l['18'] - l['16'] + l[6] - l[0] + l[3] - l['30'] + l['37'] - l['19'] + l['21'] + l['25'] - l['15'] == -42 && l['21'] + l['26'] - l['17'] - l['25'] + l['27'] - l['22'] - l['39'] - l['23'] - l['15'] - l['20'] - l['32'] + l['12'] + l[3] - l[6] + l['28'] + l['31'] + l['13'] - l['16'] - l['37'] - l['30'] - l[5] + l['41'] + l['29'] + l['36'] + l[1] + l['11'] + l['24'] + l['18'] - l['40'] + l['19'] - l['35'] + l[2] - l['38'] + l['14'] - l[9] + l[4] + l[0] - l['33'] == 289 && l['29'] + l['31'] + l['32'] - l['17'] - l[7] + l['34'] + l[2] + l['14'] + l['23'] - l[4] + l[3] + l['35'] - l['33'] - l[9] - l['20'] - l['37'] + l['24'] - l['27'] + l['36'] + l['15'] - l['18'] - l[0] + l['12'] + l['11'] - l['38'] + l[6] + l['22'] + l['39'] - l['25'] - l['10'] - l['19'] - l[1] + l['13'] - l['41'] + l['30'] - l['16'] + l['28'] - l['26'] == -117 && l[5] + l['37'] - l['39'] + l[0] - l['27'] + l['12'] + l['41'] - l['22'] + l[8] - l['16'] - l['38'] + l[9] + l['15'] - l['35'] - l['29'] + l['18'] + l[6] - l['25'] - l['28'] + l['36'] + l['34'] + l['32'] - l['14'] - l[1] + l['20'] + l['40'] - l['19'] - l[4] - l[7] + l['26'] + l['30'] - l['10'] + l['13'] - l['21'] + l[2] - l['23'] - l[3] - l['33'] == -252 && l['29'] + l['10'] - l['41'] - l[9] + l['12'] - l['28'] + l['11'] + l['40'] - l['27'] - l[8] + l['32'] - l['25'] - l['23'] + l['39'] - l[1] - l['36'] - l['15'] + l['33'] - l['20'] + l['18'] + l['22'] - l[3] + l[6] - l['34'] - l['21'] + l['19'] + l['26'] + l['13'] - l[4] + l[7] - l['37'] + l['38'] - l[2] - l['30'] - l[0] - l['35'] + l[5] + l['17'] == -183 && l[6] - l[8] - l['20'] + l['34'] - l['33'] - l['25'] - l[4] + l[3] + l['17'] - l['13'] - l['15'] - l['40'] + l[1] - l['30'] - l['14'] - l['28'] - l['35'] + l['38'] - l['22'] + l[2] + l['24'] - l['29'] + l[5] + l[9] + l['37'] + l['23'] - l['18'] + l['19'] - l['21'] + l['11'] + l['36'] + l['41'] - l[7] - l['32'] + l['10'] + l['26'] - l[0] + l['31'] == 188 && l[3] + l[6] - l['41'] + l['10'] + l['39'] + l['37'] + l[1] + l[8] + l['21'] + l['24'] + l['29'] + l['12'] + l['27'] - l['38'] + l['11'] + l['23'] + l['28'] + l['33'] - l['31'] + l['14'] - l[5] + l['32'] - l['17'] + l['40'] - l['34'] + l['20'] - l['22'] - l['16'] + l['19'] + l[2] - l['36'] - l[7] + l['18'] + l['15'] + l['26'] - l[0] - l[4] + l['35'] == 1036 && l['28'] - l['33'] + l[2] + l['37'] - l['12'] - l[9] - l['39'] + l['16'] - l['32'] + l[8] - l['36'] + l['31'] + l['10'] - l[4] + l['21'] - l['25'] + l['18'] + l['24'] - l[0] + l['29'] - l['26'] + l['35'] - l['22'] - l['41'] - l[6] + l['15'] + l['19'] + l['40'] + l[7] + l['34'] + l['17'] - l[3] - l['13'] + l[5] + l['23'] + l['11'] - l['27'] + l[1] == 328 && l['22'] - l['32'] + l['17'] - l[9] + l['20'] - l['18'] - l['34'] + l['23'] + l['36'] - l['35'] - l['38'] + l['27'] + l[4] - l[5] - l['41'] + l['29'] + l['33'] + l[0] - l['37'] + l['28'] - l['40'] - l['11'] - l['12'] + l[7] + l[1] + l[2] - l['26'] - l['16'] - l[8] + l['24'] - l['25'] + l[3] - l[6] - l['19'] - l['39'] - l['14'] - l['31'] + l['10'] == -196 && l['11'] + l['13'] + l['14'] - l['15'] - l['29'] - l[2] + l[7] + l['20'] + l['30'] - l['36'] - l['33'] - l['19'] + l['31'] + l[0] - l['39'] - l[4] - l[6] + l['38'] + l['35'] - l['28'] + l['34'] - l[9] - l['23'] - l['26'] + l['37'] - l[8] - l['27'] + l[5] - l['41'] + l[3] + l['17'] + l['40'] - l['10'] + l['25'] + l['12'] - l['24'] + l['18'] + l['32'] == 7 && l['34'] - l['37'] - l['40'] + l[4] - l['22'] - l['31'] - l[6] + l['38'] + l['13'] - l['28'] + l[8] + l['30'] - l['20'] - l[7] - l['32'] + l['26'] + l[1] - l['18'] + l[5] + l['35'] - l['24'] - l['41'] + l[9] - l[0] - l[2] - l['15'] - l['10'] + l['12'] - l['36'] + l['33'] - l['16'] - l['14'] - l['25'] - l['29'] - l['21'] + l['27'] + l[3] - l['17'] == -945 && l['12'] - l['30'] - l[8] + l['20'] - l[2] - l['36'] - l['25'] - l[0] - l['19'] - l['28'] - l[7] - l['11'] - l['33'] + l[4] - l['23'] + l['10'] - l['41'] + l['39'] - l['32'] + l['27'] + l['18'] + l['15'] + l['34'] + l['13'] - l['40'] + l['29'] - l[6] + l['37'] - l['14'] - l['16'] + l['38'] - l['26'] + l['17'] + l['31'] - l['22'] - l['35'] + l[5] - l[1] == -480 && l['36'] - l['11'] - l['34'] + l[8] + l[0] + l['15'] + l['28'] - l['39'] - l['32'] - l[2] - l['27'] + l['22'] + l['16'] - l['30'] - l[3] + l['31'] - l['26'] + l['20'] + l['17'] - l['29'] - l['18'] + l['19'] - l['10'] + l[6] - l[5] - l['38'] - l['25'] - l['24'] + l[4] + l['23'] + l[9] + l['14'] + l['21'] - l['37'] + l['13'] - l['41'] - l['12'] + l['35'] == -213 && l['19'] - l['36'] - l['12'] + l['33'] - l['27'] - l['37'] - l['25'] + l['38'] + l['16'] - l['18'] + l['22'] - l['39'] + l['13'] - l[7] - l['31'] - l['26'] + l['15'] - l['10'] - l[9] - l[2] - l['30'] - l['11'] + l['41'] - l[4] + l['24'] + l['34'] + l[5] + l['17'] + l['14'] + l[6] + l[8] - l['21'] - l['23'] + l['32'] - l[1] - l['29'] - l[0] + l[3] == -386 && l[0] + l[7] - l['28'] - l['38'] + l['19'] + l['31'] - l[5] + l['24'] - l[3] + l['33'] - l['12'] - l['29'] + l['32'] + l[1] - l['34'] - l[9] - l['25'] + l['26'] - l[8] + l[4] - l['10'] + l['40'] - l['15'] - l['11'] - l['27'] + l['36'] + l['14'] + l['41'] - l['35'] - l['13'] - l['17'] - l['21'] - l['18'] + l['39'] - l[2] + l['20'] - l['23'] - l['22'] == -349 && l['10'] + l['22'] + l['21'] - l[0] + l['15'] - l[6] + l['20'] - l['29'] - l['30'] - l['33'] + l['19'] + l['23'] - l['28'] + l['41'] - l['27'] - l['12'] - l['37'] - l['32'] + l['34'] - l['36'] + l[3] + l[1] - l['13'] + l['18'] + l['14'] + l[9] + l[7] - l['39'] + l[8] + l[2] - l['31'] - l[5] - l['40'] + l['38'] - l['26'] - l[4] + l['16'] - l['25'] == 98 && l['28'] + l['38'] + l['20'] + l[0] - l[5] - l['34'] - l['41'] + l['22'] - l['26'] + l['11'] + l['29'] + l['31'] - l[3] - l['16'] + l['23'] + l['17'] - l['18'] + l[9] - l[4] - l['12'] - l['19'] - l['40'] - l['27'] + l['33'] + l[8] - l['37'] + l[2] + l['15'] - l['24'] - l['39'] + l['10'] + l['35'] - l[1] + l['30'] - l['36'] - l['25'] - l['14'] - l['32'] == -412 && l[1] - l['24'] - l['29'] + l['39'] + l['41'] + l[0] + l[9] - l['19'] + l[6] - l['37'] - l['22'] + l['32'] + l['21'] + l['28'] + l['36'] + l[4] - l['17'] + l['20'] - l['13'] - l['35'] - l[5] + l['33'] - l['27'] - l['30'] + l['40'] + l['25'] - l['18'] + l['34'] - l[3] - l['10'] - l['16'] - l['23'] - l['38'] + l[8] - l['14'] - l['11'] - l[7] + l['12'] == -95 && l[2] - l['24'] + l['31'] + l[0] + l[9] - l[6] + l[7] - l[1] - l['22'] + l[8] - l['23'] + l['40'] + l['20'] - l['38'] - l['11'] - l['14'] + l['18'] - l['36'] + l['15'] - l[4] - l['41'] - l['12'] - l['34'] + l['32'] - l['35'] + l['17'] - l['21'] - l['10'] - l['29'] + l['39'] - l['16'] + l['27'] + l['26'] - l[3] - l[5] + l['13'] + l['25'] - l['28'] == -379 && l['19'] - l['17'] + l['31'] + l['14'] + l[6] - l['12'] + l['16'] - l[8] + l['27'] - l['13'] + l['41'] + l[2] - l[7] + l['32'] + l[1] + l['25'] - l[9] + l['37'] + l['34'] - l['18'] - l['40'] - l['11'] - l['10'] + l['38'] + l['21'] + l[3] - l[0] + l['24'] + l['15'] + l['23'] - l['20'] + l['26'] + l['22'] - l[4] - l['28'] - l[5] + l['39'] + l['35'] == 861 && l['35'] + l['36'] - l['16'] - l['26'] - l['31'] + l[0] + l['21'] - l['13'] + l['14'] + l['39'] + l[7] + l[4] + l['34'] + l['38'] + l['17'] + l['22'] + l['32'] + l[5] + l['15'] + l[8] - l['29'] + l['40'] + l['24'] + l[6] + l['30'] - l[2] + l['25'] + l['23'] + l[1] + l['12'] + l[9] - l['10'] - l[3] - l['19'] + l['20'] - l['37'] - l['33'] - l['18'] == 1169 && l['13'] + l[0] - l['25'] - l['32'] - l['21'] - l['34'] - l['14'] - l[9] - l[8] - l['15'] - l['16'] + l['38'] - l['35'] - l['30'] - l['40'] - l['12'] + l[3] - l['19'] + l[4] - l['41'] + l[2] - l['36'] + l['37'] + l['17'] - l[1] + l['26'] - l['39'] - l['10'] - l['33'] + l[5] - l['27'] - l['23'] - l['24'] - l[7] + l['31'] - l['28'] - l['18'] + l[6] == -1236 && l['20'] + l['27'] - l['29'] - l['25'] - l[3] + l['28'] - l['32'] - l['11'] + l['10'] + l['31'] + l['16'] + l['21'] - l[7] + l[4] - l['24'] - l['35'] + l['26'] + l['12'] - l['37'] + l[6] + l['23'] + l['41'] - l['39'] - l['38'] + l['40'] - l['36'] + l[8] - l[9] - l[5] - l[1] - l['13'] - l['14'] + l['19'] + l[0] - l['34'] - l['15'] + l['17'] + l['22'] == -114 && l['12'] - l['28'] - l['13'] - l['23'] - l['33'] + l['18'] + l['10'] + l['11'] + l[2] - l['36'] + l['41'] - l['16'] + l['39'] + l['34'] + l['32'] + l['37'] - l['38'] + l['20'] + l[6] + l[7] + l['31'] + l[5] + l['22'] - l[4] - l['15'] - l['24'] + l['17'] - l[3] + l[1] - l['35'] - l[9] + l['30'] + l['25'] - l[0] - l[8] - l['14'] + l['26'] + l['21'] == 659 && l['21'] - l[3] + l[7] - l['27'] + l[0] - l['32'] - l['24'] - l['37'] + l[4] - l['22'] + l['20'] - l[5] - l['30'] - l['31'] - l[1] + l['15'] + l['41'] + l['12'] + l['40'] + l['38'] - l['17'] - l['39'] + l['19'] - l['13'] + l['23'] + l['18'] - l[2] + l[6] - l['33'] - l[9] + l['28'] + l[8] - l['16'] - l['10'] - l['14'] + l['34'] + l['35'] - l['11'] == -430 && l['11'] - l['23'] - l[9] - l['19'] + l['17'] + l['38'] - l['36'] - l['22'] - l['10'] + l['27'] - l['14'] - l[4] + l[5] + l['31'] + l[2] + l[0] - l['16'] - l[8] - l['28'] + l[3] + l['40'] + l['25'] - l['33'] + l['13'] - l['32'] - l['35'] + l['26'] - l['20'] - l['41'] - l['30'] - l['12'] - l[7] + l['37'] - l['39'] + l['15'] + l['18'] - l['29'] - l['21'] == -513 && l['32'] + l['19'] + l[4] - l['13'] - l['17'] - l['30'] + l[5] - l['33'] - l['37'] - l['15'] - l['18'] + l[7] + l['25'] - l['14'] + l['35'] + l['40'] + l['16'] + l[1] + l[2] + l['26'] - l[3] - l['39'] - l['22'] + l['23'] - l['36'] - l['27'] - l[9] + l[6] - l['41'] - l[0] - l['31'] - l['20'] + l['12'] - l[8] + l['29'] - l['11'] - l['34'] + l['21'] == -502 && l['30'] - l['31'] - l['36'] + l[3] + l[9] - l['40'] - l['33'] + l['25'] + l['39'] - l['26'] + l['23'] - l[0] - l['29'] - l['32'] - l[4] + l['37'] + l['28'] + l['21'] + l['17'] + l[2] + l['24'] + l[6] + l[5] + l[8] + l['16'] + l['27'] + l['19'] + l['12'] + l['20'] + l['41'] - l['22'] + l['15'] - l['11'] + l['34'] - l['18'] - l['38'] + l[1] - l['14'] == 853 && l['38'] - l['10'] + l['16'] + l[8] + l['21'] - l['25'] + l['36'] - l['30'] + l['31'] - l[3] + l[5] - l['15'] + l['23'] - l['28'] + l[7] + l['12'] - l['29'] + l['22'] - l[0] - l['37'] - l['14'] - l['11'] + l['32'] + l['33'] - l[9] + l['39'] + l['41'] - l['19'] - l[1] + l['18'] - l[4] - l[6] + l['13'] + l['20'] - l[2] - l['35'] - l['26'] + l['27'] == -28 && l['11'] + l['18'] - l['26'] + l['15'] - l['14'] - l['33'] + l[7] - l['23'] - l['25'] + l[0] - l[6] - l['21'] - l['16'] + l['17'] - l['19'] - l['28'] - l['38'] - l['37'] + l[9] + l['20'] - l[8] - l[3] + l['22'] - l['35'] - l['10'] - l['31'] - l[2] + l['41'] - l[1] - l[4] + l['24'] - l['34'] + l['39'] + l['40'] + l['32'] - l[5] + l['36'] - l['27'] == -529 && l['38'] + l[8] + l['36'] + l['35'] - l['23'] - l['34'] + l['13'] - l[4] - l['27'] - l['24'] + l['26'] + l['31'] - l['30'] - l[5] - l['40'] + l['28'] - l['11'] - l[2] - l['39'] + l['15'] + l['10'] - l['17'] + l[3] + l['19'] + l['22'] + l['33'] + l[0] + l['37'] + l['16'] - l[9] - l['32'] + l['25'] - l['21'] - l['12'] + l[6] - l['41'] + l['20'] - l['18'] == -12 && l[6] - l['30'] - l['20'] - l['27'] - l['14'] - l['39'] + l['41'] - l['33'] - l[0] + l['25'] - l['32'] - l[3] + l['26'] - l['12'] + l[8] - l['35'] - l['24'] + l['15'] + l[9] - l[4] + l['13'] + l['36'] + l['34'] + l[1] - l['28'] - l['21'] + l['18'] + l['23'] + l['29'] - l['10'] - l['38'] + l['22'] + l['37'] + l[5] + l['19'] + l[7] + l['16'] - l['31'] == 81".replace("'",'')
elist = estring.split('&&')
print(elist)

s = Solver()
flen = 0x2a
l = [0 for i in range(flen)]

for i in range(flen):
l[i] = Int(f'l[{i}]')

for e in elist:

if s.check() == sat:
result = s.model()

print(result)

flag = ''
for i in range(flen):
flag += chr(result[eval(f'l[i]')].as_long())

print(flag)
`
• 0
点赞
• 1
收藏
觉得还不错? 一键收藏
• 0
评论
04-15 360
07-19 2676
07-14 820
06-06 490
03-14 4276
10-12 2406
12-16 1244
03-07 223
03-05 1144

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