有点之前已经写过wp了,主要就写一下,该注意的点吧
xxor
主要考察的就是 XTEA
#include <stdio.h>
int main() {
__int64 a1[6];
a1[5] = 0x84F30420;
a1[1] = 0x20CAACF4;
__int64 a = 0x84A236FFLL, b = 0xFA6CB703LL, c = 0x42D731A8LL;
a1[2] = (a + b + c) / 2;
a1[3] = a1[2] - a;
a1[0] = 0xDF48EF7E;
a1[4] = a1[2] - c;
for (int i = 0; i < 6; i++) {
printf("%d ", a1[i]);
}
//__int64 a1[6] = { 3746099070, 550153460, 3774025685, 1548802262, 2652626477, 2230518816 };
int a2[4] = { 2,2,3,4 };
for (int j = 0; j <= 4; j += 2) {
int v5 = 1166789954 * 64;
unsigned int v3 = a1[j];
unsigned int v4 = a1[j + 1];
for (int i = 0; i <= 63; ++i)
{
v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
v5 -= 1166789954;
}
a1[j] = v3;
a1[j + 1] = v4;
}
for (int i = 0; i < 6; i++) {
printf("%x", a1[i]);
}
printf("\n");
for (int i = 0; i < 6; ++i) {
printf("%c%c%c", *((char*)&a1[i] + 2), *((char*)&a1[i] + 1), *((char*)&a1[i]));
}
return 0;
}
要注意密文是 __int64, delta 是 int ,中间 v3,v4是 unsigned int
还有就是十六进制打印成字符。
for (int i = 0; i < 6; ++i) {
printf("%c%c%c", *((char*)&a1[i] + 2), *((char*)&a1[i] + 1), *((char*)&a1[i]));
//取a1第三,二,一字节(从低到高)
}
端序这个东西真是不太好理解
[羊城杯 2020]easyre
就是简单的 base64,打乱顺序,还有凯撒加密
打乱顺序哪里写脚本,卡了半天 0.0
···
import base64
# enc='EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG'
# l1=len(enc)
# enc=list(map(ord,enc))
# cipher=[0]*l1
# for i in range(l1):
# tmp=enc[i]
# if 47<tmp<=57:
# enc[i]=(tmp-48-3)%10+48
# elif 64<tmp<=90:
# enc[i]=(tmp-65-3)%26+65
# elif 96<tmp<=122:
# enc[i]=(tmp-97-3)%26+97
# else:
# enc[i]=tmp
# for i in range(l1):
# print(chr(enc[i]),end='')
# print()
# # for i in range(13):
# # cipher.append(enc[13+i])
# # for i in range(13):
# # cipher.append(enc[39+i])
# # for i in range(13):
# # cipher.append(enc[i])
# # for i in range(13):
# # cipher.append(enc[39+i])
# cipher.extend(enc[13:26]) # 取enc的第14到第26个字符,共13个字符
# cipher.extend(enc[39:52]) # 取enc的第40到第52个字符,共13个字符
# cipher.extend(enc[0:13]) # 取enc的前13个字符
# cipher.extend(enc[39:52]) # 取enc的第40到第52个字符,共13个字符
# cipher_str = ''.join(map(chr, cipher))
# print(cipher_str)
# # hhh=''
# # for i in range(l1):
# # hhh+=chr(cipher[i])
# # print(hhh)
# enc='EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG'
# l1=len(enc)
# enc=list(map(ord, enc))
# cipher=[]
#
# # 解密过程
# for i in range(l1):
# tmp = enc[i]
# if 47 < tmp <= 57: # 数字 '0'-'9'
# enc[i] = (tmp - 48 - 3) % 10 + 48
# elif 64 < tmp <= 90: # 大写字母 'A'-'Z'
# enc[i] = (tmp - 65 - 3) % 26 + 65
# elif 96 < tmp <= 122: # 小写字母 'a'-'z'
# enc[i] = (tmp - 97 - 3) % 26 + 97
# else: # 其他字符保持不变
# enc[i] = tmp
#
# # 生成cipher列表
# cipher.extend(enc[13:26]) # 取enc的第14到第26个字符,共13个字符
# cipher.extend(enc[39:52]) # 取enc的第40到第52个字符,共13个字符
# cipher.extend(enc[0:13]) # 取enc的前13个字符
# cipher.extend(enc[39:52]) # 取enc的第40到第52个字符,共13个字符
#
# # 将cipher列表转换为字符串并输出
# cipher_str = ''.join(map(chr, cipher))
# print(cipher_str)
#
# flag=base64.b64decode(cipher_str)
# print(flag)
import base64
data='EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG'
data1=''
for i in data:
if ord(i)>=48 and ord(i)<=57:
data1 += chr((ord(i)-3-48)%10+48)
elif ord(i)>=65 and ord(i)<=90:
data1 += chr((ord(i)-3-65)%26+65)
elif ord(i)>=97 and ord(i)<=122:
data1 += chr((ord(i)-3-97)%26+97)
else:
data1 += i
# strncpy(a3, a1 + 26, 0xDui64);
# strncpy(a3 + 13, a1, 0xDui64);
# strncpy(a3 + 26, a1 + 39, 0xDui64);
# strncpy(a3 + 39, a1 + 13, 0xDui64);
flag = data1[13:26] + data1[39:] + data1[:13] + data1[26:39]
print(base64.b64decode(flag).decode('utf-8'))
受不了了
还有一个比较好理解的
int main(){
string flag = "BjYjM2Mjk4NzMR1dIVHs2NzJjY0MTEzM2VhMn0=zQ3NzhhMzhlOD";
string flag1 = "";
string flag2 = "";
string flag3 = "";
string flag4 = "";
int cn = 0;
for (int i = 13; i < 26; i++) {
flag1 += flag[i];
}
for (int i = 39; i < flag.size(); i++) {
flag2 += flag[i];
}
for (int i = 0; i < 13; i++) {
flag3 += flag[i];
}
for (int i = 26; i < 26+13; i++) {
flag4 += flag[i];
}
string ans = flag1+flag2+flag3+flag4;
cout << ans << endl;
return 0;
}
crackMe
还是忘记了
这个函数看似改变了 enc,但解密的时候没管,?
这个想到了可以通过动调来看
但确实改变了啊,0xA5–>0xD2 ?想不到了
动调把 S_Box 调出来,然后异或得到 password
还有一个问题就是 ida 和 dbg 调出来的值不一样?
最后写脚本:
data=[0x64,0x62,0x61,0x70,0x70,0x73,0x65,0x63]
print(''.join(list(map(chr,data))))
byte=[0x2A, 0xD7, 0x92, 0xE9, 0x53, 0xE2, 0xC4, 0xCD]
flag=[]
for i in range(len(data)):
flag.append(data[i]^byte[i])
for i in range(len(flag)):
print(hex(flag[i])[2:],end='')
# dbappsec
# 4eb5f3992391a1ae
[GUET-CTF2019]number_game
检查二维数组元素是否重复
那这怪多重复的啊
有几个函数中用到了递归
0.0
看了看 wp 大致明白了:
其实看到那个检查重复的就可以猜是数独了
那几个递归函数也是在给变量赋值
解完还不对,因为这是最后结果,是经过上面两个函数得到的,
而这两个函数是二叉树的遍历好像,还没学 0.0 先记着
[网鼎杯 2020 青龙组]jocker
要先修复,不能直接修smc,patch代码
选中call __Z7encryptPc这行指令,按alt+k,将新旧sp偏移值改成0;
call 是属于虚函数
通过ALT + P 来确认下变量起始地址,清除个数与保存个数是否正常(0.0)
上面那个看似正常的 call 也要改,然后再 f5 就没有报错了
然后解 smc
这个 jocker 真是,怎么说每次写都要遇到一些新问题,
我简单总结一下:
1,需要假flag过 wrong和omg函数
2,sp指针修复,要用到调用约定知识
3,smc修复,finally可能和encrypt连在一起,两个都被smc修改了
4,最后一部分flag,需要推测(猜)‘}’=c^x
也有在 smc 那里自解后 dump 出来,但我的太丑了,还是算了
[2019红帽杯]xx
撕,也是一道很令人头疼的题,代码也很长
看 wp 是知道了大致的流程,不过一些代码还是需要自己去理解,再看看。