DosSnake_e

16位 DOS 程序,直接拖进 IDA:

先看字符串,有关键字符串 DASCTF,直接定位到代码部分:

取 DASCTF+6 处的字符串与 DASCTF 进行异或,直到全部处理完毕,看下这两处:

直接脚本解开(注意输出结果得逆序):

dasctf = [0x44, 0x41, 0x53, 0x43, 0x54, 0x46]  # "DASCTF"
encrypted_data = [
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x3F, 0x09, 0x63, 0x34, 0x32, 0x13, 0x2A, 0x2F, 0x2A, 0x37, 0x3C, 0x23, 0x00,
    0x2E, 0x20, 0x10, 0x3A, 0x27, 0x2F, 0x24, 0x3A, 0x30, 0x75, 0x67, 0x65, 0x3C]
​
def decrypt(dasctf, encrypted_data):
    decrypted_data = []
    dasctf_len = len(dasctf)
​
    for i in range(len(encrypted_data)):
        decrypted_byte = encrypted_data[i] ^ dasctf[i % dasctf_len]
        decrypted_data.append(decrypted_byte)
​
    return decrypted_data
​
decrypted_data = decrypt(dasctf, encrypted_data)
​
decrypted_string = ''.join(chr(byte) for byte in decrypted_data if byte != 0)
​
print(f"解密后的字符串: {decrypted_string}")
​
#DASCTF{H0wfUnnytheDosSnakeis!!!}

也有别的做法:

Strangeprograme

上来先发现一处假 flag:

定位过去,代码长这样:

程序逻辑显然是输入正确的 flag,然后比较后如果正确就通过,至少看上去是这样。但是这 flag 是假的,那就有问题啊,

显然问题出在这个 j_memcmp 函数上,使用附加调试,在 memcmp 上下断点,就可以发现 IAT 表被修改了,属于 IATHOOK,

真正的函数逻辑是:

__int64 __cdecl sub_41D250(char *Str)
{
  __int64 v1; // rax
  __int64 v3; // [esp-8h] [ebp-24Ch]
  int j; // [esp+D0h] [ebp-174h]
  size_t i; // [esp+F4h] [ebp-150h]
  char *v6; // [esp+100h] [ebp-144h]
  int v7; // [esp+124h] [ebp-120h] BYREF
  int v8; // [esp+128h] [ebp-11Ch]
  int v9; // [esp+12Ch] [ebp-118h]
  int v10; // [esp+130h] [ebp-114h]
  char v11[260]; // [esp+13Ch] [ebp-108h] BYREF
  int savedregs; // [esp+244h] [ebp+0h] BYREF
​
  sub_4114D8(&unk_4250F3);
  v11[0] = -7;
  v11[1] = 77;
  v11[2] = 43;
  v11[3] = -68;
  v11[4] = 19;
  v11[5] = -35;
  v11[6] = 19;
  v11[7] = 98;
  v11[8] = -55;
  v11[9] = -4;
  v11[10] = -1;
  v11[11] = -119;
  v11[12] = 125;
  v11[13] = 79;
  v11[14] = -55;
  v11[15] = 15;
  v11[16] = 99;
  v11[17] = 29;
  v11[18] = 109;
  v11[19] = 82;
  v11[20] = 80;
  v11[21] = -3;
  v11[22] = 65;
  v11[23] = -29;
  v11[24] = 51;
  v11[25] = 118;
  v11[26] = 40;
  v11[27] = -105;
  v11[28] = 56;
  v11[29] = 54;
  v11[30] = -7;
  v11[31] = 107;
  v11[32] = -112;
  v11[33] = 57;
  v11[34] = 20;
  v11[35] = -125;
  v11[36] = 44;
  v11[37] = -30;
  v11[38] = 44;
  v11[39] = 31;
  memset(&v11[40], 0, 216);
  v7 = 0;
  v8 = 0;
  v9 = 0;
  v10 = 0;
  if ( j_strlen(Str) == 40 )
  {
    v6 = Str + 4;
    v7 = *Str;
    v8 = *(Str + 1);
    sub_411541(&v7, &unk_422100);
    *Str = v7;
    *(Str + 1) = v8;
    for ( i = 2; i < j_strlen(Str) >> 2; i += 2 )
    {
      sub_411541(&v7, &unk_422100);
      *Str = v7;
      *v6 = v8;
      *&Str[4 * i] ^= *Str;
      *&Str[4 * i + 4] ^= *v6;
    }
    for ( j = 0; j < 40; ++j )
    {
      HIDWORD(v1) = j;
      if ( Str[j] != v11[j] )
      {
        LODWORD(v1) = 1;
        goto LABEL_12;
      }
    }
    LODWORD(v1) = 0;
  }
  else
  {
    LODWORD(v1) = 1;
  }
LABEL_12:
  v3 = v1;
  sub_41130C(&savedregs, &unk_41D5CC);
  return v3;
}

解题 exp:

int __cdecl sub_41D6F0(unsigned int *a1, _DWORD *a2)
{
  int result; // eax
  unsigned int i; // [esp+DCh] [ebp-2Ch]
  int v4; // [esp+E8h] [ebp-20h]
  unsigned int v5; // [esp+F4h] [ebp-14h]
  unsigned int v6; // [esp+100h] [ebp-8h]
​
  sub_4114D8(&unk_4250F3);
  v6 = *a1;
  v5 = a1[1];
  v4 = 0;
  for ( i = 0; i < 0x10; ++i )
  {
    v6 += (a2[1] + (v5 >> 5)) ^ (v4 + v5) ^ (*a2 + 16 * v5);
    v5 += (a2[3] + (v6 >> 5)) ^ (v4 + v6) ^ (a2[2] + 16 * v6);
    v4 -= 1640531527;
  }
  *a1 = v6;
  result = 4;
  a1[1] = v5;
  return result;
}int __cdecl sub_41D6F0(unsigned int *a1, _DWORD *a2)
{
  int result; // eax
  unsigned int i; // [esp+DCh] [ebp-2Ch]
  int v4; // [esp+E8h] [ebp-20h]
  unsigned int v5; // [esp+F4h] [ebp-14h]
  unsigned int v6; // [esp+100h] [ebp-8h]
​
  sub_4114D8(&unk_4250F3);
  v6 = *a1;
  v5 = a1[1];
  v4 = 0;
  for ( i = 0; i < 0x10; ++i )
  {
    v6 += (a2[1] + (v5 >> 5)) ^ (v4 + v5) ^ (*a2 + 16 * v5);
    v5 += (a2[3] + (v6 >> 5)) ^ (v4 + v6) ^ (a2[2] + 16 * v6);
    v4 -= 1640531527;
  }
  *a1 = v6;
  result = 4;
  a1[1] = v5;
  return result;
}
#include <stdio.h>
#include <stdint.h>
//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], i; 
    uint32_t delta=0x61C88647;  
    uint32_t sum=-delta*0x10;                 
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<0x10; i++) {                         /* basic cycle start */
        sum += 0x61C88647;
        v1 -= (k3 + (v0 >> 5)) ^ (sum + v0) ^ (k2 + v0 * 16);
        v0 -= (k1 + (v1 >> 5)) ^ (sum + v1) ^ (k0 + v1 * 16);
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}
​
​
 int main() {
    uint32_t key[]={ 0x12345678, 0x09101112, 0x13141516, 0x15161718 };
    uint32_t enc[40]={0xBC2B4DF9, 0x6213DD13, 0x89FFFCC9, 0x0FC94F7D, 0x526D1D63, 0xE341FD50, 0x97287633, 0x6BF93638, 
    0x83143990, 0x1F2CE22C};
    for (size_t i = 8; i >= 2; i-=2)
    {
        enc[i] ^= enc[0];
        enc[i+1] ^= enc[1];
        decrypt(enc,key);
    }
    decrypt(enc,key);
    puts((char*)enc);
    
}
​
#DASCTF{I4TH0ok_I5S0ooFunny_Isnotit?????}

BabyAndroid

还没看,有空再说