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;
}
搞定