这个比赛的人比较少,中间又有强网杯,作了5个小题
目录
题目
- from secret import flag
- from Crypto.Util.number import *
-
- seed = bytes_to_long(flag)
- bits = seed.bit_length()
-
- while True:
- p = getPrime(bits + 1)
- if p > seed:
- break
- print(p)
-
- a = getRandomRange(1, p)
- b = getRandomRange(1, p)
-
- for _ in range(3):
- seed = (a * seed + b) % p
- print(seed)
-
- # 31893593182018727625473530765941216190921866039118147474754069955393226712079257707838327486268599271803
- # 25820280412859586557218124484272275594433027771091486422152141535682739897353623931875432576083022273940
- # 24295465524789348024814588142969609603624462580932512051939198335014954252359986260009296537423802567677
- # 14963686422550871447791815183480974143372785034397446416396172429864269108509521776424254168481536292904
flag是第一个seed,然后每次用seed = (a*seed +b)%p得到下一个,可以用手工得到两个方程
- s3-s2 = a(s2-s1) mod p #求a
- s3 = a*s2 + b mod p #求b
得到a,b以后就能直接得到flag
- p = 31893593182018727625473530765941216190921866039118147474754069955393226712079257707838327486268599271803
- s1= 25820280412859586557218124484272275594433027771091486422152141535682739897353623931875432576083022273940
- s2= 24295465524789348024814588142969609603624462580932512051939198335014954252359986260009296537423802567677
- s3= 14963686422550871447791815183480974143372785034397446416396172429864269108509521776424254168481536292904
-
- from gmpy2 import *
- # s3-s2 = a(s2-s1) mod p
- t = invert(s2-s1, p)
- a = (t*(s3-s2))%p
- a = 25714049524051800625758372225598770398614533519595256157902456884372427008002817231382013589153912429484
-
- # s3 = a*s2 + b mod p
- b = (s3 - a*s2 )%p
- b = 10170297191068284996927402215696494489341479919496467043387273609973505047115652911086290426648313876559
- #s1 = a*s0 + b mod p
- a1 = invert(a,p)
- s0 = ((s1 - b)*a1 )%p
- s0 = 14337636555117933152506165016723944787939761429733562849369091223517166614830298165864272285381681301117
- bytes.fromhex(hex(s0)[2:])
- #flag{e4syRsa1snotdifficult5996642D0A7415EF}
- #e4syRsa1snotdifficult5996642D0A7415EF
题目程序
- # from flag import FLAG
- import random
- from PIL import Image
- from hashlib import md5
- from Crypto.Util.number import long_to_bytes as n2b
-
- FLAG = b'A'*28
-
- random.seed(793211)
-
-
- def pbl(bits):
- num = random.getrandbits(bits)
- bins = []
- while num:
- bins.append(num & 1)
- num >>= 1
- while len(bins) != bits:
- bins.append(0)
- return bins
-
-
- assert len(FLAG) == 28
- cat = Image.open('1.png')
- cat1 = Image.new('L', cat.size)
- cat2 = Image.new('L', cat.size)
- cat3 = Image.new('L', cat.size)
-
- x, y = cat.size
- bits = x * y
- r1, r2 = pbl(bits), pbl(bits)
- r3 = FLAG + n2b(random.getrandbits((bits - len(FLAG)) * 8))
- r3 = list(r3)
- random.shuffle(r3)
-
- for i in range(x):
- for j in range(y):
- pix = cat.getpixel((i, j))
- cat1.putpixel((i, j), pix[0] ^ r1[i * y + j])
- cat2.putpixel((i, j), pix[1] ^ r2[i * y + j])
- cat3.putpixel((i, j), pix[2] ^ r3[i * y + j])
-
- img = Image.new('RGB', cat.size)
-
-
- for p1, p3 in zip(cat1.getdata(), cat3.getdata()):
- print(p1, p3)
- break
- #img.putdata([(p1, 0, p3) for p1, p3 in zip(cat1.getdata(), cat3.getdata())])
- #img.save('xx.png')
附件给了两个图片,然后给定加密程序,可以看到 第2个图的B通道是第1个图片B通过与flag异或的结果,异或序列是一个随机数序列,seed已经给出,通过seed可以得到这个序列。
- import random
- from PIL import Image
- from hashlib import md5
- from Crypto.Util.number import long_to_bytes as n2b
-
- def pbl(bits):
- num = random.getrandbits(bits)
- bins = []
- while num:
- bins.append(num & 1)
- num >>= 1
- while len(bins) != bits:
- bins.append(0)
- return bins
-
-
- cat = Image.open('1.png')
- xx = Image.open('xx.png')
-
- x, y = cat.size
- bits = x * y
-
- r3 = [0]*bits
- for i in range(x):
- for j in range(y):
- pix = cat.getpixel((i, j))
- pxx = xx.getpixel((i, j))
- r3[i * y + j] = pix[2]^pxx[2]
-
- #print(r3)
-
- r_ord = [i for i in range(bits)]
- random.seed(793211)
- r1, r2 = pbl(bits), pbl(bits)
- random.getrandbits((bits - 28) * 8)
-
- random.shuffle(r_ord)
- #print(r_ord)
-
- flag = [0]*28
- for i in range(bits):
- if r_ord[i]<28:
- flag[r_ord[i]] = r3[i]
-
- print(bytes(flag))
- #flag{lovely_cat_with_random}
这个给了一个pyc的文件,无法反编译,先用dis打印出来可视字节码再手工翻译
- import marshal
- import dis
- import numpy as np
-
- def a1():
- code = open('whatisthis.cpython-38.pyc', 'rb').read()[16:]
-
- code = marshal.loads(code)
- dis.dis(code)
输出
- 2 0 LOAD_CONST 0 (0)
- 2 LOAD_CONST 1 (None)
- 4 IMPORT_NAME 0 (marshal)
- 6 STORE_NAME 0 (marshal)
- 8 LOAD_CONST 0 (0)
- 10 LOAD_CONST 1 (None)
- 12 IMPORT_NAME 1 (numpy)
- 14 STORE_NAME 2 (np)
- 16 LOAD_CONST 2 (235)
- 18 LOAD_CONST 3 (26)
- 20 LOAD_CONST 4 (15)
- 22 LOAD_CONST 5 (8)
- ...同上都是数据,此处略掉十万行...
- 259458 LOAD_CONST 19 (18)
- 259460 LOAD_CONST 123 (7)
- 259462 EXTENDED_ARG 1
- 259464 EXTENDED_ARG 506
- 259466 BUILD_LIST 129723
- 259468 STORE_NAME 3 (LKmDJNIyYcklUJMlklygvZUBQUjRuhRGVrWiKDrdMsRjAshBxlXysnzMLXrrIHpovIRyoQWZQjvPbolMpJBkxXFMJtrfuQmXoNUXPfHZwdAYdYwDkuGOtJZLcYUnzCnm)
-
- 4 259470 LOAD_CONST 133 ("Don't try to reverse this python script. You will be disappointed about it ")
- 259472 STORE_NAME 4 (SrvcwKKBZzolvVvpsMTzdEwhhsZYRBHaCjDkbjjaeTtrvMAYGjFHGGJofdCqlwsVlHZardbOZULepuWWTLSbZwjixarkVXPHOeMpPdArcybkUWoaMvoZrxGVzKPsUUAn)
-
- 5 259474 LOAD_CONST 134 ('475')
- 259476 STORE_NAME 5 (EPwKMzdvDfYeFVrZDDSRPDqULNPDfaOYUKVpGuxabUwVBfovYMvOjkRbvwTxzTpgUXJOKvlUFGGJbfEEvIlyQBdsCEoTcmMWEqLKTrMwWLdjVsYnfNJsXtRKefaSastz)
-
- 6 259478 LOAD_NAME 2 (np)
- 259480 LOAD_ATTR 6 (random)
- 259482 LOAD_METHOD 7 (seed)
- 259484 LOAD_NAME 2 (np)
- 259486 LOAD_METHOD 8 (sum)
- 259488 LOAD_CONST 135 (
object at 0x0000022FAE5EA6B0, file "/root/share/vm_share/³ö̢/notDefined/new/NotDefined_obfu.py", line 5>) - 259490 LOAD_CONST 136 ('
' ) - 259492 MAKE_FUNCTION 0
- 259494 LOAD_NAME 5 (EPwKMzdvDfYeFVrZDDSRPDqULNPDfaOYUKVpGuxabUwVBfovYMvOjkRbvwTxzTpgUXJOKvlUFGGJbfEEvIlyQBdsCEoTcmMWEqLKTrMwWLdjVsYnfNJsXtRKefaSastz)
- 259496 GET_ITER
- 259498 CALL_FUNCTION 1
- 259500 CALL_METHOD 1
- 259502 CALL_METHOD 1
- 259504 POP_TOP
-
- 7 259506 LOAD_NAME 9 (range)
- 259508 LOAD_NAME 10 (len)
- 259510 LOAD_NAME 3 (LKmDJNIyYcklUJMlklygvZUBQUjRuhRGVrWiKDrdMsRjAshBxlXysnzMLXrrIHpovIRyoQWZQjvPbolMpJBkxXFMJtrfuQmXoNUXPfHZwdAYdYwDkuGOtJZLcYUnzCnm)
- 259512 CALL_FUNCTION 1
- 259514 CALL_FUNCTION 1
- 259516 GET_ITER
- 259518 FOR_ITER 32 (to 259584)
- 259520 STORE_NAME 11 (EFAAANzoMBMeiWmpiPLHzCedWRoczlJwzpxHuBDPSWIlfFxpOqFiIZmWbvpOgrVNCsngbdYnwnxskvnFKLFfwMYNRmzfDisiWwXruLUffUyerjtrsmPoNzMUMpAatNWH)
-
- 8 259522 LOAD_NAME 3 (LKmDJNIyYcklUJMlklygvZUBQUjRuhRGVrWiKDrdMsRjAshBxlXysnzMLXrrIHpovIRyoQWZQjvPbolMpJBkxXFMJtrfuQmXoNUXPfHZwdAYdYwDkuGOtJZLcYUnzCnm)
- 259524 LOAD_NAME 11 (EFAAANzoMBMeiWmpiPLHzCedWRoczlJwzpxHuBDPSWIlfFxpOqFiIZmWbvpOgrVNCsngbdYnwnxskvnFKLFfwMYNRmzfDisiWwXruLUffUyerjtrsmPoNzMUMpAatNWH)
- 259526 DUP_TOP_TWO
- 259528 BINARY_SUBSCR
- 259530 LOAD_NAME 2 (np)
- 259532 LOAD_ATTR 6 (random)
- 259534 LOAD_METHOD 12 (randint)
- 259536 LOAD_CONST 137 (27)
- 259538 CALL_METHOD 1
- 259540 INPLACE_XOR
- 259542 ROT_THREE
- 259544 STORE_SUBSCR
- 259546 EXTENDED_ARG 3
- 259548 EXTENDED_ARG 1013
- 259550 JUMP_ABSOLUTE 259518 (to 519036)
- 259552 LOAD_NAME 13 (exec)
- 259554 LOAD_NAME 0 (marshal)
- 259556 LOAD_METHOD 14 (loads)
- 259558 LOAD_NAME 15 (bytearray)
- 259560 LOAD_NAME 3 (LKmDJNIyYcklUJMlklygvZUBQUjRuhRGVrWiKDrdMsRjAshBxlXysnzMLXrrIHpovIRyoQWZQjvPbolMpJBkxXFMJtrfuQmXoNUXPfHZwdAYdYwDkuGOtJZLcYUnzCnm)
- 259562 CALL_FUNCTION 1
- 259564 CALL_METHOD 1
- 259566 CALL_FUNCTION 1
- 259568 POP_TOP
- 259570 LOAD_CONST 1 (None)
- 259572 RETURN_VALUE
-
- Disassembly of
object at 0x0000022FAE5EA6B0, file "/root/share/vm_share/³ö̢/notDefined/new/NotDefined_obfu.py", line 5>: - 5 0 BUILD_LIST 0
- 2 LOAD_FAST 0 (.0)
- 4 FOR_ITER 12 (to 30)
- 6 STORE_FAST 1 (EFAAANzoMBMeiWmpiPLHzCedWRoczlJwzpxHuBDPSWIlfFxpOqFiIZmWbvpOgrVNCsngbdYnwnxskvnFKLFfwMYNRmzfDisiWwXruLUffUyerjtrsmPoNzMUMpAatNWH)
- >> 8 LOAD_GLOBAL 0 (ord)
- 10 LOAD_FAST 1 (EFAAANzoMBMeiWmpiPLHzCedWRoczlJwzpxHuBDPSWIlfFxpOqFiIZmWbvpOgrVNCsngbdYnwnxskvnFKLFfwMYNRmzfDisiWwXruLUffUyerjtrsmPoNzMUMpAatNWH)
- 12 CALL_FUNCTION 1
- 14 LIST_APPEND 2
- 16 JUMP_ABSOLUTE 4 (to 8)
- 18 RETURN_VALUE
手工翻译结果
- import marshal
- import numpy as np
-
- LKmD = [...]
- Srvc = "Don't try to reverse this python script. You will be disappointed about it "
- EPwK = '475'
-
- np.random.seed(np.sum([ord(i) for i in EPwK]))
-
- for EFAA in range(len(LKmD)):
- LKmD[EFAA] ^= np.random.randint(27)
- exec(marshal.loads(bytearray(LKmD)))
大意是前边那个数组与已知seed的随机序列异或得到一个串再执行,写函数处理一下,再用dis输出
- def a2():
- fp = open('aaa.txt')
- [fp.readline() for i in range(8)]
- v = [int(fp.readline().split('(')[1].split(')')[0]) for i in range(129723)]
-
- EPwK = '475'
- np.random.seed(np.sum([ord(i) for i in EPwK]))
-
- for i in range(len(v)):
- v[i] ^= np.random.randint(27)
-
- code = marshal.loads(bytes(v))
- dis.dis(code)
后边的结果就更简单了,就是直接给一个字符串的原码,然后执行,翻译后
- import marshal
-
- sv1 = [...略掉十成个数字...]
- def sv2(key):
- sv3 = list(range(256))
- sv4 = 0
- for sv5 in range(256):
- sv4 = (sv4 + sv3[sv5] + ord(key[sv5 % len(key)])) % 256
- sv3[sv5], sv3[sv4] = sv3[sv4], sv3[sv5]
- return sv3
- def sv6(p):
- sv7 = sv2('h0lyduck')
- sv8 = []
- sv5 = sv4 = 0
- for sv9 in p:
- sv5 = (sv5 + 1) % 256
- sv4 = (sv4 + sv7[sv5]) % 256
- sv7[sv5], sv7[sv4] = sv7[sv4], sv7[sv5]
- sva = (sv7[sv5] + sv7[sv4]) % 256
- svb = sv7[sva]
- sv8.append(sv9 ^ svb)
- return sv8
- #exec(marshal.loads(bytearray(sv6(sv1))))
-
- import dis
-
- code = marshal.loads(bytearray(sv6(sv1)))
- dis.dis(code)
第3得到都是直接的串,同样方法处理
- import marshal
- import struct
- from typing import List
- sv1 = [...略掉数据...]
- class sv2:
- def __init__(self, val: int):
- assert isinstance(val, int)
- self.val = val
- def __add__(self, other):
- return sv2((self.val + other.val) & 0xffffffff)
- def __xor__(self, other):
- return sv2(self.val ^ other.val)
- def __lshift__(self, nbit: int):
- sv3 = (self.val << nbit % 32) & 0xffffffff
- sv4 = (self.val & 0xffffffff) >> (32 - (nbit % 32))
- return sv2(sv3 | sv4)
- def __repr__(self):
- return hex(self.val)
- def __int__(self):
- return int(self.val)
- def sv5(sv6: sv2, b: sv2, sv7: sv2, d: sv2):
- sv6 += b
- d ^= sv6
- d <<= 16
- sv7 += d
- b ^= sv7
- b <<= 12
- sv6 += b
- d ^= sv6
- d <<= 8
- sv7 += d
- b ^= sv7
- b <<= 7
- return sv6, b, sv7, d
- def sv8(sv9: List[sv2], idx1, idx2, idx3, idx4):
- sv9[idx1], sv9[idx2], sv9[idx3], sv9[idx4] = \
- sv5(sv9[idx1], sv9[idx2], sv9[idx3], sv9[idx4])
- def sva(sv9: List[sv2]):
- sv8(sv9, 0, 4, 8, 12)
- sv8(sv9, 1, 5, 9, 13)
- sv8(sv9, 2, 6, 10, 14)
- sv8(sv9, 3, 7, 11, 15)
- sv8(sv9, 0, 5, 10, 15)
- sv8(sv9, 1, 6, 11, 12)
- sv8(sv9, 2, 7, 8, 13)
- sv8(sv9, 3, 4, 9, 14)
- return sv9
- def svb(sv9: List[sv2]) -> List[bytes]:
- return b''.join([struct.pack(', int(svc)) for svc in sv9])
- def svd(sve: bytes, svf: int, svg: bytes) -> bytes:
- svh = [sv2(svj) for svj in struct.unpack('
, b'expand 32-byte k')] - sve = [sv2(svj) for svj in struct.unpack('
, sve)] - svf = [sv2(svf)]
- svg = [sv2(svj) for svj in struct.unpack('
, svg)] - sv9 = svh + sve + svf + svg
- svk = sv9[:]
- for svm in range(10):
- sv9 = sva(sv9)
- sv9 = [svc + svn for svc, svn in zip(sv9, svk)]
- return svb(sv9)
- def svp(svj: bytes, y: bytes):
- return bytes(sv6 ^ b for sv6, b in zip(svj, y))
- def svq(sve: bytes, svf: int, svg: bytes, plaintext: bytes):
- sv7 = bytearray(0)
- for svr in range(len(plaintext) // 64):
- svs = svd(sve, svf + svr, svg)
- svt = plaintext[svr * 64:(svr + 1) * 64]
- sv7 += svp(svt, svs)
- if len(plaintext) % 64 != 0:
- svr = len(plaintext) // 64
- svs = svd(sve, svf + svr, svg)
- svt = plaintext[svr * 64:]
- sv7 += svp(svt, svs)
- return sv7
- sve = bytes.fromhex(
- '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f')
- svf = 0x00000001
- svg = bytes.fromhex('000000000000004a00000000')
- sv6 = svq(sve, svf, svg, bytearray(sv1))
- code = marshal.loads(sv6)
- import dis
- dis.dis(code)
-
最后一次得到的文件,可以看到flag
- 3 0 LOAD_CONST 0 (0)
- 2 LOAD_CONST 1 (None)
- 4 IMPORT_NAME 0 (builtins)
- 6 STORE_NAME 0 (builtins)
-
- 5 8 LOAD_CONST 2 ('flag{Wow_Y0o0U_@re_MaSt3r_0F_Not_d3f1neD}')
- 10 STORE_NAME 1 (flag)
-
- 19 12 LOAD_CONST 3 (
object enc at 0x000002567BCAD370, file "", line 5>) - 14 LOAD_CONST 4 ('enc')
- 16 MAKE_FUNCTION 0
- 18 STORE_NAME 2 (enc)
main里边直接调用加密程序,然后与密文核对
- int __cdecl main(int argc, const char **argv, const char **envp)
- {
- __int64 v3; // rcx
- __int64 v4; // rdx
- __int128 v6[2]; // [rsp+20h] [rbp-38h] BYREF
- char v7; // [rsp+40h] [rbp-18h]
-
- memset(v6, 0, sizeof(v6));
- v7 = 0;
- sub_140001020("I prefer TeaProPlus! can you give me this?\n");
- sub_140001020("TeaProPlus code:");
- sub_140001080("%32s", (const char *)v6);
- sub_1400010E0(v3, (unsigned int *)v6);
- v4 = 0i64;
- while ( *((_BYTE *)v6 + v4) == byte_1400032F0[v4] )
- {
- if ( (unsigned __int64)++v4 >= 0x20 )
- {
- sub_140001020("Oh yeah! Good code! flag{(your input)}\n");
- return 0;
- }
- }
- puts("oh NO!I want to drink TeaProPlus");
- return -1;
- }
加密程序是一个变种的tea
- __int64 __fastcall sub_1400010E0(__int64 a1, unsigned int *a2)
- {
- unsigned int v7; // r9d
- unsigned int key; // edi
- unsigned int v1; // ebp
- unsigned int v0; // esi
- unsigned int v2; // r14d
- unsigned int v3; // r15d
- unsigned int v4; // r12d
- unsigned int v5; // r13d
- _DWORD *key2; // r11
- _DWORD *v11; // r10
- __int64 v12; // rbx
- _DWORD *v13; // r9
- __int64 result; // rax
- bool v15; // zf
- unsigned int v6; // [rsp+40h] [rbp+8h]
- int round; // [rsp+48h] [rbp+10h]
- unsigned int v18; // [rsp+50h] [rbp+18h]
-
- v7 = a2[7];
- key = 0;
- v1 = a2[1];
- v0 = *a2;
- v2 = a2[2];
- v3 = a2[3];
- v4 = a2[4];
- v5 = a2[5];
- v6 = a2[6];
- v18 = v7;
- round = 12;
- do
- {
- key -= 0x61C88647;
- key2 = &key3[(key >> 2) & 3];
- v0 += ((key ^ v1) + (*key2 ^ v7)) ^ (((16 * v7) ^ (v1 >> 3)) + ((v7 >> 5) ^ (4 * v1)));
- *a2 = v0;
- v11 = &key3[(key >> 2) & 3 ^ 1i64];
- v1 += ((*v11 ^ v0) + (key ^ v2)) ^ (((16 * v0) ^ (v2 >> 3)) + ((v0 >> 5) ^ (4 * v2)));
- a2[1] = v1;
- v12 = (key >> 2) & 3 ^ 3i64;
- v13 = &key3[(key >> 2) & 3 ^ 2i64];
- v2 += ((key ^ v3) + (*v13 ^ v1)) ^ (((16 * v1) ^ (v3 >> 3)) + ((v1 >> 5) ^ (4 * v3)));
- a2[2] = v2;
- v3 += ((key ^ v4) + (key3[v12] ^ v2)) ^ (((16 * v2) ^ (v4 >> 3)) + ((v2 >> 5) ^ (4 * v4)));
- a2[3] = v3;
- v4 += ((key ^ v5) + (*key2 ^ v3)) ^ (((16 * v3) ^ (v5 >> 3)) + ((v3 >> 5) ^ (4 * v5)));
- a2[4] = v4;
- v5 += ((*v11 ^ v4) + (key ^ v6)) ^ (((16 * v4) ^ (v6 >> 3)) + ((v4 >> 5) ^ (4 * v6)));
- a2[5] = v5;
- LODWORD(key2) = (((key ^ v18) + (*v13 ^ v5)) ^ (((16 * v5) ^ (v18 >> 3)) + ((v5 >> 5) ^ (4 * v18)))) + v6;
- a2[6] = (unsigned int)key2;
- v6 = (unsigned int)key2;
- result = key ^ v0;
- v18 += (result + (key3[v12] ^ (unsigned int)key2)) ^ (((16 * (_DWORD)key2) ^ (v0 >> 3))
- + (((unsigned int)key2 >> 5) ^ (4 * v0)));
- v15 = round-- == 1;
- v7 = v18;
- a2[7] = v18;
- }
- while ( !v15 );
- return result;
- }
解密程序
- from pwn import u32,p32
-
- s = bytes.fromhex('473BBD10F9E05561C5EBF76A5F43238D0516091AEF403DD4676AB1B4A978356B')
- c = [0]*8
- for i in range(8):
- c[i] = u32(s[i*4: i*4+4])
-
- key = [0]*13
- k = 0
- for i in range(13):
- k = (k - 0x61C88647)%0x100000000
- key[i] = k
-
- key3 = [0x1234, 0x2345, 0x4567, 0x6789]
- for i in range(11, -1, -1):
- for j in range(7, -1, -1):
- p_next = (j+1)%8
- p_pre = (j-1)%8
- t = j%4
- c[j] = ( c[j] -
- ( ((key[i]^c[p_next]) + (key3[((key[i]>>2)&3) ^ t]^c[p_pre]) )
- ^ (((c[p_pre]<<4)^(c[p_next]>>3)) + ((c[p_pre]>>5)^(c[p_next]<<2)) ) )
- ) %0x100000000
- print(hex(key[i]))
-
- flag = b''
- for i in range(8):
- flag += p32(c[i])
-
- print(flag)
- #7f943921724d63dc0ac9c6febf99fa88
main里边啥都没有,发现有反调,调用了TlsCallback_0
- void __stdcall TlsCallback_0(int a1, DWORD flOldProtect, int a3)
- {
- int i; // eax
-
- if ( flOldProtect == 1 )
- {
- VirtualProtect(StartAddress, 0x320u, 0x40u, &flOldProtect);
- for ( i = 0; i < 0x320; ++i )
- *((_BYTE *)StartAddress + i) ^= i;
- CreateThread(0, 0, StartAddress, 0, 0, 0);
- }
- }
函数对程序块异或解密后起线程执行,先用程序给程序patch
- a1 = open('re2.exe', 'rb').read()
- a1 = list(a1)
- for i in range(800):
- a1[0x440 + i ] ^= i&0xff
-
- open('re_patch.exe', 'wb').write(bytes(a1))
然后用ida打开patch后的程序可以看到加密代码
- DWORD __stdcall StartAddress(LPVOID lpThreadParameter)
- {
- int k; // ebx
- int v4[65534]; // [esp+Ch] [ebp-50530h]
- char v5[66816]; // [esp+40004h] [ebp-10538h] BYREF
- int v6[6]; // [esp+50504h] [ebp-38h]
- char *v7; // [esp+5051Ch] [ebp-20h]
- int v8; // [esp+50520h] [ebp-1Ch]
- int v9; // [esp+50524h] [ebp-18h]
- int v10; // [esp+50528h] [ebp-14h]
- int v11; // [esp+5052Ch] [ebp-10h]
- int i; // [esp+50530h] [ebp-Ch]
- int v13; // [esp+50534h] [ebp-8h]
- int j; // [esp+50538h] [ebp-4h]
-
- while ( !dword_41B2E4 )
- Sleep(0x3E8u);
- for ( i = 0; i < 112; ++i )
- byte_41B30A += *((_BYTE *)&loc_401450 + i);
- for ( i = 0; byte_41B2EC[i]; ++i )
- byte_41B2EC[i] ^= byte_41B30A;
- v6[0] = 81;
- v6[1] = 102;
- v6[2] = 114;
- v6[3] = 111;
- v6[4] = 115;
- v6[5] = 116;
- for ( j = 0; j < 256; ++j )
- *(_DWORD *)&v5[4 * j + 0x10100] = j;
- for ( j = 0; j < 256; ++j )
- v5[j + 0x10000] = v6[j % 6]; // key
- v13 = 0;
- for ( j = 0; j < 256; ++j )
- {
- v13 = (v5[j + 0x10000] + *(_DWORD *)&v5[4 * j + 65792] + v13) % 256;
- v10 = *(_DWORD *)&v5[4 * j + 65792];
- *(_DWORD *)&v5[4 * j + 65792] = *(_DWORD *)&v5[4 * v13 + 65792];
- *(_DWORD *)&v5[4 * v13 + 65792] = v10;
- }
- v11 = dword_41B2E8;
- v9 = 0;
- v13 = 0;
- j = 0;
- while ( v11-- )
- {
- j = (j + 1) % 256;
- v13 = (*(_DWORD *)&v5[4 * j + 65792] + v13) % 256;
- v10 = *(_DWORD *)&v5[4 * j + 65792];
- *(_DWORD *)&v5[4 * j + 65792] = *(_DWORD *)&v5[4 * v13 + 65792];
- *(_DWORD *)&v5[4 * v13 + 65792] = v10;
- v8 = (*(_DWORD *)&v5[4 * v13 + 65792] + *(_DWORD *)&v5[4 * j + 65792]) % 256;
- v4[v9++] = *(_DWORD *)&v5[4 * v8 + 65792];
- }
- for ( j = 0; j < dword_41B2E8; ++j )
- v5[j] = LOBYTE(v4[j]) ^ byte_41B2EC[j];
- v7 = v5;
- for ( k = 0; k < dword_41B2E8; ++k )
- {
- if ( v7[k] != *(_BYTE *)(k + 0x401307) )
- {
- puts(0x401345);
- _loaddll(0);
- break;
- }
- }
- puts((int)"right\n");
- j___fgetchar();
- return 0;
- }
感觉好像叫RC4还是啥来着,先生成加密流,再与明文异或。反正对应写程序就行了
- a1 = open('re_patch.exe', 'rb').read()[0x707: 0x707+ 0x100]
-
- v6 = b'Qfrost'
- v51 = [i for i in range(256)]
- key = [v6[j%6] for j in range(256)]
- v13 = 0
- for j in range(256):
- v13 = (key[j] + v51[j] + v13) % 256
- v51[j], v51[v13] = v51[v13], v51[j]
-
- flen = 50
- v13 = 0
- v4 = [0]*flen
- j = 0
- for i in range(flen):
- j = (j+1)%256
- v13 = (v51[j] + v13)%256
- v51[j], v51[v13] = v51[v13], v51[j]
- v8 = (v51[j] + v51[v13])%256
- v4[i] = v51[v8]^a1[i]
-
- for i in range(256):
- tmp = bytes([i^v for v in v4])
- #if b'flag{' in tmp:
- print(tmp)
-
- #QDbg-Is_an_1ntereSting-Game!