逆向玩家狂喜!用C++野生写法一键破解线性加密(不规范但巨好用)
文章目录
作为常年和游戏逆向、数值加密打交道的野生程序员,今天不聊规范、不聊设计模式,纯分享一段"反套路"的C++野生代码------看似乱七八糟、不符合编码规范,却能精准解决逆向中最常见的线性加密破解问题,扔两组数据进去,自动算出k和b,爽到飞起!
先上核心代码,直接感受一下什么叫"野路子出奇迹":
cpp
#include<iostream>
struct pair {
int m;
int n;
};
struct pairs {
pair p1;
pair p2;
// 类型转换运算符,强行算斜率k(完全不按语义来)
operator int() {
return static_cast<double>(p2.n - p1.n) / (p2.m - p1.m);
}
// 括号运算符,强行算截距b(靠*this白嫖k的值)
int operator()() {
return -(*this * p1.m - p1.n);
}
};
int main() {
int s = 0;
// 两遍重复写法,不复用但够用
std::cout << (s = pairs({1, 18}, {2, 29})) << std::endl;
std::cout << (s = pairs({1, 18}, {2, 29})()) << std::endl;
return 0;
}
// 运行结果:
// 11
// 7
运行结果直接出k=11、b=7,对应线性加密公式y=11x+7------没错,就是这么粗暴,这么直接,哪怕代码写得"一塌糊涂",功能却精准命中需求。
先吐槽:这段代码有多"不规范"?
懂C++的朋友一眼就能看出问题,放在企业评审里绝对直接打回,放在课本里老师能气晕:
-
命名极不规范:pair、pairs命名太随意,m、n变量完全看不出是x、y坐标,可读性为0;
-
运算符滥用:类型转换运算符(operator int())本来是用来转换对象类型,我硬用来算斜率k;括号运算符(operator())本来是函数调用,我硬用来算截距b,符号和功能完全不搭边;
-
完全不复用:计算k和b时,重复计算差值,没有抽取公共函数;打印时,一模一样的构造和参数写了两遍,纯纯"硬怼";
-
类型强转随意:static_cast<double>看似合理,但整体写法缺乏严谨性,纯属"能跑就行"。
但!重点来了------对于逆向玩家来说,这些"不规范"根本不重要,重要的是:它能解决问题,而且足够简单、足够快。
再膜拜:这段野生代码到底牛在哪?
这段代码的核心,是我为了破解游戏线性加密(y=kx+b),硬生生把数学消元法塞进了C++结构体里,主打一个"顺手就来",藏着两个野生黑魔法:
黑魔法1:运算符滥用=一键算k
游戏逆向中,我们经常能拿到两组明文-密文对应关系(比如x1,y1、x2,y2),要手动算k=(y2-y1)/(x2-x1),麻烦又容易算错。
我直接滥用类型转换运算符,把结构体对象转成int时,自动执行斜率计算:
cpp
operator int() {
return static_cast<double>(p2.n - p1.n) / (p2.m - p1.m);
}
只要构造pairs对象时传入两组(x,y),直接用对象本身就能拿到k值------比如pairs({1,18},{2,29}),转成int就等于11,省了手动计算的麻烦。
黑魔法2:*this链式调用=白嫖k算b
算b需要用到已经算出的k,正常写法是抽个变量存k,再代入公式b=y1 -k*x1。但我懒,不想多写变量,直接用了链式调用的思路------*this。
在括号运算符里,*this会自动触发上面的类型转换运算符,也就是自动算出k,然后直接代入公式:
cpp
int operator()() {
return -(*this * p1.m - p1.n);
}
拆解一下:this就是k,代入公式b = -(kx1 - y1)(等价于b=y1 -k*x1),一步算出b=7。
这里的this,根本不是正经的链式调用,而是我"偷梁换柱",硬生生把链式调用的语法,改成了数学计算的工具------别人用this连点函数,我用*this连算公式。
核心场景:逆向线性加密的"懒人神器"
为什么要写这么一段"野生代码"?因为在游戏逆向中,99%的数值加密都是线性加密(y=kx+b),原因很简单:二次及以上多项式会出现多解,游戏无法精准还原数值(比如y=x²,y=4对应x=2和x=-2,游戏不知道该取哪个)。
我们只要拿到两组明文-密文对应关系,用这段代码,不用手动解方程,不用写多余逻辑,运行一下就能拿到k和b,直接扒出加密公式------对于逆向玩家来说,够用、够快,比什么都重要。
比如我之前遇到的游戏加密,拿到(1,18)和(2,29)两组数据,用这段代码一秒算出y=11x+7,后续不管遇到什么密文,都能直接还原明文,效率拉满。
最后:野生写法的真谛------不追求完美,只追求实用
很多程序员会纠结代码规范、复用性、可读性,但对于我们逆向玩家、对于自用工具来说,"能解决问题"才是第一优先级。
这段代码,我写的时候完全是"碰运气":随便蒙了个运算符重载,随便用*this白嫖k值,甚至重复写了两遍打印代码,但它能跑、能算对、能帮我快速破解加密------这就够了。
当然,不建议在商用项目中这么写(会被同事打),但作为自用工具、逆向神器,这种野生写法真的香!
最后再放一遍核心代码,感兴趣的逆向小伙伴可以直接复制用,亲测好用:
cpp
#include<iostream>
struct pair {
int m; // x坐标
int n; // y坐标
};
struct pairs {
pair p1; // 第一组(x1,y1)
pair p2; // 第二组(x2,y2)
// 算斜率k
operator int() {
return static_cast<double>(p2.n - p1.n) / (p2.m - p1.m);
}
// 算截距b
int operator()() {
return -(*this * p1.m - p1.n);
}
};
int main() {
// 传入两组(x,y),依次输出k和b
std::cout << pairs({1, 18}, {2, 29}) << std::endl;
std::cout << pairs({1, 18}, {2, 29})() << std::endl;
return 0;
}
如果你们也有这种"不规范但巨好用"的野生代码,欢迎在评论区交流,一起解锁C++的奇奇怪怪用法~