hgame 2022-2024 week4 汇总

hgame 2022-2024 week4 汇总

在该处下断点动调的时候,先输入32个字符,然后F9步过,然后出现下图情况

image-20240314011117611

下面的链接即为当比较成功时的跳转地,上方的则为当比较数据不同时的Never Gonna Give You UP(其实没啥用)

image-20240314172042098

在If里面直接对两个数据进行比较,如果一样就输出win,所以我们可以得知两个数据相同

可以看出在48行前的加密和比较后进行的加密是对称加密,则我们可以选择将Buf2的1数据调整成条件判断里面unk_974D40这个地方的数据,然后通过动调得到flag(即v10)

双击buf2,右键选择paste data,将unk_974D40的数据给Buf2,注意不是动调的时候的输入的数据所存的位置

然后不用保存文件直接F9,在输入的位置的得到被还原的flag的数据

image-20240314201249889

image-20240314202708209

hgame{WOWOW_h@ppy_n3w_ye4r_2022}

ezvm

典型vm

image-20240315161342365

已知为vm题,故可以将变量名改成寄存器,好看一点

下图可以看到关键步骤

image-20240315170805448

双击可以获取r的地址,为0x49F020,已知偏移量为0x6d,所以实际opcode的地址为0x49F020+0x6d*4=0x49f364

image-20240315170528451

可以脚本获取地址

我们最开始动调,发现程序无输入,获取r[0]的初值为0

image-20240315175108047

通过分析发现case18里面在进行数据的压栈操作,动调可知此时v0=0,由此我们可知data的数据地址为0x49F024+209*4,即为0x49f364

image-20240315230647523

前往0x49f364获取data

1
2
3
4
5
6
7
8
9
10
unsigned int opcode[66] = {
0x00000012, 0x00000008, 0x00000012, 0x00000009, 0x00000010, 0x00000004, 0x00000001, 0x0000000F,
0x0000000D, 0x00000002, 0x00000012, 0x00000008, 0x00000012, 0x00000009, 0x00000000, 0x00000004,
0x0000000F, 0x0000000D, 0x00000012, 0x00000009, 0x00000012, 0x0000000A, 0x00000013, 0x00000012,
0x0000000B, 0x00000015, 0x00000003, 0x00000014, 0x00000001, 0x00000000, 0x0000000F, 0x0000000D,
0x00000012, 0x0000000A, 0x00000012, 0x00000012, 0x00000012, 0x00000008, 0x00000013, 0x0000000F,
0x00000007, 0x00000004, 0x00000009, 0x0000000D, 0x00000009, 0x00000008, 0x00000005, 0x00000006,
0x00000004, 0x00000001, 0x00000000, 0x0000000F, 0x0000000D, 0x00000012, 0x00000009, 0x00000012,
0x00000008, 0x00000012, 0x0000000A, 0x00000012, 0x00000007, 0x0000000F, 0x0000000C, 0x00000011,
0x0000000E, 0xFFFFFFFF};
1
2
3
4
5
6
7
8
9
10
11
12
13
unsigned int data[83] = {
0x0000000A, 0xFFFFFFFB, 0x00000020, 0x0000002F, 0xFFFFFFF6, 0x00000000, 0x0000005E, 0x00000046,
0x00000061, 0x00000043, 0x0000000E, 0x00000053, 0x00000049, 0x0000001F, 0x00000051, 0x0000005E,
0x00000036, 0x00000037, 0x00000029, 0x00000041, 0x00000063, 0x0000003B, 0x00000064, 0x0000003B,
0x00000015, 0x00000018, 0x0000005B, 0x0000003E, 0x00000022, 0x00000050, 0x00000046, 0x0000005E,
0x00000035, 0x0000004E, 0x00000043, 0x00000023, 0x00000060, 0x0000003B, 0x00000000, 0xFFFFFFEF,
0x00000015, 0x0000008E, 0x00000088, 0x000000A3, 0x00000099, 0x000000C4, 0x000000A5, 0x000000C3,
0x000000DD, 0x00000019, 0x000000EC, 0x0000006C, 0x0000009B, 0x000000F3, 0x0000001B, 0x0000008B,
0x0000005B, 0x0000003E, 0x0000009B, 0x000000F1, 0x00000086, 0x000000F3, 0x000000F4, 0x000000A4,
0x000000F8, 0x000000F8, 0x00000098, 0x000000AB, 0x00000086, 0x00000089, 0x00000061, 0x00000022,
0x000000C1, 0x00000002, 0x00000000, 0xFFFFFFFA, 0x00000073, 0x00000075, 0x00000063, 0x00000063,
0x00000065, 0x00000073, 0x00000073
};

通过脚本跑出结果

image-20240315233423220

xor_keys = [94, 70, 97, 67, 14, 83, 73, 31, 81, 94, 54, 55, 41, 65, 99, 59, 100, 59, 21, 24, 91, 62, 34, 80, 70, 94, 53, 78, 67, 35, 96, 59] plain_text = [] cipher = [142, 136, 163, 153, 196, 165, 195, 221, 25, 236, 108, 155, 243, 27, 139, 91, 62, 155, 241, 134, 243, 244, 164, 248, 248, 152, 171, 134, 137, 97, 34, 193] for i in range(0,32): plain_text.append(chr((cipher[i]^xor_keys[i])//2)) print(plain_text) print(‘’.join(plain_text))

hgame{Ea$Y-Vm-t0-PrOTeCT_cOde!!}

Server

在main_main函数里面找到

image-20240314210636014

进入main_HttpHandleFunc,找到main_encrypt

image-20240314210746022

image-20240315011532248

在main_encrypt函数中,可以找到math_big_ptr_Int_SetString函数,经了解可知该题目若使用 IDA7.6 及以上版本打开时,会直接加载嵌入的符号表,可减轻逆向的难度,如果打开后部分的函数仍然分析不出函数参数时,可以自行针对math_big__ptr_Int_SetString函数进行数据的补齐

image-20240315145544247

参考格式:

__int64 __usercall math_big___ptr_Int__SetString@(char *str@, __int64 a2@, int a3@, int a4@)

关键加密逻辑

根据前面的代码我们可以猜测是RSA,在main_encrypt函数里面可以获得数据

其中p=92582184765240663364795767694262273105045150785272129481762171937885924776597

q=107310528658039985708896636559112400334262005367649176746429531274300859498993

e=950501

浅浅浅去看了一下RSA…………………………

exp:

import gmpy2
from Crypto.Util.number import bytes_to_long,long_to_bytes

p=92582184765240663364795767694262273105045150785272129481762171937885924776597
q=107310528658039985708896636559112400334262005367649176746429531274300859498993
n=p*q
e=950501
ccc=[99, 85, 4, 3, 5, 5, 5, 3, 7, 7, 2, 8, 8, 11, 1, 2, 10, 4, 2, 13, 8, 9, 12, 9, 4, 13, 8, 0, 14, 0, 15, 13, 14, 10, 2, 2, 1, 7, 3, 5, 6, 4, 6, 7, 6, 2, 2, 5, 3, 3, 9, 6, 0, 11, 13, 11, 0, 2, 3, 8, 3, 11, 7, 1, 11, 5, 14, 5, 0, 10, 14, 15, 13, 7, 13, 7, 14, 1, 15, 1, 11, 5, 6, 2, 12, 6, 10, 4, 1, 7, 4, 2, 6, 3, 6, 12, 5, 12, 3, 12, 6, 0, 4, 15, 2, 14, 7, 0, 14, 14, 12, 4, 3, 4, 2, 0, 0, 2, 6, 2, 3, 6, 4, 4, 4, 7, 1, 2, 3, 9, 2, 12, 8, 1, 12, 3, 12, 2, 0, 3, 14, 3, 14, 12, 9, 1, 7, 15, 5, 7, 2, 2, 4, 102, 94]

tmp=0x66
for i in range(1,153,2):
ccc[i] ^= tmp
tmp = ccc[i]
#print(i, chr(tmp))

print(hex(tmp))
for j in range(0x30,0x3a):
tmp=j
tmp ^= 0x66
cct=[i for i in ccc]
for i in range(0,153,2):
cct[i] ^= tmp
tmp = cct[i]
a=bytes(cct)
print(a)

c=135005562109829034199059149474896341566307600227148289525068532297727897409776873250963225670468340868270979975367474527115512003915945795967599087720024
#c=34015463119928024098049048464997351467317701237049299424078433287626887508766972240862235771478241878371969874377575537014502102905844785866589186730125
d=gmpy2.invert(e,(p-1)*(q-1))
m=pow(c,d,n)
print(long_to_bytes(m))

hgame{g0_and_g0_http_5erv3r_nb}

hardasm

了解一下

指令
  1. vpermd:这条指令用于按照索引重新排列一个256位的寄存器中的32位元素。它会根据指定的索引重新排列元素,将元素重新排列后存储到目标寄存器中。

  2. vpxor:这个指令执行两个向量寄存器之间的逻辑异或操作。即将两个向量寄存器中对应位置的元素进行逻辑异或运算,并将结果存储到目标寄存器中。

  3. vpaddb:这个指令用于在字节级别对两个向量寄存器中的元素进行相加操作。它会将两个向量寄存器中对应位置的字节元素相加,并将结果存储到目标寄存器中。

  4. vpsubb:这个指令用于在字节级别对两个向量寄存器中的元素进行相减操作。它会将两个向量寄存器中对应位置的字节元素相减,并将结果存储到目标寄存器中。

  5. vpshufb:这个指令执行按字节的逐元素选择和重组操作。根据掩码寄存器中的值,在源寄存器中选择元素,并将这些元素按照特定的顺序重新排列后存储到目标寄存器中。

  6. vpcmpeqb:将两个操作数进行逐字节比较,如果两个操作数的对应字节相等,则将目标寄存器中的对应字节设置为全部1(0xFF)

    以上这些指令主要用于在向量级别上执行数据处理和计算操作

在 AVX 指令集中,__m256 数据类型表示一个包含 8 个单精度浮点数的 256 位向量。这意味着它可以同时对这 8 个单精度浮点数执行相同的操作,从而实现数据的并行处理。

image-20240314211454895

上图中可以看出数据被存入ymm0-ymm7中

image-20240314232209430

这里的判断语句,切换到汇编界面如下

image-20240314232124621

我们可以看到下面的代码一直在进行逐个字节比较的操作,直到遇到一个字节为0或者比较完所有字节。如果所有字节都不为0,则跳转到标签”loc_140008055”,如果遇到字节为0,则直接跳转到标签”loc_14000804E”,即错误,所以当所有字节不为0时,即为正确

image-20240314233349660

从这一行我们可以看出比较是否相等的数据的结果被存放在ymm1寄存器里面

image-20240314234926255

因为在判断条件的比较里面有8个m256类型的单精度浮点数的向量,每个单精度浮点数会进行4次字节比较,所以会进行32次字节比较的操作,故flag长度为32字节

经过检验发现Flag的格式

image-20240315001543060

检验过程:1.准备除了固定的hgame{ }以外的25的字符(里面随便啥都行)

image-20240315001155280

  1. 动调,发现前面数据为0FFh,即可以说明该格式正确

image-20240315001700263

所以尝试进行爆破,对程序进行patch,将[rsp+70h+var_50]处的内容传递给rcx,然后再打印出来

要使得字符让程序返回0xFFh

在file–>script command里面添加脚本

image-20240315004344982

等待……

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import subprocess
real_flag="hgame{" #绝对正确的前6个字符
cur_index=6 #当前爆破的位置
while cur_index<32:
for i in range(32,128): #当前爆破的位置上的字符
real_flag_arr = [0] * 32

for j in range(len(real_flag)): #正确的先复制一下
real_flag_arr[j]=ord(real_flag[j])
real_flag_arr[len(real_flag_arr)-1]=ord("}") #最后一个字符"}"固定

for j in range(len(real_flag_arr)-2,cur_index,-1): #除了当前爆破的位置,其他位置 上都设置为32(空格)
real_flag_arr[j]=32

real_flag_arr[cur_index]=i #设置当前爆破的位置上的字符
real_flag_arr_s="".join(chr(k) for k in real_flag_arr) #输入到程序中的字符串
#下方路径填写自己的
p = subprocess.Popen(["G:\\A\\hgame\\2022\week4\\hardasm.exe], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write(real_flag_arr_s.encode())
p.stdin.close()
out = p.stdout.read()

if len(out)>cur_index: #判断程序打印出的0xFF的个数是否增加,增加则说明当前爆破的位置 上的字符设置的是正确的
real_flag+=chr(i)
cur_index+=1
print(real_flag)
break

hgame{right_your_asm_is_good!!}

shellcode

打开找到main_main函数,进入

image-20240315024638054

通过分析这段代码,发现主要功能——从指定目录中读取文件列表,对特定的字符串进行Base64解码操作,然后将解码后的结果存储到新文件中。

关键步骤:

  1. 使用 io_ioutil_ReadDir 函数从 “inputdir” 目录中读取文件列表,并将结果存储在变量 Dir 中。
  2. 对特定的字符串进行 Base64 解码操作,结果存储在变量 v81 中。
  3. 调用 main_VirtualAlloc 函数分配内存,并将解码后的字符串拷贝到新分配的内存中。
  4. 使用 main_RtlMoveMemory 函数将数据从一个地址复制到另一个地址。
  5. 循环遍历Dir中的文件列表,依次读取每个文件内容,并进行处理:
    • 构造输入文件路径,使用 os_ReadFile 读取文件内容。
    • 将文件内容拷贝到新的字节切片中,并执行一系列操作。
    • 将处理后的数据写入到输出文件中。
  6. 最后通过循环控制,实现对文件列表的遍历和处理,直到处理完所有文件或达到指定条件退出循环。

开始做题

先在这几个关键地方下断点,然后开始动调,发现没有输入环节

image-20240315034111606

这个地方表示对字符串进行base64的解密,且字符串长度为284字节,双击进入获取进行解密的字符串数据,得到

image-20240315034227633

注意还有下面的那一部分

image-20240315034440961

获取得到数据:

VUiD7FBIjWwkIEiJTUBIi0VAiwCJRQC4BAAAAEgDRUCLAIlFBMdFCAAAAADHRQwj782rx0UQFgAAAMdFFCEAAADHRRgsAAAAx0UcNwAAAMdFIAAAAACLRSCD+CBzWotFDANFCIlFCItFBMHgBANFEItVCANVBDPCi1UEweoFA1UUM8IDRQCJRQCLRQDB4AQDRRiLVQgDVQAzwotVAMHqBQNVHDPCA0UEiUUEuAEAAAADRSCJRSDrnkiLRUCLVQCJELgEAAAASANFQItVBIkQSI1lMF3D

然后在线解码好像不太行,选择使用脚本一键解密后直接写入文件

脚本:

import base64

with open(‘ans’, ‘wb’) as f:
f.write(base64.b64decode(‘VUiD7FBIjWwkIEiJTUBIi0VAiwCJRQC4BAAAAEgDRUCLAIlFBMdFC AAAAADHRQwj782rx0UQFgAAAMdFFCEAAADHRRgsAAAAx0UcNwAAAMdFIAAAAACLRSCD+CBzWotFDANFCIlFCItFBMHgBANFEItVCANVBDPCi1UEweoFA1UUM8IDRQCJRQCLRQDB4AQDRRiLVQgDVQAzwotVAMHqBQNVHDPCA0UEiUUEuAEAAAADRSCJRSDrnkiLRUCLVQCJELgEAAAASANFQItVBIkQSI1lMF3D’))

将脚本运行得到生成的文件,将文件拖入IDA

image-20240315133800774

p创建函数然后F5,得到加密逻辑

image-20240315133925625

发现一个规整的tea加密

由下图可知enc文件时加密后的数据

image-20240315134520317

用winhex打开flag.enc

image-20240315135048319

得到数据

\x20\x69\xB3\xE4\xD0\x24\x69\x93\x44\xD1\x16\xA8\xF5\xD5\x82\xAA\xDA\xF0\x79\x36\x06\xFD\x32\x7F\xD3\xC0\x60\x34\x39\x49\x21\xB7\xA2\x69\x72\xE5\xFA\x51\x6A\x83

exp:

#include <stdio.h>
#include <stdint.h>
void decrypt(uint32_t* v, int32_t* k) {
uint32_t v0 = v[0], v1 = v[1], i;
int32_t sum = 0xABCDEF23 * 32;
uint32_t delta = 0xABCDEF23;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i<32; i++) {
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
v[0] = v0; v[1] = v1;
}
int main(){
uint32_t key[4] = {22,33,44,55};
uint32_t enc[10] = {0xE4B36920, 0x936924D0, 0xA816D144, 0xAA82D5F5, 0x3679F0DA, 0x7F32FD06, 0x3460C0D3, 0xB7214939,
0xE57269A2, 0x836A51FA};
for(int i = 0;i<9;i+=2){
decrypt(&enc[i],key);
}

char* p = enc;
for(int i = 0;i<40;i++){
    printf("%c",p[i]);

}

}

hgame{th1s_1s_th3_tutu’s_h0mew0rk}

vm

image-20240315181422964

根据判断,遇到0xFF停止

修改变量名

image-20240315181310675

提取出opcode

这个为vm的主要逻辑

image-20240315181608327

找到数据

image-20240315194950700

image-20240315195021438

分析所模拟的指令

image-20240315203804816

image-20240315203846356

image-20240315202307774

image-20240315203337842

image-20240315203414951

概览:

image-20240315204009120

使用脚本打印出符合条件的指令

opcode = [0x00, 0x03, 0x02, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x03, 0x02, 0x32,
0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
0x01, 0x00, 0x00, 0x03, 0x02, 0x64, 0x03, 0x00, 0x02, 0x03,
0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x01, 0x00, 0x00, 0x03,
0x00, 0x08, 0x00, 0x02, 0x02, 0x01, 0x03, 0x04, 0x01, 0x00,
0x03, 0x05, 0x02, 0x00, 0x03, 0x00, 0x01, 0x02, 0x00, 0x02,
0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00, 0x01, 0x03, 0x00,
0x03, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x01, 0x28,
0x04, 0x06, 0x5F, 0x05, 0x00, 0x00, 0x03, 0x03, 0x00, 0x02,
0x01, 0x00, 0x03, 0x02, 0x96, 0x03, 0x00, 0x02, 0x03, 0x00,
0x00, 0x00, 0x00, 0x04, 0x07, 0x88, 0x00, 0x03, 0x00, 0x01,
0x03, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03,
0x01, 0x28, 0x04, 0x07, 0x63, 0xFF, 0xFF]
input1 = []
i = 0
while opcode[i] != 0xFF:
match opcode[i]:
case 0x00:
print(f’{i}’, end=’ ‘)
o = i + 1
if opcode[o]:
match opcode[o]:
case 0x01:
print(“mov input[reg[2]], reg[0]”)
case 0x02:
print(“mov reg[%d], reg[%d]” % (opcode[i+2],opcode[i+3]))
case 0x03:
print(“mov reg[%d], %d” % (opcode[i+2], opcode[i+3]))
else:
print(“mov reg[0], input[reg[2]]”)
i += 4
case 0x01:
print(f’{i}’, end=’ ‘)
o = i + 1
if opcode[o]:
match opcode[o]:
case 0x01:
print(“push reg[0]”)
case 0x02:
print(“push reg[2]”)
case 0x03:
print(“push reg[3]”)
else:
print(“push reg[0]”)
i += 2
case 0x02:
print(f’{i}’, end=’ ‘)
o = i + 1
if opcode[o]:
match opcode[o]:
case 0x01:
print(“pop reg[1]”)
case 0x02:
print(“pop reg[2]”)
case 0x03:
print(“pop reg[3]”)
else:
print(“pop reg[0]”)
i += 2
case 0x03:
print(f’{i}’, end=’ ‘)
o = i + 1
match opcode[o]:
case 0:
print(“add reg[%d],reg[%d]” % (opcode[i + 2], opcode[i + 3]))
case 1:
print(“sup reg[%d],reg[%d]” % (opcode[i + 2], opcode[i + 3]))
case 2:
print(“mul reg[%d],reg[%d]” % (opcode[i + 2], opcode[i + 3]))
case 3:
print(“xor reg[%d],reg[%d]” % (opcode[i + 2], opcode[i + 3]))
case 4:
print(“shl reg[%d],reg[%d]” % (opcode[i + 2], opcode[i + 3]))
case 5:
print(“shr reg[%d],reg[%d]” % (opcode[i + 2], opcode[i + 3]))
i += 4
case 0x04:
print(f’{i} cmp reg[0], reg[1]’)
i += 1
case 0x05:
print(f’{i} jmp %d ‘ % (opcode[i+1]))
i += 2
case 0x06:
print(f’{i} je %d ‘ % (opcode[i+1]))
i += 2
case 0x07:
print(f’{i} jne %d ‘ % (opcode[i+1]))
i += 2

得到汇编结果

mov reg[2],0

add reg[2],reg[3]

mov reg[0],data[reg[2]]

mov reg[1],reg[0]

mov reg[2],50

add reg[2],reg[3]

mov reg[0],data[reg[2]]

add reg[1],reg[0]

mov reg[2],100

add reg[2],reg[3]

mov reg[0],data[reg[2]]

xor reg[1],reg[0]

mov reg[0],8

mov reg[2],reg[1]

shl reg[1],reg[0]

shr reg[2],reg[0]

add reg[1],reg[2]

mov reg[0],reg[1]

push reg[0]

mov reg[0],1

add reg[3],reg[0]

mov reg[0],reg[3]

mov reg[1],40

cmp reg[0],reg[1]

jne 95

jmp 0

mov reg[3],0

pop reg[0]

mov reg[2],150

add reg[2],reg[3]

mov reg[0],data[reg[2]]

cmp reg[0],reg[1]

je 136

mov reg[0],1

add reg[3],reg[0]

mov reg[0],reg[3]

mov reg[1],40

cmp reg[0],reg[1]

je 99

然后再读取汇编将汇编代码转换成反汇编

a = [0x9b, 0xa8, 0x2, 0xbc, 0xac, 0x9c, 0xce, 0xfa, 0x2, 0xb9, 0xff, 0x3a, 0x74, 0x48, 0x19, 0x69, 0xe8, 0x3, 0xcb,
0xc9, 0xff, 0xfc, 0x80, 0xd6, 0x8d, 0xd7, 0x72, 0x0, 0xa7, 0x1d, 0x3d, 0x99, 0x88, 0x99, 0xbf, 0xe8, 0x96, 0x2e,
0x5d, 0x57, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
b = [0xc9, 0xa9, 0xbd, 0x8b, 0x17, 0xc2, 0x6e, 0xf8, 0xf5, 0x6e, 0x63, 0x63, 0xd5, 0x46, 0x5d, 0x16, 0x98, 0x38, 0x30,
0x73, 0x38, 0xc1, 0x5e, 0xed, 0xb0, 0x29, 0x5a, 0x18, 0x40, 0xa7, 0xfd, 0xa, 0x1e, 0x78, 0x8b, 0x62, 0xdb, 0xf,
0x8f, 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
c = [0x4800, 0xf100, 0x4000, 0x2100, 0x3501, 0x6400, 0x7801, 0xf900, 0x1801, 0x5200, 0x2500, 0x5d01, 0x4700, 0xfd00,
0x6901, 0x5c00, 0xaf01, 0xb200, 0xec01, 0x5201, 0x4f01, 0x1a01, 0x5000, 0x8501, 0xcd00, 0x2300, 0xf800, 0xc00,
0xcf00, 0x3d01, 0x4501, 0x8200, 0xd201, 0x2901, 0xd501, 0x601, 0xa201, 0xde00, 0xa601, 0xca01, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
flag = ‘0123456789012345678901234567890123456789’
res = [0 for i in range(40)]
for i in range(40): x = a[i] + ord(flag[i])
y = x ^ b[i]
z = (y << 8) & 0xff00
m = y >> 8
n = z + m

最后,逆回去就行了……

a = [0x9b, 0xa8, 0x2, 0xbc, 0xac, 0x9c, 0xce, 0xfa, 0x2, 0xb9, 0xff, 0x3a, 0x74, 0x48, 0x19, 0x69, 0xe8, 0x3, 0xcb,
0xc9, 0xff, 0xfc, 0x80, 0xd6, 0x8d, 0xd7, 0x72, 0x0, 0xa7, 0x1d, 0x3d, 0x99, 0x88, 0x99, 0xbf, 0xe8, 0x96, 0x2e,
0x5d, 0x57]
b = [0xc9, 0xa9, 0xbd, 0x8b, 0x17, 0xc2, 0x6e, 0xf8, 0xf5, 0x6e, 0x63, 0x63, 0xd5, 0x46, 0x5d, 0x16, 0x98, 0x38, 0x30,
0x73, 0x38, 0xc1, 0x5e, 0xed, 0xb0, 0x29, 0x5a, 0x18, 0x40, 0xa7, 0xfd, 0xa, 0x1e, 0x78, 0x8b, 0x62, 0xdb, 0xf,
0x8f, 0x9c]
c = [0x4800, 0xf100, 0x4000, 0x2100, 0x3501, 0x6400, 0x7801, 0xf900, 0x1801, 0x5200, 0x2500, 0x5d01, 0x4700, 0xfd00,
0x6901, 0x5c00, 0xaf01, 0xb200, 0xec01, 0x5201, 0x4f01, 0x1a01, 0x5000, 0x8501, 0xcd00, 0x2300, 0xf800, 0xc00,
0xcf00, 0x3d01, 0x4501, 0x8200, 0xd201, 0x2901, 0xd501, 0x601, 0xa201, 0xde00, 0xa601, 0xca01]
c = [i for i in reversed(c)]
flag = ‘’
for i in range(40):
m = c[i] >> 8
n = (c[i] & 0xff) << 8
y = m + n
y = y ^ b[i]
y = y - a[i]
flag += chr(y)
print(flag)

hgame{y0ur_rever5e_sk1ll_i5_very_g0od!!}

hgame week4 re wp

change

点开进入程序可以发现主要逻辑集中在中间那块

image-20240308145909632

exp:

cmp=[0x13, 0x0A, 0x5D, 0x1C, 0x0E, 0x08, 0x23, 0x06, 0x0B, 0x4B,
0x38, 0x22, 0x0D, 0x1C, 0x48, 0x0C, 0x66, 0x15, 0x48, 0x1B,
0x0D, 0x0E, 0x10, 0x4F]
s=’am2qasl’
flag=’’
for i in range(len(cmp)):
if i%2:
flag+=chr(cmp[i]^ord(s[i%len(s)]))
else:
flag+=chr((cmp[i]-10)^ord(s[i%len(s)]))
print(flag)

1
hgame{ugly_Cpp_and_hook}

again

首先使用pyinstxtractor把bin1.exe进行解包

image-20240308221703585

在首个文件夹中找到pyc文件,并且使用命令.\pycdc 文件名进行反编译(注意不是./)

image-20240308221738225

image-20240308221944948

image-20240308223550141

上面两个不太行

直接pycdas查看字节码

image-20240308225358872

得到字节码如下:

D:\题目\hgame\again!\bin1.exe_extracted>pycdas.exe bin1.pyc
bin1.pyc (Python 3.12) //文件信息
[Code] //Code对象信息
File Name: bin1.py
Object Name:
Qualified Name:
Arg Count: 0
Pos Only Arg Count: 0
KW Only Arg Count: 0
Stack Size: 10
Flags: 0x00000000
[Names] //Names 包含了代码中使用到的变量名和模块名,例如:’hashlib’, ‘print’, ‘bytearray’ 等
‘hashlib’
‘print’
‘bytearray’
‘s’
‘open’
‘read’
‘f’
‘t’
‘range’
‘i’
‘ord’
‘len’
‘append’
‘md5’
‘bytes’
‘hexdigest’
‘md5_hash’
[Locals+Names] //Locals+Names提供具体的本地变量信息
[Constants] //Constants包含了代码中使用到的常量例如整数、字符串,一些常量示例
0
None
‘you should use this execute file to decrypt “bin2”‘
‘hint:md5’
‘bin1.pyc’
‘rb’
‘jkasnwojasd’
15
6
256
[Disassembly]
0 RESUME 0
2 LOAD_CONST 0: 0
4 LOAD_CONST 1: None
6 IMPORT_NAME 0: hashlib
8 STORE_NAME 0: hashlib
10 PUSH_NULL
12 LOAD_NAME 1: print
14 LOAD_CONST 2: ‘you should use this execute file to decrypt “bin2”‘
16
20 CALL 1
30 POP_TOP
32 PUSH_NULL
34 LOAD_NAME 1: print
36 LOAD_CONST 3: ‘hint:md5’
38
42 CALL 1
52 POP_TOP
54 PUSH_NULL
56 LOAD_NAME 2: bytearray
58
62 CALL 0
72 STORE_NAME 3: s
74 PUSH_NULL
76 LOAD_NAME 2: bytearray
78 PUSH_NULL
80 LOAD_NAME 4: open
82 LOAD_CONST 4: ‘bin1.pyc’
84 LOAD_CONST 5: ‘rb’
86
90 CALL 2
100
122
126 CALL 0
136
140 CALL 1
150 STORE_NAME 6: f
152 LOAD_CONST 6: ‘jkasnwojasd’
154 STORE_NAME 7: t
156 PUSH_NULL
158 LOAD_NAME 8: range
160 LOAD_CONST 0: 0
162 LOAD_CONST 7: 15
164
168 CALL 2
178 GET_ITER
180 FOR_ITER 106 (to 394)
182 STORE_NAME 9: i
184 LOAD_NAME 6: f
186 LOAD_NAME 9: i
188 BINARY_SUBSCR
198 LOAD_NAME 6: f
200 LOAD_NAME 9: i
202 LOAD_CONST 8: 6
204 BINARY_OP 6 (%)
208 BINARY_SUBSCR
218 BINARY_OP 0 (+)
222 PUSH_NULL
224 LOAD_NAME 10: ord
226 LOAD_NAME 7: t
228 LOAD_NAME 9: i
230 LOAD_CONST 8: 6
232 BINARY_OP 6 (%)
236 BINARY_SUBSCR
246
250 CALL 1
260 PUSH_NULL
262 LOAD_NAME 10: ord
264 LOAD_NAME 7: t
266 LOAD_NAME 9: i
268 PUSH_NULL
270 LOAD_NAME 11: len
272 LOAD_NAME 7: t
274
278 CALL 1
288 BINARY_OP 6 (%)
292 BINARY_SUBSCR
302
306 CALL 1
316 BINARY_OP 0 (+)
320 BINARY_OP 12 (^)
324 LOAD_CONST 9: 256
326 BINARY_OP 6 (%)
330 LOAD_NAME 6: f
332 LOAD_NAME 9: i
334 STORE_SUBSCR
338 LOAD_NAME 3: s
340
362 LOAD_NAME 6: f
364 LOAD_NAME 9: i
366 BINARY_SUBSCR
376
380 CALL 1
390 POP_TOP
392 JUMP_BACKWARD 107 (to 180)
394 PUSH_NULL
396 LOAD_NAME 1: print
398 LOAD_NAME 3: s
400
404 CALL 1
414 POP_TOP
416 PUSH_NULL
418 LOAD_NAME 0: hashlib
420 LOAD_ATTR 13: md5
430 PUSH_NULL
432 LOAD_NAME 14: bytes
434 LOAD_NAME 3: s
436
440 CALL 1
450
454 CALL 1
464
486
490 CALL 0
500 STORE_NAME 16: md5_hash
502 LOAD_CONST 1: None
504 RETURN_VALUE

手撕一下,写成py代码(把py文件和pyc放同一个路径下)

import hashlib
print(‘you should use this execute file to decrypt “bin2”‘)
print(‘hint:md5’)
s=bytearray()
f=bytearray(open(‘./bin1.pyc’,’rb’).read())
t=’jkasnwojasd’
for i in range(15):
f[i]=((f[i]+f[i%6]) ^ (ord(t[i%6])+ord(t[i%len(t)]))) % 256
s.append(f[i])
print(s)
md5_hash=hashlib.md5(bytes(s)).hexdigest()
print(md5_hash)

#a405b5d321e446459d8f9169d027bd92

(不知道为什么我用之前的Pyinstxtractor最后解包解出来的pyc最后得到的结果和wp不一样,于是又重新搞了一个Pyinstxtractor)

image-20240309001030771

image-20240309010601647

image-20240309000734521

用winhex打开bin2,搜索刚刚得到的字符串发现如上

因为文件不可执行,盲猜和文件数据进行异或,刚好在头部尝试进行异或以后发现MZ,exe标志,则印证了猜想

代码:

file=open(‘bin2’,’rb’).read() #读出来是b’xxxx’的形式
key1 = (“a405b5d321e446459d8f9169d027bd92”).encode() #key1进行encode后就是b’xxxx’
arr=[key1[i%len(key1)]^file[i] for i in range(len(file))]
open(‘bin2.exe’,’wb’).write(bytes(arr))
print(‘Done!’)

还是在同一路径下运行得到最终的exe

image-20240309004215171

直接使用IDA打开

image-20240309012538359

exp:

#include <stdio.h>
#include <stdint.h>
#include <stdio.h>
void decrypt1(uint32_t* v, uint32_t* k) {
uint32_t v5 = 0;
uint32_t data;
uint32_t z;
uint32_t z2;
uint32_t v7;
uint32_t y;
int v9;
int v19 = 12;
int i;
do {
v5 += 0x7937B99E;
v5 &= 0xffffffff;
} while (–v19);
v19 = 12;
y = v[0];
do
{
v7 = (v5 >> 2) & 3;
for (i = 7; i > 0; –i)
{
z = v[i - 1];
y = v[i] -= ((v5 ^ y) + (z ^ k[v7 ^ i & 3])) ^ (((16 * z) ^ (y >> 3)) + ((z >> 5) ^ (4 * y)));

    }

    z = v[7];
    y = v[0] -= (((v5 ^ y) + (z ^ k[v7 ^ i & 3])) ^ (((16 * z) ^ (y >> 3)) + ((z >> 5) ^ (4 * y))));

    v5 += 0x7937B99E;
    v5 &= 0xffffffff;
} while (--v19);

}

int main()
{
uint32_t key[4] = {
0x1234, 0x2341, 0x3412, 0x4123
};
uint32_t array[8] = { 0x506fb5c3, 0xb9358f45, 0xc91ae8c7, 0x3820e280, 0xd13aba83,
0x975cf554, 0x4352036b, 0x1cd20447 };
uint32_t temp[2] = { 0,0 };
int i = 0;
decrypt1(array, key);
for (int i = 0; i < 8; i++) {
printf(“0x%x,”, array[i]);
}

return 0;

}

hgame{btea_is_a_hard_encryption}

crackme2

image-20240310234147807

打开最开始是一个没有经过修改的base64换表题

在线解码

image-20240310234127150

发现不对

退回到main函数的界面,发现unwind

image-20240310234543687

发现异常

将上方的main函数u掉,然后对except函数按p创建函数然后反汇编

将NtQueryInformationProcess给nop掉,然后保存一下

得到下图

image-20240311005110312

该程序通过VirtualProtect将原来的base的地址的函数进行异或操作

即为SMC程序,在执行时进行自解密

在第二个virtualprotect函数处下断点进行动调(注意最后进入动调输入环节结束后需要手动按F9执行到断点所在位置处)

image-20240311012900407

然后F5即可得到反汇编代码,双击此时的Address,查看具体值,发现没有进行识别,手动全选然后c(force),再P创建函数可以得到下图反汇编代码

image-20240311225352833

image-20240311223657299

直接把上面条件一条一条搬下来使用z3求解

exp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
from z3 import *

a_0 = Int('a_0' )
a_1 = Int('a_1' )
a_2 = Int('a_2' )
a_3 = Int('a_3' )
a_4 = Int('a_4' )
a_5 = Int('a_5' )
a_6 = Int('a_6' )
a_7 = Int('a_7' )
a_8 = Int('a_8' )
a_9 = Int('a_9' )
a_10 = Int('a_10')
a_11 = Int('a_11')
a_12 = Int('a_12')
a_13 = Int('a_13')
a_14 = Int('a_14')
a_15 = Int('a_15')
a_16 = Int('a_16')
a_17 = Int('a_17')
a_18 = Int('a_18')
a_19 = Int('a_19')
a_20 = Int('a_20')
a_21 = Int('a_21')
a_22 = Int('a_22')
a_23 = Int('a_23')
a_24 = Int('a_24')
a_25 = Int('a_25')
a_26 = Int('a_26')
a_27 = Int('a_27')
a_28 = Int('a_28')
a_29 = Int('a_29')
a_30 = Int('a_30')
a_31 = Int('a_31')
v1 = a_25;
v2 = a_21;
v3 = a_31;
v4 = a_29;
v5 = a_0;
v6 = a_23;
v7 = a_8;
v8 = a_28;
v9 = a_12;
v10 = a_3;
v11 = a_2;
v19 = a_30;
v15 = a_18;
v16 = a_24;
v27 = a_11;
v17 = a_26;
v30 = a_14;
v40 = a_7;
v26 = a_20;
v37 = 2 * v26;
v42 = a_22;
v28 = a_1;
v25 = a_27;
v21 = a_19;
v23 = a_16;
v31 = a_13;
v29 = a_10;
v41 = a_5;
v24 = a_4;
v20 = a_15;
v39 = a_17;
v22 = a_6;
v18 = a_9;
s=Solver()

v37 = 2 * v26
s.add( v18 + 201 * v24 + 194 * v10 + 142 * v20 + 114 * v39 + 103 * v11 + 52 * (v17 + v31) + ((v9 + v23) * 64) + 14 * (v21 + 4 * v25 + v25) + 9 * (v40 + 23 * v27 + v2 + 3 * v1 + 4 * v2 + 4 * v6) + 5 * (v16 + 23 * v30 + 2 * (v3 + 2 * v19) + 5 * v5 + 39 * v15 + 51 * v4) + 24 * (v8 + 10 * v28 + 4 * (v42 + v7 + 2 * v26)) + 62 * v22 + 211 * v41 + 212 * v29 == 296473 )
v38 = 2 * v16
s.add( 207 * v41 + 195 * v22 + 151 * v40 + 57 * v5 + 118 * v6 + 222 * v42 + 103 * v7 + 181 * v8 + 229 * v9 + 142 * v31 + 51 * v29 + 122 * (v26 + v20) + 91 * (v2 + 2 * v16) + 107 * (v27 + v25) + 81 * (v17 + 2 * v18 + v18) + 45 * (v19 + 2 * (v11 + v24) + v11 + v24) + 4 * (3 * (v23 + a_19 + 2 * v23 + 5 * v4) + v39 + 29 * (v10 + v1) + 25 * v15) + 26 * v28 + 101 * v30 + 154 * v3 == 354358 )
s.add( 177 * v40 + 129 * v26 + 117 * v42 + 143 * v28 + 65 * v8 + 137 * v25 + 215 * v21 + 93 * v31 + 235 * v39 + 203 * v11 + 15 * (v7 + 17 * v30) + 2 * (v24 + 91 * v9 + 95 * v29 + 51 * v41 + 81 * v20 + 92 * v18 + 112 * (v10 + v6) + 32 * (v22 + 2 * (v1 + v23)) + 6 * (v2 + 14 * v16 + 19 * v15) + 83 * v5 + 53 * v4 + 123 * v19) + v17 + 175 * v27 + 183 * v3 == 448573 )
s.add( 113 * v19 + 74 * v3 + 238 * v6 + 140 * v2 + 214 * v26 + 242 * v8 + 160 * v21 + 136 * v23 + 209 * v9 + 220 * v31 + 50 * v24 + 125 * v10 + 175 * v20 + 23 * v39 + 137 * v22 + 149 * v18 + 83 * (v4 + 2 * v30) + 21 * (9 * v29 + v16) + 59 * (4 * v27 + v17) + 41 * (v1 + v41) + 13 * (v7 + 11 * (v40 + v15) + 6 * v42 + 4 * (v28 + 2 * v11) + v28 + 2 * v11 + 17 * v5) + 36 * v25 == 384306 )
s.add( 229 * v21 + 78 * v1 + v2 + v9 + 133 * v27 + 74 * v6 + 69 * v26 + 243 * v7 + 98 * v28 + 253 * v8 + 142 * v25 + 175 * v31 + 105 * v41 + 221 * v10 + 121 * v39 + 218 * (v19 + v29) + 199 * (v24 + v30) + 33 * (v40 + 7 * v17) + 4 * (27 * v20 + 50 * v11 + 45 * v18 + 19 * (v3 + v42) + v16 + 16 * v23 + 52 * v4) + 195 * v22 + 211 * v5 + 153 * v15 == 424240 )
s.add( 181 * v25 + 61 * v2 + 65 * v21 + 58 * v31 + 170 * v29 + 143 * v24 + 185 * v10 + 86 * v11 + 97 * v22 + 235 * (v23 + v27) + 3 * (53 * v41 + 74 * (v8 + v3) + 13 * (v42 + 6 * v9) + 11 * (v39 + 7 * v20) + 15 * (v18 + 4 * v17) + v7 + 35 * v1 + 29 * v15) + 4 * (57 * v6 + 18 * (v5 + v37) + v28 + 17 * v16 + 55 * v30) + 151 * v40 + 230 * v4 + 197 * v19 == 421974 )
v33 = 2 * v41
s.add( 209 * v21 + 249 * v30 + 195 * v2 + 219 * v25 + 201 * v39 + 85 * v18 + 213 * (v17 + v31) + 119 * (v11 + 2 * v41) + 29 * (8 * v24 + v40 + 4 * v27 + v27) + 2 * (v8 + 55 * (2 * v29 + v19) + 3 * (v10 + 39 * v9 + 2 * (v6 + 20 * v20) + 35 * v7) + 4 * (v5 + 31 * v42 + 28 * v3) + 26 * v28 + 46 * (v37 + v16) + 98 * v1) + 53 * v23 + 171 * v15 + 123 * v4 == 442074 )
v32 = 2 * v18
s.add( 162 * v19 + 74 * v5 + 28 * v27 + 243 * v42 + 123 * v28 + 73 * v8 + 166 * v23 + 94 * v24 + 113 * v11 + 193 * v22 + 122 * (v6 + 2 * v7) + 211 * (v10 + v25) + 21 * (v17 + 7 * v41) + 11 * (v4 + 23 * (v16 + v39) + 2 * (v40 + 5 * v30 + 2 * (2 * v18 + v29) + 2 * v18 + v29)) + 5 * (46 * v9 + 26 * v20 + 4 * (v31 + 2 * v21) + v15 + 27 * v2 + 10 * v1) + 36 * (v3 + 5 * v26) == 376007 )
v35 = v25 + v30
s.add( 63 * v19 + 143 * v5 + 250 * v6 + 136 * v2 + 214 * v40 + 62 * v26 + 221 * v42 + 226 * v7 + 171 * v28 + 178 * v8 + 244 * v23 + (v9 * 128) + 150 * v31 + 109 * v29 + 70 * v41 + 127 * v20 + 204 * v39 + 121 * v22 + 173 * v18 + 69 * (v25 + v30 + v27) + 74 * (v16 + 2 * v15 + v15) + 22 * (7 * v24 + v17 + 10 * v11) + 40 * (v1 + 4 * v21 + v21) + 81 * v10 + 94 * v4 + 84 * v3 == 411252 )
s.add( 229 * v15 + 121 * v4 + 28 * v30 + 206 * v16 + 145 * v27 + 41 * v1 + 247 * v6 + 118 * v26 + 241 * v28 + 79 * v8 + 102 * v25 + 124 * v23 + 65 * v9 + 68 * v31 + 239 * v17 + 148 * v24 + 245 * v39 + 115 * v11 + 163 * v22 + 137 * v18 + 53 * (v5 + 2 * v29) + 126 * (v40 + 2 * v10) + 38 * (v7 + v21 + 4 * v7 + 6 * v41) + 12 * (v2 + 16 * v42) + 109 * v20 + 232 * v3 + 47 * v19 == 435012 )
s.add( 209 * v21 + 233 * v40 + 93 * v1 + 241 * v2 + 137 * v8 + 249 * v17 + 188 * v29 + 86 * v24 + 246 * v10 + 149 * v20 + 99 * v11 + 37 * v22 + 219 * v18 + 17 * (v6 + 10 * v25) + 49 * (v5 + 3 * v3 + 4 * v28 + v28) + 5 * (16 * v39 + 11 * (v41 + 2 * v27 + v27) + 12 * v7 + v31 + 30 * v16 + 27 * v19) + 18 * (v23 + 2 * (v4 + v26 + 2 * v4) + v4 + v26 + 2 * v4) + 24 * v9 + 109 * v42 + 183 * v30 + 154 * v15 == 392484 )
v34 = 2 * v31
s.add( 155 * v15 + 247 * v40 + 157 * v28 + 119 * v23 + 161 * v17 + 133 * v20 + 85 * v22 + 229 * (v7 + v24) + 123 * (2 * v31 + v42) + 21 * (v41 + 12 * v30) + 55 * (v9 + v5 + v18 + 2 * v5) + 15 * (v3 + 16 * v10 + 9 * v21) + 2 * (v2 + 115 * v29 + 111 * v16 + 26 * v6 + 88 * v8 + 73 * v39 + 71 * v11 + 28 * (v26 + 2 * (v25 + 2 * v1)) + 51 * v27 + 99 * v4 + 125 * v19) == 437910 )
s.add( 220 * v3 + 200 * v4 + 139 * v15 + 33 * v5 + 212 * v30 + 191 * v16 + 30 * v27 + 233 * v1 + 246 * v6 + 89 * v2 + 252 * v40 + 223 * v42 + 19 * v25 + 141 * v21 + 163 * v9 + 185 * v17 + 136 * v31 + 46 * v24 + 109 * v10 + 217 * v39 + 75 * v22 + 157 * v18 + 125 * (v11 + v19) + 104 * (v33 + v20) + 43 * (v28 + 2 * v29 + v29) + 32 * (v8 + v7 + 2 * v8 + 2 * (v23 + v26)) == 421905 )
s.add( 211 * v24 + 63 * v15 + 176 * v5 + 169 * v16 + 129 * v27 + 146 * v40 + 111 * v26 + 68 * v42 + 39 * v25 + 188 * v23 + 130 * v9 + (v31 * 64) + 91 * v41 + 208 * v20 + 145 * v39 + 247 * v18 + 93 * (v22 + v17) + 71 * (v6 + 2 * v11) + 103 * (v8 + 2 * v30) + 6 * (v21 + 10 * v28 + 28 * v7 + 9 * v29 + 19 * v2 + 24 * v1 + 22 * v3) + 81 * v10 + 70 * v4 + 23 * v19 == 356282 )
v12 = v10 + 2 * (v31 + 4 * (v29 + v17)) + v31 + 4 * (v29 + v17)
s.add( 94 * v42 + 101 * v2 + 152 * v40 + 200 * v7 + 226 * v8 + 211 * v23 + 121 * v24 + 74 * v11 + 166 * v18 + ((v6 + 3 * v28) * 64) + 41 * (4 * v9 + v21) + 23 * (v39 + 11 * v41) + 7 * (v20 + 10 * v25 + 2 * v12 + v12) + 3 * (78 * v30 + 81 * v16 + 55 * v27 + 73 * v1 + 4 * v26 + v15 + 85 * v3 + 65 * v19) + 62 * v22 + 88 * v5 + 110 * v4 == 423091 )
s.add( 133 * v22 + 175 * v15 + 181 * v30 + 199 * v16 + 123 * v27 + 242 * v1 + 75 * v6 + 69 * v2 + 153 * v40 + 33 * v26 + 100 * v42 + 229 * v7 + 177 * v8 + 134 * v31 + 179 * v29 + 129 * v41 + 14 * v10 + 247 * v24 + 228 * v20 + 92 * v11 + 86 * (v9 + v32) + 94 * (v23 + v21) + 37 * (v17 + 4 * v3) + 79 * (v25 + 2 * v28) + 72 * v5 + 93 * v39 + 152 * v4 + 214 * v19 == 391869 )
s.add( 211 * v24 + 213 * v18 + 197 * v40 + 159 * v25 + 117 * v21 + 119 * v9 + 98 * v17 + 218 * v41 + 106 * v39 + 69 * v11 + 43 * (v2 + v29 + 2 * v2) + 116 * (v4 + v10 + v37) + 5 * (v42 + 9 * v23 + 35 * v20 + 37 * v31) + 11 * (v16 + 13 * v27 + 5 * v5 + 8 * v30) + 6 * (29 * v28 + 25 * v8 + 38 * v22 + v15 + 13 * v1 + 10 * v3) + 136 * v7 + 142 * v6 + 141 * v19 == 376566 )
s.add( 173 * v3 + 109 * v15 + 61 * v30 + 187 * v1 + 79 * v6 + 53 * v40 + 184 * v21 + 43 * v23 + 41 * v9 + 166 * v31 + 193 * v41 + 58 * v24 + 146 * v10 + (v20 * 64) + 89 * v39 + 121 * v11 + 5 * (v17 + 23 * v8) + 7 * (29 * v18 + v29 + 4 * v7) + 13 * (3 * v42 + v16 + 7 * v26 + 13 * v2) + 3 * (v4 + 83 * v5 + 51 * v27 + 33 * v22 + 8 * (v19 + 4 * v28) + 18 * v25) == 300934 )
v36 = 3 * v21
s.add( 78 * v1 + 131 * v5 + 185 * v16 + 250 * v40 + 90 * v26 + 129 * v42 + 255 * v28 + 206 * v8 + 239 * v25 + 150 * v10 + 253 * v39 + 104 * v22 + 58 * (v2 + 2 * v7) + 96 * (v15 + v31) + 117 * (v9 + 2 * v4) + 27 * (v17 + 8 * v18 + v18) + 19 * (v23 + 3 * v21 + 4 * v29 + v29) + 7 * (22 * v41 + 3 * (v11 + 11 * v24) + v3 + 29 * v6 + 14 * v27) + 109 * v20 + 102 * v30 + 100 * v19 == 401351 )
s.add( 233 * v19 + 71 * v5 + 209 * v27 + 82 * v6 + 58 * v26 + 53 * v25 + 113 * v23 + 206 * v31 + 39 * v41 + 163 * v20 + 222 * v11 + 191 * v18 + 123 * (v7 + v40) + 69 * (v9 + 2 * v22 + v22) + 9 * (v3 + 8 * v24 + 7 * (3 * v1 + v28) + 5 * v16 + 19 * v30) + 4 * (v15 + 26 * v17 + 61 * v29 + 43 * v42 + 49 * v2 + 32 * v4) + 10 * (7 * (v8 + v36) + v39 + 12 * v10) == 368427 )
s.add( 139 * v30 + 53 * v5 + 158 * v16 + 225 * v1 + 119 * v6 + 67 * v2 + 213 * v40 + 188 * v28 + 152 * v8 + 187 * v21 + 129 * v23 + 54 * v9 + 125 * v17 + 170 * v24 + 184 * v11 + 226 * v22 + 253 * v18 + 26 * (v29 + v41) + 97 * (v4 + 2 * v25) + 39 * (5 * v26 + v27) + 21 * (v39 + 8 * v42) + 12 * (17 * v10 + v31 + 15 * v7 + 12 * v19) + 165 * v20 + 88 * v15 + 157 * v3 == 403881 )
s.add( 114 * v3 + 61 * v27 + 134 * v40 + 62 * v42 + 89 * v9 + 211 * v17 + 163 * v41 + 66 * v24 + 201 * (v7 + v18) + 47 * (5 * v16 + v22) + 74 * (v4 + v31) + 142 * (v2 + v28) + 35 * (v20 + 6 * v26) + 39 * (v15 + 6 * v30) + 27 * (v25 + 9 * v23 + 8 * v6) + 4 * (v21 + 63 * v19 + 2 * (v1 + 12 * (v10 + v5) + 8 * v11 + 26 * v29)) + 10 * (v8 + 4 * v39 + v39) == 382979 )
s.add( 122 * v25 + 225 * v21 + 52 * v23 + 253 * v9 + 197 * v17 + 187 * v31 + 181 * v29 + 183 * v41 + 47 * v20 + 229 * v39 + 88 * v22 + 127 * (v10 + v32) + 37 * (v7 + 3 * v3) + ((v11 + 2 * v30 + v30) * 64) + 7 * (21 * v8 + v27 + 18 * (v4 + v1 + v38)) + 6 * (23 * v24 + v26 + 17 * v2 + 39 * v6) + 10 * (v5 + 11 * v28 + 21 * v42) + 149 * v19 + 165 * v40 + 121 * v15 == 435695 )
s.add( 165 * v20 + 223 * v4 + 249 * v5 + 199 * v1 + 135 * v2 + 133 * v26 + 254 * v42 + 111 * v7 + 189 * v28 + 221 * v25 + 115 * v21 + 186 * v9 + 79 * v41 + 217 * v24 + 122 * v11 + 38 * v18 + 109 * (v34 + v29) + 14 * (v8 + 17 * v40 + 8 * (v6 + v38)) + 4 * (11 * (5 * v30 + v39) + 6 * (v10 + 2 * v22) + v27 + 52 * v17 + 50 * v23) + 229 * v15 + 86 * v3 + 234 * v19 == 453748 )
s.add( 181 * v25 + 94 * v42 + 125 * v1 + 226 * v26 + 155 * v7 + 95 * v21 + 212 * v17 + 91 * v31 + 194 * v29 + 98 * v24 + 166 * v11 + 120 * v22 + 59 * v18 + 32 * (v9 + v8) + 158 * (v6 + v5) + 101 * (v41 + v19) + 63 * (v4 + 2 * v23) + 67 * (v28 + 2 * v20) + 11 * (v39 + 10 * v16 + 11 * v10) + 39 * (v30 + 4 * (v2 + v15)) + 233 * v40 + 56 * v27 + 225 * v3 == 358321 )
s.add( 229 * v21 + 135 * v4 + 197 * v15 + 118 * v5 + 143 * v16 + 134 * v6 + 204 * v40 + 173 * v26 + 81 * v7 + 60 * v28 + 58 * v8 + 179 * v23 + 142 * v9 + 178 * v17 + 230 * v31 + 148 * v29 + 224 * v41 + 194 * v24 + 223 * v10 + 87 * v20 + 200 * v39 + 233 * v11 + 49 * v22 + 127 * v35 + 31 * (4 * v27 + v18) + 42 * (v1 + 6 * v2) + 109 * v42 + 75 * v3 + 165 * v19 == 456073 )
s.add( 41 * v4 + 253 * v3 + 163 * v15 + 193 * v30 + 155 * v16 + 113 * v27 + 131 * v6 + 55 * v2 + 21 * v40 + 53 * v26 + 13 * v8 + 201 * v25 + 237 * v9 + 223 * v31 + 95 * v24 + 194 * v20 + 62 * v39 + 119 * v11 + 171 * v22 + 135 * v18 + 69 * (v10 + 3 * v28) + 211 * (v1 + v29) + 4 * (43 * v7 + v42 + 40 * v17) + 6 * (v5 + 33 * v41 + 20 * (2 * v19 + v21) + 24 * v23) == 407135 )
v13 = v6 + v1 + 8 * v6 + 4 * (v8 + 2 * v27)
s.add( 111 * v19 + 190 * v3 + 149 * v4 + 173 * v28 + 118 * v23 + 146 * v29 + 179 * v10 + 51 * v20 + 49 * v39 + 61 * v11 + 125 * v22 + 162 * v18 + 214 * v35 + 14 * (v34 + v24) + 178 * (v41 + v16) + 11 * (4 * v9 + v21 + 17 * v42) + 65 * (v26 + v17 + 2 * v26 + 2 * v5) + 4 * (v7 + 38 * v15 + 4 * v13 + v13 + 8 * v40 + 43 * v2) == 369835 )
s.add( 27 * v27 + 223 * v6 + 147 * v26 + 13 * v21 + 35 * (v17 + 7 * v4) + 57 * (v19 + v32 + 3 * v11) + 11 * (v1 + 17 * (v9 + v5) + 10 * v16 + 3 * v31) + 2 * (53 * v23 + v25 + 38 * v15 + 43 * v42 + 115 * v29 + 61 * v22 + 111 * (v10 + v40) + 14 * (v20 + v7 + 2 * v7 + 8 * v28) + 109 * v2 + 100 * v41 + 63 * v8) + 93 * v39 + 251 * v30 + 131 * v3 == 393303 )
s.add( 116 * v9 + 152 * v29 + 235 * v20 + 202 * v18 + 85 * (v8 + 3 * v11) + 221 * (v16 + v40) + 125 * (v33 + v24) + 7 * (19 * v4 + 9 * (v10 + 2 * v25) + v2 + 33 * v3 + 32 * v19) + 3 * (71 * v39 + 43 * v22 + 32 * (v17 + v26) + 15 * (v5 + v6 + 2 * v23) + v28 + 74 * v31 + 48 * v42) + 10 * (v21 + 11 * v30 + 16 * v15) + 136 * v7 + 106 * v1 + 41 * v27 == 403661 )
s.add( 127 * v4 + 106 * v15 + 182 * v30 + 142 * v5 + 159 * v16 + 17 * v1 + 211 * v6 + 134 * v2 + 199 * v7 + 103 * v28 + 247 * v23 + 122 * v9 + 95 * v41 + 62 * v10 + 203 * v39 + 16 * v11 + 41 * (6 * v42 + v25) + 9 * (22 * v24 + v20 + 27 * v31 + 28 * v40) + 10 * (v8 + v22 + v36 + 8 * v17 + 2 * (v22 + v36 + 8 * v17) + 13 * v29) + 6 * (23 * v27 + v26) + 213 * v18 + 179 * v3 + 43 * v19 == 418596 )
s.add( 149 * v19 + v1 + 133 * v22 + 207 * v41 + 182 * v26 + 234 * v7 + 199 * v8 + 168 * v21 + 58 * v10 + 108 * v20 + 142 * v18 + 156 * (v9 + v25) + 16 * (v29 + 6 * v31) + 126 * (v17 + 2 * v39) + 127 * (v4 + 2 * v27 + v40) + 49 * (v30 + 4 * v16) + 11 * (v5 + 22 * v11) + 5 * (v15 + v42 + 45 * v24 + 50 * v28) + 109 * v2 + 124 * v6 + 123 * v3 == 418697 )


print(s.check())
m = s.model()
print(m)

hgame{SMC_4nd_s0lv1ng_equ4t1Ons}


hgame 2022-2024 week4 汇总
http://example.com/2024/03/24/hgame 2022-2024 week4 汇总/
作者
John Doe
发布于
2024年3月24日
许可协议