no-strings-attached

使用die查看,发现是32位的
image

使用32位的ida打开,f5反编译
image

得到核心函数调用链

main → setlocale(宽字符适配)→ banner(干扰项)→ prompt_authentication(输入提示)→ authenticate(核心认证)

查看authenticate函数
image

可以知道我们需要的秘钥就是s2
s2通过&s和&dword_8048A90传入decrypt()函数计算得出
查看decrypt函数
image

分析代码

wchar_t *__cdecl decrypt(wchar_t *s, wchar_t *a2)
{
  size_t v2; // eax
  signed int v4; // [esp+1Ch] [ebp-1Ch]
  signed int i; // [esp+20h] [ebp-18h]
  signed int v6; // [esp+24h] [ebp-14h]
  signed int v7; // [esp+28h] [ebp-10h]
  wchar_t *dest; // [esp+2Ch] [ebp-Ch]

  v6 = wcslen(s); //密文长度
  v7 = wcslen(a2); //密文长度
  v2 = wcslen(s); //再次获得密文长度
  dest = (wchar_t *)malloc(v2 + 1); 
  wcscpy(dest, s); //将密文复制到dest
  while ( v4 < v6 ) //遍历所有密文字符
  {
    for ( i = 0; i < v7 && v4 < v6; ++i ) // 循环使用秘钥
      dest[v4++] -= a2[i]; //每个字符减去对应的秘钥字符
  }
  return dest;
}

所以加密逻辑就是:密文字符=明文字符+秘钥值

s和a2分别代表传进来的&s和&dword_8048A90
回到authenticate函数,点击&s和&dword_8048A90获得他们的值
image
image

所以

s = [':', '6', '7', ';','\x80', 'z', 'q','x', 'c', 'f', 's','g', 'b', 'e', 's','`', 'k', 'q', 'x','j', 's', 'p', 'd','x', 'n', 'p', 'p','d', 'p', 'd', 'n','{', 'v', 'x', 'j', 's', '{', '\x80']

a2 = [1, 2, 3, 4, 5]

解密逻辑就是:密文字符-密钥值=明文字符
示例:
第一个密文:的ascll码是58,所以第一个明文字符=58-1=57-->9
第二个密文6的ascll码是54,所以第二个明文字符=54-2=52-->4
以此类推

写一个解密脚本

s = [':', '6', '7', ';', '\x80', 'z', 'q', 'x', 'c', 'f', 's',
     'g', 'b', 'e', 's', '`', 'k', 'q', 'x', 'j', 's', 'p', 'd',
     'x', 'n', 'p', 'p', 'd', 'p', 'd', 'n', '{', 'v', 'x', 'j', 's', '{', '\x80']
a2 = [1, 2, 3, 4, 5]
result = ''.join(chr(ord(s[i]) - a2[i%5]) for i in range(len(s)))
print(f"\n解密结果: {result}")

image

posted @ 2026-03-07 00:55  大雪深埋  阅读(3)  评论(0)    收藏  举报