babyre
第一个是一个 AES
key 是
0x35, 0x77, 0x40, 0x2E, 0xCC, 0xA4, 0x4A, 0x3F, 0x9A, 0xB7, 
0x21, 0x82, 0xF9, 0xB0, 0x1F, 0x35
从后往前看
__int64 __fastcall sub_4020F7(__int64 result)
{
  int v1; // r8d
  int v2; // ecx
  int v3; // ecx
  int var38[16]; // [rsp+8h] [rbp-38h]
  int i; // [rsp+38h] [rbp-8h]
  unsigned int v7; // [rsp+3Ch] [rbp-4h]
 
  v7 = 1;
  for ( i = 0; i <= 15; ++i )
  {
    var38[11] = *(_DWORD *)(48i64 * i + result);
    var38[10] = *(_DWORD *)(48i64 * i + result + 4);
    var38[9] = *(_DWORD *)(48i64 * i + result + 8);
    var38[8] = *(_DWORD *)(48i64 * i + result + 12);
    var38[7] = *(_DWORD *)(48i64 * i + result + 16);
    var38[6] = *(_DWORD *)(48i64 * i + result + 20);
    var38[5] = *(_DWORD *)(48i64 * i + result + 24);
    var38[4] = *(_DWORD *)(48i64 * i + result + 28);
    var38[3] = *(_DWORD *)(48i64 * i + result + 32);
    var38[2] = *(_DWORD *)(48i64 * i + result + 36);
    var38[1] = *(_DWORD *)(48i64 * i + result + 40);
    var38[0] = *(_DWORD *)(48i64 * i + result + 44);
    v1 = var38[2] & var38[3] & var38[4] & (var38[6] == 0) & (var38[7] == 0) & var38[8] & ((var38[9] | var38[10] | var38[11]) == 0) & (var38[5] == 0) & (var38[1] == 0) | var38[2] & var38[4] & var38[6] & (var38[8] == 0) & (var38[9] == 0) & var38[11] & (var38[10] == 0) & (var38[7] == 0) & (var38[5] == 0) & (var38[3] == 0) & (var38[1] == 0) | var38[1] & (var38[3] == 0) & (var38[4] == 0) & (var38[5] == 0) & var38[6] & var38[7] & (unsigned __int8)(var38[9] & var38[10] & LOBYTE(var38[11])) & (var38[8] == 0) & (var38[2] == 0);
    v2 = var38[0] & var38[1] & var38[3] & var38[4] & var38[5] & var38[6] & var38[7] & (var38[9] == 0) & (unsigned __int8)(var38[10] & LOBYTE(var38[11])) & (var38[8] == 0) & (var38[2] == 0) | (var38[1] == 0) & (var38[2] == 0) & var38[3] & var38[4] & var38[5] & var38[7] & var38[8] & var38[10] & (var38[11] == 0) & (var38[9] == 0) & (var38[6] == 0) & (var38[0] == 0) | var38[0] & (var38[2] == 0) & var38[3] & var38[5] & var38[7] & var38[8] & var38[9] & var38[11] & (var38[10] == 0) & (var38[6] == 0) & (var38[4] == 0) & (var38[1] == 0) | var38[0] & var38[2] & var38[3] & var38[5] & var38[6] & var38[8] & var38[9] & (*(_QWORD *)&var38[10] == 0i64) & (var38[7] == 0) & (var38[4] == 0) & (var38[1] == 0) | (v1 | var38[1] & var38[2] & (var38[4] == 0) & var38[5] & (var38[7] == 0) & var38[8] & var38[9] & var38[11] & (var38[10] == 0) & (var38[6] == 0) & (var38[3] == 0)) & (var38[0] == 0);
    v3 = var38[0] & var38[1] & (var38[3] == 0) & (var38[4] == 0) & var38[5] & (var38[7] == 0) & (var38[8] == 0) & (var38[9] == 0) & (unsigned __int8)(var38[10] & LOBYTE(var38[11])) & (var38[6] == 0) & (var38[2] == 0) | (var38[1] == 0) & (var38[2] == 0) & (var38[3] == 0) & (var38[4] == 0) & var38[5] & (var38[7] == 0) & var38[8] & ((var38[9] | var38[10] | var38[11]) == 0) & (var38[6] == 0) & (var38[0] == 0) | var38[0] & var38[1] & var38[2] & (var38[4] == 0) & (var38[5] == 0) & var38[6] & var38[7] & (var38[9] == 0) & var38[10] & (var38[11] == 0) & (var38[8] == 0) & (var38[3] == 0) | var38[0] & var38[2] & (var38[4] == 0) & (var38[5] == 0) & var38[6] & ((var38[7] | var38[8] | var38[9] | var38[10] | var38[11]) == 0) & (var38[3] == 0) & (var38[1] == 0) | var38[0] & (var38[2] == 0) & (var38[3] == 0) & var38[4] & var38[5] & var38[6] & var38[7] & (var38[9] == 0) & var38[11] & (var38[10] == 0) & (var38[8] == 0) & (var38[1] == 0) | v2;
    if ( !(var38[1] & var38[3] & var38[5] & var38[7] & (var38[9] == 0) & var38[10] & (var38[11] == 0) & (var38[8] == 0) & (var38[6] == 0) & (var38[4] == 0) & (var38[2] == 0) & (var38[0] == 0) | var38[0] & var38[1] & var38[2] & var38[3] & (var38[5] == 0) & (var38[6] == 0) & var38[7] & (var38[9] == 0) & var38[10] & (var38[11] == 0) & (var38[8] == 0) & (var38[4] == 0) | v3 | var38[1] & var38[2] & var38[3] & var38[5] & var38[7] & ((var38[8] | var38[9] | var38[10] | var38[11]) == 0) & (var38[6] == 0) & (var38[4] == 0) & (var38[0] == 0)) )
      v7 = 0;
  }
  return v7;
}char __fastcall sub_402001(int *result, unsigned __int8 *buf)
{
  __int64 k_1; // rax
  int k; // [rsp+0h] [rbp-10h]
  int j; // [rsp+4h] [rbp-Ch]
  int i; // [rsp+8h] [rbp-8h]
  int now_i; // [rsp+Ch] [rbp-4h]
 
  for ( i = 0; i <= 15; ++i )
  {
    LOBYTE(k_1) = i;
    now_i = i;
    for ( j = 0; j <= 3; ++j )
    {
      k_1 = 11 - j;
      result[12 * i + k_1] = now_i & 1;         // 8-11 index
      now_i >>= 1;
    }
    for ( k = 0; k <= 7; ++k )
    {
      result[12 * i + 7 - k] = buf[i] & 1;      // 0-7 buf
      LOBYTE(k_1) = buf[i] >> 1;
      buf[i] = k_1;
    }
  }
  return k_1;
}把输入按位拆开,前 8 bits 放在 0-7(大的在前面),后面 8-11 放 index 的 bits
那就反转过来 3-11 是我们想要的数据,写个 z3 求解出来:
from z3 import *
res = []
for i in range(16):
	sol = Solver()
	v5 = [BitVec(f"v{i}", 1) for i in range(12)]
 
	v1 = v5[2] & v5[3] & v5[4] & (~v5[6]) & (~v5[7]) & v5[8] & (~(v5[9] | v5[10] | v5[11])) & (~v5[5]) & (~v5[1]) | v5[2] & v5[4] & v5[6] & (~v5[8]) & (~v5[9]) & v5[11] & (~v5[10]) & (~v5[7]) & (~v5[5]) & (~v5[3]) & (~v5[1]) | v5[1] & (~v5[3]) & (~v5[4]) & (~v5[5]) & v5[6] & v5[7] & (v5[9] & v5[10] & v5[11]) & (~v5[8]) & (~v5[2])
	v2 = v5[0] & v5[1] & v5[3] & v5[4] & v5[5] & v5[6] & v5[7] & (~v5[9]) & v5[10] & v5[11] & (~v5[8]) & (~v5[2]) | (~v5[1]) & (~v5[2]) & v5[3] & v5[4] & v5[5] & v5[7] & v5[8] & v5[10] & (~v5[11]) & (~v5[9]) & (~v5[6]) & (~v5[0]) | v5[0] & (~v5[2]) & v5[3] & v5[5] & v5[7] & v5[8] & v5[9] & v5[11] & (~v5[10]) & (~v5[6]) & (~v5[4]) & (~v5[1]) | v5[0] & v5[2] & v5[3] & v5[5] & v5[6] & v5[8] & v5[9] & (~v5[10]) & (~v5[11]) & (~v5[7]) & (~v5[4]) & (~v5[1]) | (v1 | v5[1] & v5[2] & (~v5[4]) & v5[5] & (~v5[7]) & v5[8] & v5[9] & v5[11] & (~v5[10]) & (~v5[6]) & (~v5[3])) & (~v5[0])
	v3 = v5[0] & v5[1] & (~v5[3]) & (~v5[4]) & v5[5] & (~v5[7]) & (~v5[8]) & (~v5[9]) & v5[10] & v5[11] & (~v5[6]) & (~v5[2]) | (~v5[1]) & (~v5[2]) & (~v5[3]) & (~v5[4]) & v5[5] & (~v5[7]) & v5[8] & (~(v5[9] | v5[10] | v5[11])) & (~v5[6]) & (~v5[0]) | v5[0] & v5[1] & v5[2] & (~v5[4]) & (~v5[5]) & v5[6] & v5[7] & (~v5[9]) & v5[10] & (~v5[11]) & (~v5[8]) & (~v5[3]) | v5[0] & v5[2] & (~v5[4]) & (~v5[5]) & v5[6] & (~(v5[7] | v5[8] | v5[9] | v5[10] | v5[11])) & (~v5[3]) & (~v5[1]) | v5[0] & (~v5[2]) & (~v5[3]) & v5[4] & v5[5] & v5[6] & v5[7] & (~v5[9]) & v5[11] & (~v5[10]) & (~v5[8]) & (~v5[1]) | v2
	v4 = v5[1] & v5[3] & v5[5] & v5[7] & (~v5[9]) & v5[10] & (~v5[11]) & (~v5[8]) & (~v5[6]) & (~v5[4]) & (~v5[2]) & (~v5[0]) | v5[0] & v5[1] & v5[2] & v5[3] & (~v5[5]) & (~v5[6]) & v5[7] & (~v5[9]) & v5[10] & (~v5[11]) & (~v5[8]) & (~v5[4]) | v3 | v5[1] & v5[2] & v5[3] & v5[5] & v5[7] & (~(v5[8] | v5[9] | v5[10] | v5[11])) & (~v5[6]) & (~v5[4]) & (~v5[0])
 
	sol.add(v4 == 1)
	sol.add(v5[0] == i&1)
	sol.add(v5[1] == (i>>1)&1)
	sol.add(v5[2] == (i>>2)&1)
	sol.add(v5[3] == (i>>3)&1)
 
	sol.check()
	mod = sol.model()
	# print(mod)
	x = 0
	for j in range(11, 3, -1):
		x = (x << 1) | (mod[v5[j]].as_long())
	res.append(x)
print(res)
for _ in res:
	print(hex(_)[2:], end=" ")18, 143, 236, 194, 133, 4, 178, 76, 91, 186, 74, 207, 17, 54, 10, 72
12 8f ec c2 85 4 b2 4c 5b ba 4a cf 11 36 a 48
35 77 40 2E CC A4 4A 3F 9A B7 21 82 F9 B0 1F 35
好像 no-padding 才是对的

4d87ef03-77bb-491a-80f5-4620245807c4
easyre
https://bbs.kanxue.com/thread-284044.htm?style=1
https://blog.xmcve.com/2024/10/20/%E5%BC%BA%E7%BD%91%E6%8B%9F%E6%80%812024-Writeup/#title-11
反调试绕过: https://github.com/x64dbg/ScyllaHide/
什么超级动调大师训练题(
j__fgetc_nolock 和 strlen 可以确定输入位置 在 sub_7FF7CC614A9C(__int64 a1, int a2)
对输入位置下硬件断点,ponce 调试
len = strlen(flag) cmp     rdx, 38h ;



好麻烦,用输入验证到底干嘛了,有两次操作,一次加法,一次取反和与运算乱七八糟合在一起,
应该是一一对应,输入进去一样的输出一样,那么遍历输入就能直接得到字典



有 shr 11

有 TEA 加密特征数

这里就是 key[(sum>>11) & 3] 的取数的地方

key = [0x0EF6FD9DB,0x0D2C273D3,0x6F97E412,0x72BFD624]
在返回的时候查看栈帧,可以看到参数的传递(硬件断点)

所以加密次数是 0x66

(原始的函数栈还是很干净的


00007FF7CC60B1A0
什么鬼,IDA 爆炸了,trace 出来看罢

在这里比较最后一位,往前溯源,得到密文(其实就是 data 段的开头,猜的话应该也是猜放在这)

0xA1, 0xE3, 0x51, 0x98, 0x86, 0x56, 0x76, 0x49, 0x6F, 0x6B, 
0x2B, 0x81, 0xCF, 0xCE, 0x12, 0x96, 0xA2, 0x70, 0x35, 0x3C, 
0x31, 0x62, 0x5C, 0xF1, 0xFA, 0x77, 0x6B, 0xAA, 0x9E, 0x6D, 
0x05, 0xBE, 0xE8, 0x24, 0xA4, 0xF8, 0xDB, 0x23, 0x3A, 0x0B, 
0x16, 0x20, 0xCC, 0x03, 0xAD, 0xB5, 0x2B, 0xA9, 0x34, 0x9F, 
0x78, 0x1D, 0x2E, 0xB9, 0xF9, 0x9E
根据前面的密码本就能复原
#include <stdint.h>
#include <stdio.h>
 
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
 
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 0x9E3779B9;
    for (i = 0; i < num_rounds; i++) {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
    }
    v[0] = v0;
    v[1] = v1;
}
 
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 0x9E3779B9, sum = delta * num_rounds;
    for (i = 0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    }
    v[0] = v0;
    v[1] = v1;
}
 
int main() {
    uint8_t cipher[] = {
        0xA1, 0xE3, 0x51, 0x98, 0x86, 0x56, 0x76, 0x49, 0x6F, 0x6B, 0x2B, 0x81,
        0xCF, 0xCE, 0x12, 0x96, 0xA2, 0x70, 0x35, 0x3C, 0x31, 0x62, 0x5C, 0xF1,
        0xFA, 0x77, 0x6B, 0xAA, 0x9E, 0x6D, 0x05, 0xBE, 0xE8, 0x24, 0xA4, 0xF8,
        0xDB, 0x23, 0x3A, 0x0B, 0x16, 0x20, 0xCC, 0x03, 0xAD, 0xB5, 0x2B, 0xA9,
        0x34, 0x9F, 0x78, 0x1D, 0x2E, 0xB9, 0xF9, 0x9E};
    uint32_t key[4] = {0x0EF6FD9DB, 0x0D2C273D3, 0x6F97E412, 0x72BFD624};
 
    for (int i = 0; i * 8 < sizeof(cipher); i++) {
        decipher(0x66, (uint32_t *)(cipher + i * 8), key);
    }
 
    uint8_t ebokk[] = {0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16,
                       0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D,
                       0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04,
                       0x03, 0x02, 0x01, 0x00, 0xFF, 0xFE, 0xFD, 0xFC, 0xFB,
                       0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2,
                       0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9,
                       0xE8, 0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0,
                       0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8, 0xD7,
                       0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xD0, 0xCF, 0xCE,
                       0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC8, 0xC7, 0xC6, 0xC5,
                       0xC4, 0xC3, 0xC2, 0xC1};
 
    for (int i = 0; i < sizeof(cipher); i++) {
        int ch = 0;
        for (int j = 0; j < sizeof(ebokk); j++) {
            if (cipher[i] == ebokk[j]) {
                ch = j;
                break;
            }
        }
        printf("%c", ch + 0x21);
    }
 
    return 0;
}flag{u_ar3_re@11y_g00d_@t_011vm_de0bf_and_anti_debugger}