名字提示的也很明确了,TEA算法,这里用的是xxtea算法
脚本
#include
#include
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
void btea(uint32_t *v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52 / n;
sum = 0;
z = v[n - 1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++)
{
y = v[p + 1];
z = v[p] += MX;
}
y = v[0];
z = v[n - 1] += MX;
} while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52 / n;
sum = rounds * DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--)
{
z = v[p - 1];
y = v[p] -= MX;
}
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
} while (--rounds);
}
}
int main()
{
uint32_t v[35] = {0xe74eb323,0xb7a72836,0x59ca6fe2,0x967cc5c1,0xe7802674,0x3d2d54e6,0x8a9d0356,0x99dcc39c,0x7026d8ed,0x6a33fdad,0xf496550a,0x5c9c6f9e,0x1be5d04c,0x6723ae17,0x5270a5c2,0xac42130a,0x84be67b2,0x705cc779,0x5c513d98,0xfb36da2d,0x22179645,0x5ce3529d,0xd189e1fb,0xe85bd489,0x73c8d11f,0x54b5c196,0xb67cb490,0x2117e4ca,0x9de3f994,0x2f5aa1aa,0xa7e801fd,0xc30d6eab,0x1baddc9c,0x3453b04a,0x92a406f9};
uint32_t const k[4] = {1,2,3,4};
int n = -35; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位;
btea(v, n, k);
for (int i = 0; i < 35; i++)
{
printf("%c", (char)v[i]);
}
return 0;
}
//hgame{l00ks_1ike_y0u_f0Und_th3_t34}
tmp=[0x97,0x99,0x9c,0x91,0x9e,0x81,0x91,0x9d,0x9b,0x9a,0x9a,0xab,0x81,0x97,0xae,0x80,0x83,0x8f,0x94,0x89,0x99,0x97]
flag=[]
n=0xff
for i in range(22):
flag.append(tmp[i]^n)
n=n-1
print(''.join(map(chr,flag)))
#hgame{hello_re_player}
python字节码,每个块是代表一行,强行译一手
raw_flag=input('give me your flag:\n')
cipher=list(raw_flag[6:-1])
length=len(cipher)
for i in range(length//2):
cipher[2*i+1],cipher[2*i]=cipher[2*i],cipher[2*i+1]
res=[]
for i in range(length):
res.append(ord(cipher[i])^i)
res=bytes(res).hex()
print('your flag: '+res)
逆向写出脚本即可
flag0='30466633346f59213b4139794520572b45514d61583151576638643a'
tmp=bytearray.fromhex(flag0)
length=len(tmp)
flag=[]
for i in range(length):
flag.append(tmp[i]^i)
for i in range(length//2):
flag[2*i+1],flag[2*i]=flag[2*i],flag[2*i+1]
print('hgame{'+''.join(map(chr,flag))+'}')
#hgame{G00dj0&_H3r3-I$Y@Ur_$L@G!~!~}
输入两部分password
password1:
xmm,所以逆序字符串
2b0c5e6a3a20b189
password2:
静态看基本可以确定,AES CBC模式,所以找Key和iv,iv可以找到memcpy(v14, &unk_40312C, *(size_t *)v46);
。Key的原理是
开启了一个新线程,共享内存,将输入的password1与0-f异或,得到Key。不过直接动调也可,CNG的加密方式BCryptGenerateSymmetricKey产生密钥,倒数第三个参数就是密钥
如何动调?此程序存在一个IsDebuggerPresent()反调,X32dbg有反调插件,直接过反调,但在实操过程中发现无法停到password2,也就是输入后下断停不下来,这点小疑惑。所以换IDA,先输入password1,然后IDA attach上去。
动调可得Key,逆序
2c2`1`0f;h8;n<66
常规思路找字符串,进而找到算法,这个分析一波发现是z3,z3脚本写了写,一直跑不出来,开始苦恼。后来init()中发现反调试,sub_406A11()中,取/proc/self/status
中的值, TracerPid的值非0判断为调试,进而SMC异或解密数据。写个idc脚本,模拟执行一下
#include
static main()
{
auto addr=0x00401216; //函数地址
auto addr2=0x00409080; //byte数组地址
auto i = 0;
for(i=0;i<=0x43E;i++)
{
PatchByte(addr+i,Byte(addr+i)^Byte(addr2+i));
}
}
ait+f7加载脚本,选中函数区域按C转代码,
z3脚本跑一下
from z3 import *
s=Solver()
a1=[0 for i in range(36)]
for i in range(36):
a1[i]=Int('a1['+str(i)+']')
v2=[0 for i in range(36)]
v1=[0 for i in range(36)]
v3=[0 for i in range(36)]
v2[0] = 55030
v2[1] = 61095
v2[2] = 60151
v2[3] = 57247
v2[4] = 56780
v2[5] = 55726
v2[6] = 46642
v2[7] = 52931
v2[8] = 53580
v2[9] = 50437
v2[10] = 50062
v2[11] = 44186
v2[12] = 44909
v2[13] = 46490
v2[14] = 46024
v2[15] = 44347
v2[16] = 43850
v2[17] = 44368
v2[18] = 54990
v2[19] = 61884
v2[20] = 61202
v2[21] = 58139
v2[22] = 57730
v2[23] = 54964
v2[24] = 48849
v2[25] = 51026
v2[26] = 49629
v2[27] = 48219
v2[28] = 47904
v2[29] = 50823
v2[30] = 46596
v2[31] = 50517
v2[32] = 48421
v2[33] = 46143
v2[34] = 46102
v2[35] = 46744
v1[0] = 104
v1[1] = 103
v1[2] = 97
v1[3] = 109
v1[4] = 101
v1[5] = 123
v1[6] = 64
v1[7] = 95
v1[8] = 70
v1[9] = 65
v1[10] = 75
v1[11] = 69
v1[12] = 95
v1[13] = 102
v1[14] = 108
v1[15] = 97
v1[16] = 103
v1[17] = 33
v1[18] = 45
v1[19] = 100
v1[20] = 111
v1[21] = 95
v1[22] = 89
v1[23] = 48
v1[24] = 117
v1[25] = 95
v1[26] = 107
v1[27] = 111
v1[28] = 110
v1[29] = 119
v1[30] = 95
v1[31] = 83
v1[32] = 77
v1[33] = 67
v1[34] = 63
v1[35] = 125
for i in range(6):
for j in range(6):
for k in range(6):
v3[6 * i + j] += v1[6 * k + j] * a1[6*i+k]
for x in range(6):
for y in range(6):
s.add(v3[6 * x + y] == v2[6 * x + y])
print(s.check())
print(s.model())
answer=s.model()
for i in range(36):
print(answer[a1[i]],end=' ')
跑出转字符串即可
hgame{E@sy_Se1f-Modifying_C0oodee33}
我运行不了,新本子计划启动中
这里记一下思路,通过调试信息搜字符串,找到关键变量,找引用发现是call+pop结构,病毒常用结构,nop掉,F5找到算法,取反+RC4
vm
在学了在学了