[MiniLCTF 2024] Re
longlongcall
首先挂在linux下,IDA远程调试运行,发现Hack,退出了,搜字符串,找到后找x-ref
发现有两处,如下两张图,分别把这两处的上一层函数跳转改成强制的(不走hacker,过反调试)
然后重新打开运行发现就正常了,然后跟着走,来到了scanf("%44s", xx),意味着flag长度是44,接着走,发现他两个两个读取你输入的flag,然后加起来的值再分别和他俩进行异或以加密flag,最后再对flag进行对比,拿到里面加密后的flag后,可以通过暴力枚举来写出exp
ans = bytes.fromhex("BBBFB9BEC3CCCEDC9E8F9D9BA78CD795B0ADBDB488AF92D0CFA1A392B7B4C99E94A7AEF0A199C0E3B4B4BFE3")
def decrypt(a, b):
for i in range(0, 256):
for j in range(0, 256):
if a == (i+j)^i and b == (i+j)^j:
return (i, j)
for i in range(0, len(ans), 2):
b1, b2 = decrypt(ans[i],ans[i+1])
print(chr(b1)+chr(b2),end='')
# miniLCTF{just_s1mple_x0r_1n_lon9_l0ng_c@ll!}
补一个之后用z3写的wp
from z3 import *
ans = bytes.fromhex("BBBFB9BEC3CCCEDC9E8F9D9BA78CD795B0ADBDB488AF92D0CFA1A392B7B4C99E94A7AEF0A199C0E3B4B4BFE3")
sol = Solver()
v = [BitVec(f"v{i}", 8) for i in range(44)]
for i in range(0, 44, 2):
p = (v[i] + v[i+1])
v[i] = v[i] ^ p
v[i+1] = v[i+1] ^ p
for i in range(44):
sol.add(v[i] == ans[i])
print(sol.check())
m = sol.model()
result = [0] * 44
for p in m.decls():
# print(chr(m[v[i]].as_long()),end='')
result[int((p.name()[1:]))] = m[p].as_long()
print(list(map(chr, result)))
print("".join(map(chr, result)))
Bigbanana
从switch表中找到,F2 00 00 00这个后面跟着的,
稍微整理一下
再稍微分析一下
F4, 01 立即数加法
F3 两个异或
F2 checkAnswer 后面跟着应该的结果
FE 看是否播放banana
F0 好像是把上一次结果保存
10 getchar并推上栈
F8 push 栈[0]字符
F7 push 栈[1]字符
10 00 00 00 10 00 00 00 F8 00 00 00 F7 00 00 00
F4 00 00 00 4D 69 4E 69 栈[1]字符 ('m')
01 00 00 00 4C 2D 63 74 栈[0]字符 ('i')
F4 00 00 00 00 00 00 00
F3 00 00 00 栈上xor 000000001D2D440F
F2 00 00 00 0F 44 2D 1D check Answer
FE 00 00 00 66 00 00 00 banana
F0 00 00 00 ' 拿 栈[0]字符 ('i') + 结果 74632DB5
这里f8是74632DB5
10 00 00 00 F8 00 00 00 F4 00 00 00 16 00 00 00
01 00 00 00 21 00 00 00 ' 结果 000000000000008F
F4 00 00 00 14 45 11 00
F3 00 00 00
F2 00 00 00 50 72 74 74 FE 00 00 00
...
exp
flag = "mi"
f4List = [0x16,0x00114514,
0x21,0x00228A28,
0x2C,0x0033CF3C,
0x0B,0x00451450,
0x16,0x00565964,
0x21,0x00679E78,
0x2C,0x0078E38C,
0x0B,0x008A28A0,
0x16,0x009B6DB4,
0x21,0x00ACB2C8,
0x2C,0x00BDF7DC,
0x0B,0x00CF3CF0,
0x16,0x00E08204,
0x21,0x00F1C718,
0x2C,0x01030C2C,
0x0B,0x01145140,
0x16,0x01259654,
0x21,0x0136DB68,
0x2C,0x0148207C,
0x0B,0x01596590,
0x16,0x016AAAA4,
0x21,0x017BEFB8,
0x2C,0x018D34CC,
0x0B,0x019E79E0,
0x16,0x01AFBEF4,
0x21,0x01C10408,
0x2C,0x01D2491C,
0x0B,0x01E38E30,
0x16,0x01F4D344,
0x21,0x02061858,
0x2C,0x02175D6C,
0x0B,0x0228A280,
0x16,0x0239E794,
0x21,0x024B2CA8,
0x2C,0x025C71BC,
0x0B,0x026DB6D0,
0x16,0x027EFBE4,
0x21,0x029040F8,
0x2C,0x02A1860C,
0x0B,0x02B2CB20,
0x16,0x02C41034,
0x21,0x02D55548,
0x2C,0x02E69A5C]
f01List = [0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B]
ans = [0x74747250,0x00228A4D,0x0033CFAA,0x004514CB,0x00565966,0x00679FBC,0x0078E4CC,0x008A2949,0x009B6EC8,0x00ACB3E0,0x00BDF8F6,0x00CF3D22,0x00E082EB,0x00F1C745,0x01030C9C,0x0114518E,0x01259634,0x0136DC9C,0x0148217D,0x015965AE,0x016AABB8,0x017BF02F,0x018D352A,0x019E7AE7,0x01AFBF19,0x01C1043C,0x01D249A4,0x01E38E3E,0x01F4D3B0,0x02061853,0x02175E76,0x0228A241,0x0239E866,0x024B2D81,0x025C72F0,0x026DB738,0x027EFCFC,0x029041F1,0x02A186E7,0x02B2CBE3,0x02C4105D,0x02D55595,0x02E69A7B]
# 第一轮(因为读取了两个字符所以不好处理,直接拿第一轮结果)
ll = 0x74632DB5
for i in range(43):
succeed = False
for c in range(0,256):
aa = c
temp_ll = ll + f4List[i*2] + f4List[i*2+1]
aa += f01List[i]
if aa ^ temp_ll == ans[i]:
ll = aa
flag += chr(c)
print(i,flag)
succeed = True
break
if not succeed:
print("err",i)
'''
0 min
1 mini
2 miniL
3 miniLc
4 miniLct
5 miniLctf
6 miniLctf{
7 miniLctf{b
8 miniLctf{bi
9 miniLctf{big
10 miniLctf{bigb
11 miniLctf{bigb4
12 miniLctf{bigb4n
13 miniLctf{bigb4na
14 miniLctf{bigb4nan
15 miniLctf{bigb4nan4
16 miniLctf{bigb4nan4_
17 miniLctf{bigb4nan4_i
18 miniLctf{bigb4nan4_i5
19 miniLctf{bigb4nan4_i5_
20 miniLctf{bigb4nan4_i5_v
21 miniLctf{bigb4nan4_i5_v3
22 miniLctf{bigb4nan4_i5_v3r
23 miniLctf{bigb4nan4_i5_v3ry
24 miniLctf{bigb4nan4_i5_v3ry_
25 miniLctf{bigb4nan4_i5_v3ry_i
26 miniLctf{bigb4nan4_i5_v3ry_in
27 miniLctf{bigb4nan4_i5_v3ry_int
28 miniLctf{bigb4nan4_i5_v3ry_int3
29 miniLctf{bigb4nan4_i5_v3ry_int3r
30 miniLctf{bigb4nan4_i5_v3ry_int3r5
31 miniLctf{bigb4nan4_i5_v3ry_int3r5t
32 miniLctf{bigb4nan4_i5_v3ry_int3r5t1
33 miniLctf{bigb4nan4_i5_v3ry_int3r5t1n
34 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng
35 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng_
36 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng_r
37 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng_r1
38 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng_r1g
39 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng_r1gh
40 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng_r1ght
41 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng_r1ght?
42 miniLctf{bigb4nan4_i5_v3ry_int3r5t1ng_r1ght?}
补一个之后用z3写的exp
from z3 import *
flag = "mi"
f4List = [0x16,0x00114514,
0x21,0x00228A28,
0x2C,0x0033CF3C,
0x0B,0x00451450,
0x16,0x00565964,
0x21,0x00679E78,
0x2C,0x0078E38C,
0x0B,0x008A28A0,
0x16,0x009B6DB4,
0x21,0x00ACB2C8,
0x2C,0x00BDF7DC,
0x0B,0x00CF3CF0,
0x16,0x00E08204,
0x21,0x00F1C718,
0x2C,0x01030C2C,
0x0B,0x01145140,
0x16,0x01259654,
0x21,0x0136DB68,
0x2C,0x0148207C,
0x0B,0x01596590,
0x16,0x016AAAA4,
0x21,0x017BEFB8,
0x2C,0x018D34CC,
0x0B,0x019E79E0,
0x16,0x01AFBEF4,
0x21,0x01C10408,
0x2C,0x01D2491C,
0x0B,0x01E38E30,
0x16,0x01F4D344,
0x21,0x02061858,
0x2C,0x02175D6C,
0x0B,0x0228A280,
0x16,0x0239E794,
0x21,0x024B2CA8,
0x2C,0x025C71BC,
0x0B,0x026DB6D0,
0x16,0x027EFBE4,
0x21,0x029040F8,
0x2C,0x02A1860C,
0x0B,0x02B2CB20,
0x16,0x02C41034,
0x21,0x02D55548,
0x2C,0x02E69A5C]
f01List = [0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B,0x16,0x21,0x2C,0x0B]
ans = [0x74747250,0x00228A4D,0x0033CFAA,0x004514CB,0x00565966,0x00679FBC,0x0078E4CC,0x008A2949,0x009B6EC8,0x00ACB3E0,0x00BDF8F6,0x00CF3D22,0x00E082EB,0x00F1C745,0x01030C9C,0x0114518E,0x01259634,0x0136DC9C,0x0148217D,0x015965AE,0x016AABB8,0x017BF02F,0x018D352A,0x019E7AE7,0x01AFBF19,0x01C1043C,0x01D249A4,0x01E38E3E,0x01F4D3B0,0x02061853,0x02175E76,0x0228A241,0x0239E866,0x024B2D81,0x025C72F0,0x026DB738,0x027EFCFC,0x029041F1,0x02A186E7,0x02B2CBE3,0x02C4105D,0x02D55595,0x02E69A7B]
# 第一轮(因为读取了两个字符所以不好处理,直接拿第一轮结果)
s = Solver()
x = [BitVec(f"x{i}", 8) for i in range(43)]
ll = 0x74632DB5
for i in range(43):
succeed = False
aa = x[i]
temp_ll = ll + f4List[i*2] + f4List[i*2+1]
aa += f01List[i]
s.add(aa ^ temp_ll == ans[i])
ll = aa
s.add(x[i] < 0x7f)
s.add(x[i] > 0x20)
print(s.check())
m = s.model()
result = [0] * 43
for p in m:
result[int(p.name()[1:])] = m[p].as_long()
print("".join(map(chr, result)))
RustedRobot
首先拿到app,把libmyrust.so分离出来,拖入IDA64进行分析(我还用了IDARust Demangler插件来辅助我进行分析)。
首先花了一下午给Xiaomi13刷了KernelSU,学了个Frida,如下是Hook的Frida脚本,有时候正常hook,有时候hook不上(目前不知道什么原因)
function main(){
Java.perform(function() {
var CryptoClass = Java.use("com.doctor3.androidrusttest.CryptoClass");
console.log("Hooked CryptoClass\n");
CryptoClass.encrypt.overload('[Ljava.lang.String;').implementation = function(strArr) {
var str = strArr[0];
var str2 = strArr[1];
console.log("Encrypt method called with parameters: " + str + ", " + str2 + "\n");
// 调用原始方法
this.encrypt(strArr);
};
});
}
setImmediate(main);
随后IDA里面分析so,发现它创建了一个数组(长度2), 也就是对应Java代码里面的函数参数,然后在函数末尾进行了Java static method invoke。
public static void encrypt(String[] strArr) {
int i = 0;
String str = strArr[0];
String str2 = strArr[1];
byte[] bArr = {49, -93, 51, -59, 24, -5, -59, 60, -45, -32, -55, -54, -89, 67, 42, -94, 47, 110, 72, 13, 31, 55, 55, 34, 127, 65, -120, 13, -109, -92, -71, -97};
byte[] bytes = str.getBytes();
byte[] bytes2 = str2.getBytes();
SecretKeySpec secretKeySpec = new SecretKeySpec(bytes, AES);
try {
Cipher cipher = Cipher.getInstance(AES);
cipher.init(1, secretKeySpec);
byte[] doFinal = cipher.doFinal(bytes2);
while (i < 32) {
i = (bArr[i] == doFinal[i] && doFinal.length == 32) ? i + 1 : 0;
Toast.makeText(context, "Wrong", 1).show();
return;
}
Toast.makeText(context, "Right", 1).show();
} catch (Exception e) {
Toast.makeText(context, "Wrong", 1).show();
e.printStackTrace();
}
}
然后,使用Frida进行Hook,我们得知,第一个元素恒为定值,而第二个元素随着输入而改变(我不断更改miniLCTF{xxx}中的值,发现当miniLCTF{3}的时候,第二个字符是2,而且继续更改也之影响第二个字符,我就猜想这个字符很可能被反转了)。随后在CyberChef,先解密掉bArr,获取被混淆后的真正flag,我们得到
Encrypt method called with parameters: btdfA2jeeljf.1bp, ~2|GUDMjojn
flag,但是混淆后
~u1c1s`E4UTVS|GUDMjojn
随后就进行字符串反转,而后减一得到flag
于是我们可以得到exp:
https://gchq.github.io/CyberChef/#recipe=AES_Decrypt(%7B'option':'UTF8','string':'btdfA2jeeljf.1bp'%7D,%7B'option':'Hex','string':''%7D,'ECB/NoPadding','Hex','Raw',%7B'option':'Hex','string':''%7D,%7B'option':'Hex','string':''%7D)Remove_whitespace(true,true,true,true,true,false)Reverse('Character')ADD(%7B'option':'Decimal','string':'-1'%7D)&input=MzEgYTMgMzMgYzUgMTggZmIgYzUgM2MgZDMgZTAgYzkgY2EgYTcgNDMgMmEgYTIgMmYgNmUgNDggMGQgMWYgMzcgMzcgMjIgN2YgNDEgODggMGQgOTMgYTQgYjkgOWY&oeol=NEL
OLLessVM
00007FF6C5E8A4 | 8D041F | lea eax,qword ptr ds:[rdi+rbx] |
00007FF6C5E8A4 | 48:63D3 | movsxd rdx,ebx |
00007FF6C5E8A4 | 48:63C8 | movsxd rcx,eax |
00007FF6C5E8A4 | 8A440D F7 | mov al,byte ptr ss:[rbp+rcx-9] |
00007FF6C5E8A4 | 320432 | xor al,byte ptr ds:[rdx+rsi] |
00007FF6C5E8A4 | 32C3 | xor al,bl |
00007FF6C5E8A4 | 42:880432 | mov byte ptr ds:[rdx+r14],al |
x64dbg打开,找到,输入一个东西下硬件断点找到关键点,拿到xor表,main函数的ans表和bl(counter)即可写出wp:
xort = bytes.fromhex("9199417B79814BCBA9EC2E02CB94E526910BA60F2881A160D1525FC47AAD4FFFE299D57A286EC037F570E6460707A2F54B393A97328EB0E7BBE8C7D2B7087B628ED06FBF369F0000A0F4A55946024602")
ans = bytes.fromhex("FCF12D1131C7198ADABC147C98EADB65F729D04348FC8428F92923AC59CD51E0C2B8F7590C4BE610DD59CC6D2B2A8CDA7B0808A406BB86D083D1FDE98B35455D514CD172F6B8E69EE2B72D7525712B4B864587A1C947C55A165E1AD1179D186E3FD275E9E35156C206046D1A50657DFDA912")
for i in range(len(ans)):
print(chr(i^xort[i]^ans[i]),end='')
# miniLCTF{Y0u_s0Lv3d_th3_0bfs?}
OLLessVM_RENVEGE
发现使用ReadConsoleW来读取控制台
BOOL WINAPI ReadConsole(__in HANDLE hConsoleInput,__out LPVOID lpBuffer,__in DWORD nNumberOfCharsToRead,__out LPDWORD lpNumberOfCharsRead,__in_opt LPVOID pInputControl);
#include <iostream>
#include <vector>
#include <Windows.h>
uint8_t x0r[16] = { 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80 };
int main()
{
const char* f = "miniLCTF{1141414141414111111111}";
char* flag = (char*)malloc(33);
memcpy_s(flag, 33, f, strlen(f));
if (!flag)
{
return -1;
}
for (size_t i = 0; i < 32; i++)
{
flag[i] ^= x0r[i % 16];
}
auto inn = (DWORD*)flag;
auto xnn = (DWORD*)x0r;
std::cout << std::hex;
DWORD offset = 0xEEB7B2B6;
DWORD keyOffset = 0xBADECADA;
DWORD sum = 0x2EB7B2B6;
uint32_t key = 0xBADECADA;
for (int k = 0; k < 12; k++)
{
for (int i = 0; i < 8; i++)
{
DWORD e1 = ((inn[(7 + i) % 8] >> 5) ^ (inn[(1 + i) % 8] << 2));
DWORD e2 = ((inn[(1+ i) % 8] >> 3) ^ (inn[(7 + i) % 8] << 4));
//cout << e1 << endl << e2 << endl;
/*
0x1fbe03fe
0xc7df907b
*/
DWORD p = e1 - ~e2 - 1;
//std::cout << "sum=0x" << sum << std::endl;
DWORD e3 = xnn[(sum ^ i) & 3] ^ inn[(7 + i) % 8];
DWORD p2 = inn[(1 + i) % 8] ^ key;
//cout << p << endl << e3 << endl << p2 << endl;
DWORD p3 = p2 - ~e3 - 1;
DWORD e4 = p3 ^ p;
//cout << p3 << endl << e4 << endl;
DWORD p4 = inn[(i) % 8] - ~e4 - 1;
//std::cout << "i=" << i << "|" << p4 << std::endl; // p4 is ANS
inn[i] = p4;
//std::cout << "-------------\n";
}
//std::cout << "k=" << k << "----------------------------------------------------\n";
key += keyOffset;
sum = sum + offset + !(k % 2);
}
char* result = (char*)malloc(33);
if (!result) return -1;
for (size_t i = 0; i < 32; i++)
{
result[31 - i] = flag[i] ^ x0r[(31 - i) % 16] ^ 0x18;
}
if (*(DWORD*)result != 0xc293a546)
{
std::cout << "errrr";
}
char ans[] = {0x4b ,0xa0 ,0x0c ,0xff ,0xab ,0x0a ,0x13 ,0xb0,0x32 ,0x91 ,0x6d ,0x87 ,0x8b ,0xab ,0xf5 ,0xa5,0xdc ,0x77 ,0xd4 ,0x95 ,0xb9 ,0x02 ,0xa6 ,0xac,0xe4 ,0x74 ,0x2c ,0x6b ,0xeb ,0xe1 ,0x5e ,0x25};
return 0;
}
注意到(sum ^ i) & 3,立马想到了TEA加密算法,再看一下这个结构,完全不像??
不过e1, e2好像key中的l和r,所以想办法得搞成TEA,也方便写解密脚本
注意到程序中p2 - ~e3 - 1这种模式,加密过程中出现了三次,所以想办法看看能不能化简。
这种模式立即让我想到了VMProtect 3.5,虚拟化后的加法过程,随即我翻阅了去年组会中我写的blog:
https://组织内部神秘博客地址/d/955-redi-er-ci-zu-hui-idapythonji-chu-appcallshi-yong/9
可以注意到,化简后是
p2 - ~e3 - 1 <====> p2 + e3
这样就可以化简整个加密函数
uint8_t lkey[16] = { 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80 };
void encryption(DWORD* inn)
{
DWORD offset_ = 0xBADECADA;
DWORD key = 0x2EB7B2B6;
uint32_t sum_ = 0xBADECADA;
auto xnn = (DWORD*)lkey;
for (int k = 0; k < 12; k++)
{
for (int i = 0; i < 8; i++)
{
DWORD l = ((inn[(7 + i) % 8] >> 5) ^ (inn[(1 + i) % 8] << 2));
DWORD r = ((inn[(1 + i) % 8] >> 3) ^ (inn[(7 + i) % 8] << 4));
DWORD p4 = inn[(i) % 8] + (((inn[(1 + i) % 8] ^ sum_) + (xnn[(key ^ i) & 3] ^ inn[(7 + i) % 8])) ^ (l + r));
inn[i] = p4;
}
sum_ += offset_;
key += 0xEEB7B2B6 + !(k % 2);
}
}
xnn是lkey, lkey是xor(key)表,至此我们需要写解密函数,我的处理方法是把key和sum先算12次,得到最后结果,然后反着来用,按照TEA的方法来逆向。
void decryption(DWORD* inn)
{
DWORD offset_ = 0xBADECADA;
DWORD key = 0x2EB7B2B6;
uint32_t sum_ = 0xBADECADA;
auto xnn = (DWORD*)lkey;
for (int k = 0; k < 12; k++)
{
sum_ += offset_;
key += 0xEEB7B2B6 + !(k % 2);
}
for (int k = 11; k >= 0; k--)
{
sum_ -= offset_;
key -= 0xEEB7B2B6 + !(k % 2);
for (int i = 7; i >= 0; i--)
{
DWORD l = ((inn[(7 + i) % 8] >> 5) ^ (inn[(1 + i) % 8] << 2));
DWORD r = ((inn[(1 + i) % 8] >> 3) ^ (inn[(7 + i) % 8] << 4));
inn[i] -= (((inn[(1 + i) % 8] ^ sum_) + (xnn[(key ^ i) & 3] ^ inn[(7 + i) % 8])) ^ (l + r));
}
}
}
至此,给出完整exp:
#include <iostream>
#include <vector>
#include <Windows.h>
uint8_t lkey[16] = { 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80 };
void encryption(DWORD* inn)
{
DWORD offset_ = 0xBADECADA;
DWORD key = 0x2EB7B2B6;
uint32_t sum_ = 0xBADECADA;
auto xnn = (DWORD*)lkey;
for (int k = 0; k < 12; k++)
{
for (int i = 0; i < 8; i++)
{
DWORD l = ((inn[(7 + i) % 8] >> 5) ^ (inn[(1 + i) % 8] << 2));
DWORD r = ((inn[(1 + i) % 8] >> 3) ^ (inn[(7 + i) % 8] << 4));
DWORD p4 = inn[(i) % 8] + (((inn[(1 + i) % 8] ^ sum_) + (xnn[(key ^ i) & 3] ^ inn[(7 + i) % 8])) ^ (l + r));
inn[i] = p4;
}
sum_ += offset_;
key += 0xEEB7B2B6 + !(k % 2);
}
}
void decryption(DWORD* inn)
{
DWORD offset_ = 0xBADECADA;
DWORD key = 0x2EB7B2B6;
uint32_t sum_ = 0xBADECADA;
auto xnn = (DWORD*)lkey;
for (int k = 0; k < 12; k++)
{
sum_ += offset_;
key += 0xEEB7B2B6 + !(k % 2);
}
for (int k = 11; k >= 0; k--)
{
sum_ -= offset_;
key -= 0xEEB7B2B6 + !(k % 2);
for (int i = 7; i >= 0; i--)
{
DWORD l = ((inn[(7 + i) % 8] >> 5) ^ (inn[(1 + i) % 8] << 2));
DWORD r = ((inn[(1 + i) % 8] >> 3) ^ (inn[(7 + i) % 8] << 4));
inn[i] -= (((inn[(1 + i) % 8] ^ sum_) + (xnn[(key ^ i) & 3] ^ inn[(7 + i) % 8])) ^ (l + r));
}
}
}
int main()
{
char ans[] = { 0x4b ,0xa0 ,0x0c ,0xff ,0xab ,0x0a ,0x13 ,0xb0,0x32 ,0x91 ,0x6d ,0x87 ,0x8b ,0xab ,0xf5 ,0xa5,0xdc ,0x77 ,0xd4 ,0x95 ,0xb9 ,0x02 ,0xa6 ,0xac,0xe4 ,0x74 ,0x2c ,0x6b ,0xeb ,0xe1 ,0x5e ,0x25 };
char* result = (char*)malloc(33);
if (!result) return -1;
result[32] = 0;
for (size_t i = 0; i < 32; i++)
{
result[i] = ans[31 - i] ^ lkey[(31 - i) % 16] ^ 0x18;
}
decryption((DWORD*)result);
for (size_t i = 0; i < 32; i++)
{
result[i] ^= lkey[i % 16];
}
std::cout << result;
return 0;
}