0x01 Andrénalin.2

我以为很简单,结果这个题做了好几个小时,先搜索字符串定位到关键代码处

这里可以直接爆破

但是上面的比较算法其实看不太懂怎么传参的,但是在栈里面翻到了正确密码

又在汇编窗口中看到了-符号,刚刚好是第4位和第9位替换了

再往上就追到了一个乘法,但是真的看不明白是啥

不知道最后的结果存哪去了,追也没追到,这里先放着,继续往上看

这里有个循环,按之前经验来看,这个循环一般来说就是算法,相当麻烦,但是,动调的时候,观察寄存器,它只是一个简单的循环用户名后的ascii值的叠加,在栈里面也能看到

目前就差这个乘法有点看不明白了,试过了ida,居然看不出来

最后绕来绕去,找到了一个可以反编译vb的程序VB Decompiler

好家伙,0x499602D2就是1234567890,那3有什么用呢,ai是这么说的,这个vb真是服了

再看一下计算的结果

和处理了一半的字符串是一样的

这样就验证了之前的思路是没问题的,可以写注册机了
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
int main() {
std::string username;
printf("用户名: ");
std::getline(std::cin, username);
int userLen = username.length();
int esi = 0;
for (int i = 0;i < userLen;i++) {
int eax = username[i];
esi += eax;
}
// 使用long long来避免溢出
long long result = (long long)esi * 1234567890;
// 将结果转换为字符串并填充前导零至12位
std::ostringstream oss;
oss << std::setw(12) << std::setfill('0') << result;
std::string resultStr = oss.str();
// 删除指定位置的字符(第4位和第9位,索引从0开始)
resultStr.erase(8, 1); // 先删除后面的位置(避免索引变化)
resultStr.erase(3, 1); // 再删除前面的位置
std::string formatted = resultStr.substr(0, 3) + "-" +
resultStr.substr(3, 4) + "-" +
resultStr.substr(7);
printf("key: %s", formatted.c_str());
return 0;
}

恶心,真的恶心啊

0x02 fireworx.2

没壳,是delph4丢ida导map后再放dbg里面分析,搜索字符串以后,看得是真方便

打个断点走一下,发现是5个字符的拼接,两遍用户名加上固定的625+g+72

注册机如下
#include <iostream>
#include <string>
int main() {
std::string username;
printf("用户名: ");
std::getline(std::cin, username);
printf("key: %s%s625g72", username.c_str(), username.c_str());
return 0;
}

搞定
