常规操作,先查一下
发现为C#语言写的,所以用dnspy查看
搜索Main
然后解释一下里面重要的一段代码
FileStream fileStream = File.OpenRead("gamemessage");
int num = (int)fileStream.Length;
Program.memory = new byte[num];
fileStream.Position = 0L;
fileStream.Read(Program.memory, 0, num);
这段C#代码首先打开名为"gamemessage"的文件,并获取该文件的长度,然后创建一个长度为该文件长度的字节数组Program.memory,并将文件的内容读取到该数组中。
所以我们重要看对memory的操作
第一处加密:
第二处加密:
key:
#include<stdio.h>
int main()
{
int key[] = { 66,
114,
97,
105,
110,
115,
116,
111,
114,
109,
105,
110,
103,
33,
33,
33 };
for (int j = 0; j < 16; j++)
{
printf("%c", key[j]);
}
}//Brainstorming!!!
处理一下:
生成一个文件名字改为download.dll
用010Editor打开
找到MZ头
删除前面无用部分
保存后在拉进dnspy
找到flag加密处,接下来就是看一看加密函数,将其解密
Check1
ParseKey
exp:
from z3 import * x = BitVec('x', 64) y = BitVec('y', 64) z = BitVec('z', 64) s = Solver() keystream = [101, 5, 80, 213, 163, 26, 59, 38, 19, 6, 173, 189, 198, 166, 140, 183, 42, 247, 223, 24, 106, 20, 145, 37, 24, 7, 22, 191, 110, 179, 227, 5, 62, 9, 13, 17, 65, 22, 37, 5] arr = [BitVec("arr[%d]" % i, 64) for i in range(len(keystream))] num = -1 for i in range(320): x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1) | x << 1) y = (((y >> 30 ^ y >> 27) & 1) | y << 1) z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1) | z << 1) flag = i % 8 == 0 if flag: num += 1 arr[num] = ((arr[num] << 1) | (((z >> 32 & 1 & (x >> 30 & 1)) ^ (((z >> 32 & 1) ^ 1) & ( y >> 31 & 1))) & 0xffffffff) & 0xff) for i in range(len(keystream)): s.add(keystream[i] == arr[i]) if s.check() == sat: model = s.model() print(model) y = 868387187 z = 3131229747 x = 156324965 L = [x, y, z] flag = [60, 100, 36, 86, 51, 251, 167, 108, 116, 245, 207, 223, 40, 103, 34, 62, 22, 251, 227] Key = [0] * 12 for i in range(3): for j in range(4): Key[i * 4 + j] = (L[i] >> j * 8 & 255) for j in range(len(flag)): print(chr(flag[j] ^ Key[j % len(Key)]), end='')Y0u_@re_G3meM3s7er!