萌新第一次用 C++ 写 CM
输入正确密码后提示:实在看不懂 C++ 的语法,被大佬手撕已经习惯了{:1_937:}
Ki_Yo_Mi 发表于 2024-1-22 16:02
大佬,把我源码都扒出来了QAQ
用ida就能反编译了,这玩意用到随机数,算出具体的key有点烦{:301_976:}
不过给它判断逻辑jmp就能出现cracked了 // 主函数入口
_main(argc, argv, envp);
// 初始化一个名为Block的内存块,大小为24字节
memset(Block, 0, 24);
// 使用printf函数输出提示信息:"Please input password:"
printf((const char *)Block, v39, v3, "Please input password:");
// 使用scanf函数接收用户输入的密码
scanf((const char *)Block, v39, Block, "%[^\n]");
// 加载三个128位的数据块
v4 = _mm_loadu_si128((const __m128i *)&xmmword_140030070);
v5 = _mm_loadu_si128((const __m128i *)&xmmword_140030080);
v6 = _mm_loadu_si128((const __m128i *)&xmmword_140030090);
// 初始化一个字符串为"default",并将其地址和长度存储在v40数组中
strcpy(v41, "default");
v40 = (__int64)v41;
v40 = 7LL;
// 初始化一些变量和随机数引擎
v33 = 0LL;
v34 = 0LL;
v29 = v4;
v30 = v5;
v31 = v6;
std::random_device::_M_init(Block, v39, v40, v39);
// 如果v40的地址不等于v41的地址,则释放内存块
if ((char *)v40 != v41)
operator delete(Block);
// 获取随机数并初始化一个Mersenne Twister引擎
v7 = (unsigned int)std::random_device::_M_getval((std::random_device *)Block);
v8 = 1LL;
v40 = v7;
do
{
v9 = 0x5851F42D4C957F2DLL * (v7 ^ (v7 >> 62));
v7 = v9 + v8;
v40 = v9 + v8;
++v8;
} while (v8 != 312);
// 生成312个随机数
v42 = 312LL;
std::mersenne_twister_engine<unsigned long long, 64ull, 312ull, 156ull, 31ull, 13043109905998158313ull, 29ull, 6148914691236517205ull, 17ull, 8202884508482404352ull, 37ull, 18444473444759240704ull, 43ull, 6364136223846793005ull>::_M_gen_rand(
Block,
v39,
312LL,
v40,
0x5851F42D4C957F2DLL);
// 使用生成的随机数进行一系列操作
v11 = v40;
v12 = (((v11 >> 29) & 0x5555555555555555LL ^ v11) << 17) & 0x71D67FFFEDA60000LL ^ (v11 >> 29) & 0x5555555555555555LL ^ v11;
v13 = (0x100 * (unsigned __int128)((((v12 << 37) & 0xFFF7EEE000000000LL ^ v12) >> 43) ^ (v12 << 37) & 0xFFF7EEE000000000LL ^ v12)) >> 64;
// 初始化一些变量和寄存器
v14 = 0LL;
v15 = v13;
v32 = _mm_shuffle_epi32(_mm_cvtsi32_si128(v13), 0);
v29 = _mm_xor_si128(v4, v32);
v30 = _mm_xor_si128(v5, v32);
v31 = _mm_xor_si128(v6, v32);
v33 = v32;
v34 = v32;
// 检查密码输入是否正确
do
{
if (v29.m128i_i32 != ((unsigned int)v13 ^ *((char *)Block + v14)))
{
// 如果密码错误,初始化一些变量并输出错误信息
v16 = Command;
v17 = 15LL;
v18 = _mm_loadu_si128((const __m128i *)&xmmword_1400300A0);
while (v17)
{
*(_DWORD *)v16 = 0;
v16 += 4;
--v17;
}
v37 = 10;
v35 = v18;
v36 = _mm_loadu_si128((const __m128i *)&xmmword_1400300B0);
goto LABEL_12;
}
++v14;
} while (v14 != 24);
// 如果密码正确,加载一些变量并输出一些信息
v20 = _mm_loadu_si128((const __m128i *)&xmmword_1400300A0);
v21 = Command;
v37 = 10;
v22 = 15LL;
v23 = (char *)&v35;
while (v22)
{
*(_DWORD *)v21 = 0;
v21 += 4;
--v22;
}
v35 = v20;
v16 = (char *)&unk_140030000;
v36 = _mm_loadu_si128((const __m128i *)&xmmword_1400300B0);
do
{
// 输出一些信息
printf(
(unsigned int)&unk_140030000,
(unsigned int)v39,
*(_DWORD *)v23,
(unsigned int)&unk_140030000,
v15,
v10,
v24,
v25,
v26,
v27);
v23 += 4;
} while (v39 != v23);
// 执行系统命令
LABEL_12:
system(v16);
// 结束随机数生成
std::random_device::_M_fini((std::random_device *)v16);
// 返回0表示程序正常结束
return 0;
cattie 发表于 2024-1-22 15:43
// 主函数入口
_main(argc, argv, envp);
大佬,把我源码都扒出来了QAQ{:1_893:} cattie 发表于 2024-1-22 16:15
用ida就能反编译了,这玩意用到随机数,算出具体的key有点烦
不过给它判断逻辑jmp就能出现cr ...
那这种该怎么防止呢,把验证密码的逻辑弄得更复杂吗 Ki_Yo_Mi 发表于 2024-1-22 16:17
那这种该怎么防止呢,把验证密码的逻辑弄得更复杂吗
加VMP之类的强壳,那个也只是减缓分析进程(不过脱壳以后也是这样的)
目前没有绝对安全的阻止措施。 cattie 发表于 2024-1-22 16:20
加VMP之类的强壳,那个也只是减缓分析进程(不过脱壳以后也是这样的)
目前没有绝对安全的阻止措施。
好的,谢谢大佬指点{:301_993:}
没有混淆和vmp,所以分析起来比较清晰
本帖最后由 Ki_Yo_Mi 于 2024-1-22 16:47 编辑
lianquke 发表于 2024-1-22 16:40
没有混淆和vmp,所以分析起来比较清晰
大佬厉害{:301_993:},不过每次执行都有一个随机数,难道是直接扒了前面那段数组?
页:
[1]
2