垃圾循环伪装加减法 整数溢出

main 超级超级长的函数调用 其实看下面我放的3个函数 其实就能看出来挺简单的 就是一个加减乘的三个函数 这个不是我们之前所做的输入flag之后比较的类型 而是靠这些函数调用来自己算出来

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int *v3; // eax
  int *v4; // eax
  _DWORD *v5; // eax
  _DWORD *v6; // eax
  _DWORD *v7; // eax
  int *v8; // eax
  int *v9; // eax
  int *v10; // eax
  int *v11; // eax
  int *v12; // eax
  _DWORD *v13; // eax
  _DWORD *v14; // eax
  _DWORD *v15; // eax
  int *v16; // eax
  int *v17; // eax
  int *v18; // eax
  int *v19; // eax
  int *v20; // eax
  _DWORD *v21; // eax
  int *v22; // eax
  int *v23; // eax
  _DWORD *v24; // eax
  _DWORD *v25; // eax
  _DWORD *v26; // eax
  int *v27; // eax
  int *v28; // eax
  int *v29; // eax
  _DWORD *v30; // eax
  _DWORD *v31; // eax
  _DWORD *v32; // eax
  _DWORD *v33; // eax
  _DWORD *v34; // eax
  _DWORD *v35; // eax
  _DWORD *v36; // eax
  int *v37; // eax
  int *v38; // eax
  int *v39; // eax
  _DWORD *v40; // eax
  _DWORD *v41; // eax
  _DWORD *v42; // eax
  _DWORD *v43; // eax
  _DWORD *v44; // eax
  _DWORD *v45; // eax
  _DWORD *v46; // eax
  int *v47; // eax
  int *v48; // eax
  int *v49; // eax
  _DWORD *v50; // eax
  int *v51; // eax
  int *v52; // eax
  _DWORD *v53; // eax
  _DWORD *v54; // eax
  _DWORD *v55; // eax
  _DWORD *v56; // eax
  _DWORD *v57; // eax
  _DWORD *v58; // eax
  _DWORD *v59; // eax
  _DWORD *v60; // eax
  int *v61; // eax
  int *v62; // eax
  int *v63; // eax
  _DWORD *v64; // eax
  _DWORD *v65; // eax
  _DWORD *v66; // eax
  _DWORD *v67; // eax
  _DWORD *v68; // eax
  _DWORD *v69; // eax
  _DWORD *v70; // eax
  _DWORD *v71; // eax
  _DWORD *v72; // eax
  _DWORD *v73; // eax
  _DWORD *v74; // eax
  _DWORD *v75; // eax
  _DWORD *v76; // eax
  _DWORD *v77; // eax
  _DWORD *v78; // eax
  int *v79; // eax
  int *v80; // eax
  int *v81; // eax
  _DWORD *v82; // eax
  int *v83; // eax
  int *v84; // eax
  _DWORD *v85; // eax
  int *v86; // eax
  int *v87; // eax
  _DWORD *v88; // eax
  _DWORD *v89; // eax
  _DWORD *v90; // eax
  _DWORD *v91; // eax
  _DWORD *v92; // eax
  _DWORD *v93; // eax
  int *v94; // eax
  int *v95; // eax
  int *v96; // eax
  _DWORD *v97; // eax
  _DWORD *v98; // eax
  _DWORD *v99; // eax
  _DWORD *v100; // eax
  _DWORD *v101; // eax
  _DWORD *v102; // eax
  _DWORD *v103; // eax
  _DWORD *v104; // eax
  _DWORD *v105; // eax
  _DWORD *v106; // eax
  _DWORD *v107; // eax
  _DWORD *v108; // eax
  _DWORD *v109; // eax
  _DWORD *v110; // eax
  int *v111; // eax
  int *v112; // eax
  int *v113; // eax
  int v115; // [esp-8h] [ebp-9Ch]
  int v116; // [esp-4h] [ebp-98h]
  int v117; // [esp-4h] [ebp-98h]
  int i; // [esp+4h] [ebp-90h]
  int j; // [esp+8h] [ebp-8Ch]
  int v120[12]; // [esp+Ch] [ebp-88h] BYREF
  int v121; // [esp+3Ch] [ebp-58h] BYREF
  int v122; // [esp+40h] [ebp-54h] BYREF
  int v123; // [esp+44h] [ebp-50h] BYREF
  int v124; // [esp+48h] [ebp-4Ch] BYREF
  int v125; // [esp+4Ch] [ebp-48h] BYREF
  int v126; // [esp+50h] [ebp-44h] BYREF
  int v127; // [esp+54h] [ebp-40h] BYREF
  int v128; // [esp+58h] [ebp-3Ch] BYREF
  int v129; // [esp+5Ch] [ebp-38h] BYREF
  int v130; // [esp+60h] [ebp-34h] BYREF
  int v131; // [esp+64h] [ebp-30h] BYREF
  int v132; // [esp+68h] [ebp-2Ch] BYREF
  int v133; // [esp+6Ch] [ebp-28h] BYREF
  int v134; // [esp+70h] [ebp-24h] BYREF
  int v135; // [esp+74h] [ebp-20h] BYREF
  int v136; // [esp+78h] [ebp-1Ch] BYREF
  int v137; // [esp+7Ch] [ebp-18h] BYREF
  int v138; // [esp+80h] [ebp-14h] BYREF
  int v139; // [esp+84h] [ebp-10h] BYREF
  _DWORD v140[2]; // [esp+88h] [ebp-Ch] BYREF

  for ( i = 0; i < 32; ++i )
    v120[i] = 1;
  v140[1] = 0;
  puts("Your flag is:");
  v3 = sub_401100(v120, 1000000000);
  v4 = sub_401220(v3, 999999950);
  sub_401100(v4, 2);
  v5 = sub_401000(&v120[1], 5000000);
  v6 = sub_401220(v5, 6666666);
  v7 = sub_401000(v6, 1666666);
  v8 = sub_401000(v7, 45);
  v9 = sub_401100(v8, 2);
  sub_401000(v9, 5);
  v10 = sub_401100(&v120[2], 1000000000);
  v11 = sub_401220(v10, 999999950);
  v12 = sub_401100(v11, 2);
  sub_401000(v12, 2);
  v13 = sub_401000(&v120[3], 55);
  v14 = sub_401220(v13, 3);
  v15 = sub_401000(v14, 4);
  sub_401220(v15, 1);
  v16 = sub_401100(&v120[4], 100000000);
  v17 = sub_401220(v16, 99999950);
  v18 = sub_401100(v17, 2);
  sub_401000(v18, 2);
  v19 = sub_401220(&v120[5], 1);
  v20 = sub_401100(v19, 1000000000);
  v21 = sub_401000(v20, 55);
  sub_401220(v21, 3);
  v22 = sub_401100(&v120[6], 1000000);
  v23 = sub_401220(v22, 999975);
  sub_401100(v23, 4);
  v24 = sub_401000(&v120[7], 55);
  v25 = sub_401220(v24, 33);
  v26 = sub_401000(v25, 44);
  sub_401220(v26, 11);
  v27 = sub_401100(&v120[8], 10);
  v28 = sub_401220(v27, 5);
  v29 = sub_401100(v28, 8);
  sub_401000(v29, 9);
  v30 = sub_401000(&v120[9], 0);
  v31 = sub_401220(v30, 0);
  v32 = sub_401000(v31, 11);
  v33 = sub_401220(v32, 11);
  sub_401000(v33, 53);
  v34 = sub_401000(&v120[10], 49);
  v35 = sub_401220(v34, 2);
  v36 = sub_401000(v35, 4);
  sub_401220(v36, 2);
  v37 = sub_401100(&v120[11], 1000000);
  v38 = sub_401220(v37, 999999);
  v39 = sub_401100(v38, 4);
  sub_401000(v39, 50);
  v40 = sub_401000(&v121, 1);
  v41 = sub_401000(v40, 1);
  v42 = sub_401000(v41, 1);
  v43 = sub_401000(v42, 1);
  v44 = sub_401000(v43, 1);
  v45 = sub_401000(v44, 1);
  v46 = sub_401000(v45, 10);
  sub_401000(v46, 32);
  v47 = sub_401100(&v122, 10);
  v48 = sub_401220(v47, 5);
  v49 = sub_401100(v48, 8);
  v50 = sub_401000(v49, 9);
  sub_401000(v50, 48);
  v51 = sub_401220(&v123, 1);
  v52 = sub_401100(v51, -294967296);
  v53 = sub_401000(v52, 55);
  sub_401220(v53, 3);
  v54 = sub_401000(&v124, 1);
  v55 = sub_401000(v54, 2);
  v56 = sub_401000(v55, 3);
  v57 = sub_401000(v56, 4);
  v58 = sub_401000(v57, 5);
  v59 = sub_401000(v58, 6);
  v60 = sub_401000(v59, 7);
  sub_401000(v60, 20);
  v61 = sub_401100(&v125, 10);
  v62 = sub_401220(v61, 5);
  v63 = sub_401100(v62, 8);
  v64 = sub_401000(v63, 9);
  sub_401000(v64, 48);
  v65 = sub_401000(&v126, 7);
  v66 = sub_401000(v65, 6);
  v67 = sub_401000(v66, 5);
  v68 = sub_401000(v67, 4);
  v69 = sub_401000(v68, 3);
  v70 = sub_401000(v69, 2);
  v71 = sub_401000(v70, 1);
  sub_401000(v71, 20);
  v72 = sub_401000(&v127, 7);
  v73 = sub_401000(v72, 2);
  v74 = sub_401000(v73, 4);
  v75 = sub_401000(v74, 3);
  v76 = sub_401000(v75, 6);
  v77 = sub_401000(v76, 5);
  v78 = sub_401000(v77, 1);
  sub_401000(v78, 20);
  v79 = sub_401100(&v128, 1000000);
  v80 = sub_401220(v79, 999999);
  v81 = sub_401100(v80, 4);
  v82 = sub_401000(v81, 50);
  sub_401220(v82, 1);
  v83 = sub_401220(&v129, 1);
  v84 = sub_401100(v83, -294967296);
  v85 = sub_401000(v84, 49);
  sub_401220(v85, 1);
  v86 = sub_401220(&v130, 1);
  v87 = sub_401100(v86, 1000000000);
  v88 = sub_401000(v87, 54);
  v89 = sub_401220(v88, 1);
  v90 = sub_401000(v89, 1000000000);
  sub_401220(v90, 1000000000);
  v91 = sub_401000(&v131, 49);
  v92 = sub_401220(v91, 1);
  v93 = sub_401000(v92, 2);
  sub_401220(v93, 1);
  v94 = sub_401100(&v132, 10);
  v95 = sub_401220(v94, 5);
  v96 = sub_401100(v95, 8);
  v97 = sub_401000(v96, 9);
  sub_401000(v97, 48);
  v98 = sub_401000(&v133, 1);
  v99 = sub_401000(v98, 3);
  v100 = sub_401000(v99, 3);
  v101 = sub_401000(v100, 3);
  v102 = sub_401000(v101, 6);
  v103 = sub_401000(v102, 6);
  v104 = sub_401000(v103, 6);
  sub_401000(v104, 20);
  v105 = sub_401000(&v134, 55);
  v106 = sub_401220(v105, 33);
  v107 = sub_401000(v106, 44);
  v108 = sub_401220(v107, 11);
  sub_401000(v108, 42);
  sub_401000(&v135, v134);
  sub_401000(&v136, v121);
  v115 = v136;
  v109 = sub_401220(&v137, 1);
  v110 = sub_401000(v109, v115);
  sub_401220(v110, 1);
  v116 = v132;
  v111 = sub_401220(&v138, 1);
  v112 = sub_401100(v111, 1000000);
  sub_401000(v112, v116);
  v117 = v136;
  v113 = sub_401000(&v139, 1);
  sub_401100(v113, v117);
  sub_401000(v140, v139);
  printf("CTF{");
  for ( j = 0; j < 32; ++j )
    printf("%c", SLOBYTE(v120[j]));
  printf("}\n");
  return 0;
}

sub_401100

int *__cdecl sub_401100(int *a1, int a2)
{
  int v3; // [esp+Ch] [ebp-1Ch]
  int v4; // [esp+14h] [ebp-14h]
  int v5; // [esp+18h] [ebp-10h]
  int v6; // [esp+18h] [ebp-10h]
  int v7; // [esp+1Ch] [ebp-Ch]
  int v8; // [esp+20h] [ebp-8h] BYREF

  v4 = *a1;
  v5 = a2;
  v3 = -1;
  v8 = 0;
  v7 = a2 * v4;
  while ( a2 )
  {
    v6 = v7 * v4;
    sub_401000(&v8, *a1);
    ++v7;
    --a2;
    v5 = v6 - 1;
  }
  while ( v3 )
  {
    ++v7;
    ++*a1;
    --v3;
    --v5;
  }
  ++*a1;
  *a1 = v8;
  return a1;
}

sub_401000

_DWORD *__cdecl sub_401000(_DWORD *a1, int a2)
{
  int v3; // [esp+Ch] [ebp-18h]
  int v4; // [esp+10h] [ebp-14h]
  int v5; // [esp+18h] [ebp-Ch]
  int v6; // [esp+1Ch] [ebp-8h]

  v4 = -1;
  v3 = -1 - a2 + 1;
  v6 = 1231;
  v5 = a2 + 1231;
  while ( v3 )
  {
    ++v6;
    --*a1;
    --v3;
    --v5;
  }
  while ( v4 )
  {
    --v5;
    ++*a1;
    --v4;
  }
  ++*a1;
  return a1;
}

sub_401220

_DWORD *__cdecl sub_401220(_DWORD *a1, int a2)
{
  int v3; // [esp+8h] [ebp-10h]
  int v4; // [esp+Ch] [ebp-Ch]
  int v5; // [esp+14h] [ebp-4h]
  int v6; // [esp+14h] [ebp-4h]

  v4 = -1;
  v3 = -1 - a2 + 1;
  v5 = -1;
  while ( v3 )
  {
    ++*a1;
    --v3;
    --v5;
  }
  v6 = v5 * v5;
  while ( v4 )
  {
    v6 *= 123;
    ++*a1;
    --v4;
  }
  ++*a1;
  return a1;
}

加密逻辑 总体简化就是这样 而为什么是这样的呢 因为整数溢出

sub_401000(p, x)  =>  *p += x;
sub_401220(p, x)  =>  *p -= x;
sub_401100(p, x)  =>  *p *= x;

来我们来解析一个函数就知道了 其他两个同理 sub_401000(a1, a2) 为什么是加法?

因为重点是

v3 = -a2;
while (v3)
{
    --*a1;
    --v3;
}

比如 a2 = 5,那么

v3 = -5

在 32 位整数里,-5 可以看成

0xfffffffb

它不断 --v3,最后会溢出回到 0

循环次数是

2^32 - 5

每次执行

--*a1;

所以效果是

*a1 -= 2^32 - 5

在 32 位下等价于

*a1 += 5

因为

-(2^32 - 5) ≡ +5 mod 2^32

后面这段

v4 = -1;
while (v4)
{
    ++*a1;
    --v4;
}
++*a1;

循环次数是

2^32 - 1

所以

*a1 += 2^32 - 1
*a1 += 1

合起来

*a1 += 2^32

在 32 位下等价于加 0

所以最终

sub_401000(a1, a2)

等价于

*a1 += a2;

exp

MASK = 0xffffffff

def add(x, a):
    return (x + a) & MASK

def sub(x, a):
    return (x - a) & MASK

def mul(x, a):
    return (x * a) & MASK

v = [1] * 32

v[0] = mul(v[0], 1000000000)
v[0] = sub(v[0], 999999950)
v[0] = mul(v[0], 2)

v[1] = add(v[1], 5000000)
v[1] = sub(v[1], 6666666)
v[1] = add(v[1], 1666666)
v[1] = add(v[1], 45)
v[1] = mul(v[1], 2)
v[1] = add(v[1], 5)

v[2] = mul(v[2], 1000000000)
v[2] = sub(v[2], 999999950)
v[2] = mul(v[2], 2)
v[2] = add(v[2], 2)

v[3] = add(v[3], 55)
v[3] = sub(v[3], 3)
v[3] = add(v[3], 4)
v[3] = sub(v[3], 1)

v[4] = mul(v[4], 100000000)
v[4] = sub(v[4], 99999950)
v[4] = mul(v[4], 2)
v[4] = add(v[4], 2)

v[5] = sub(v[5], 1)
v[5] = mul(v[5], 1000000000)
v[5] = add(v[5], 55)
v[5] = sub(v[5], 3)

v[6] = mul(v[6], 1000000)
v[6] = sub(v[6], 999975)
v[6] = mul(v[6], 4)

v[7] = add(v[7], 55)
v[7] = sub(v[7], 33)
v[7] = add(v[7], 44)
v[7] = sub(v[7], 11)

v[8] = mul(v[8], 10)
v[8] = sub(v[8], 5)
v[8] = mul(v[8], 8)
v[8] = add(v[8], 9)

v[9] = add(v[9], 0)
v[9] = sub(v[9], 0)
v[9] = add(v[9], 11)
v[9] = sub(v[9], 11)
v[9] = add(v[9], 53)

v[10] = add(v[10], 49)
v[10] = sub(v[10], 2)
v[10] = add(v[10], 4)
v[10] = sub(v[10], 2)

v[11] = mul(v[11], 1000000)
v[11] = sub(v[11], 999999)
v[11] = mul(v[11], 4)
v[11] = add(v[11], 50)

# v121 ~ v139 对应 v[12] ~ v[30]
for a in [1, 1, 1, 1, 1, 1, 10, 32]:
    v[12] = add(v[12], a)

v[13] = mul(v[13], 10)
v[13] = sub(v[13], 5)
v[13] = mul(v[13], 8)
v[13] = add(v[13], 9)
v[13] = add(v[13], 48)

v[14] = sub(v[14], 1)
v[14] = mul(v[14], -294967296)
v[14] = add(v[14], 55)
v[14] = sub(v[14], 3)

for a in [1, 2, 3, 4, 5, 6, 7, 20]:
    v[15] = add(v[15], a)

v[16] = mul(v[16], 10)
v[16] = sub(v[16], 5)
v[16] = mul(v[16], 8)
v[16] = add(v[16], 9)
v[16] = add(v[16], 48)

for a in [7, 6, 5, 4, 3, 2, 1, 20]:
    v[17] = add(v[17], a)

for a in [7, 2, 4, 3, 6, 5, 1, 20]:
    v[18] = add(v[18], a)

v[19] = mul(v[19], 1000000)
v[19] = sub(v[19], 999999)
v[19] = mul(v[19], 4)
v[19] = add(v[19], 50)
v[19] = sub(v[19], 1)

v[20] = sub(v[20], 1)
v[20] = mul(v[20], -294967296)
v[20] = add(v[20], 49)
v[20] = sub(v[20], 1)

v[21] = sub(v[21], 1)
v[21] = mul(v[21], 1000000000)
v[21] = add(v[21], 54)
v[21] = sub(v[21], 1)
v[21] = add(v[21], 1000000000)
v[21] = sub(v[21], 1000000000)

v[22] = add(v[22], 49)
v[22] = sub(v[22], 1)
v[22] = add(v[22], 2)
v[22] = sub(v[22], 1)

v[23] = mul(v[23], 10)
v[23] = sub(v[23], 5)
v[23] = mul(v[23], 8)
v[23] = add(v[23], 9)
v[23] = add(v[23], 48)

for a in [1, 3, 3, 3, 6, 6, 6, 20]:
    v[24] = add(v[24], a)

v[25] = add(v[25], 55)
v[25] = sub(v[25], 33)
v[25] = add(v[25], 44)
v[25] = sub(v[25], 11)
v[25] = add(v[25], 42)

v[26] = add(v[26], v[25])
v[27] = add(v[27], v[12])

v[28] = sub(v[28], 1)
v[28] = add(v[28], v[27])
v[28] = sub(v[28], 1)

v[29] = sub(v[29], 1)
v[29] = mul(v[29], 1000000)
v[29] = add(v[29], v[23])

v[30] = add(v[30], 1)
v[30] = mul(v[30], v[27])

v[31] = add(v[31], v[30])

flag = ''.join(chr(x & 0xff) for x in v)
print("CTF{" + flag + "}")

flag

CTF{daf8f4d816261a41a115052a1bc21ade}

一把梭

image