破解 4399 古剑奇侠 网页游戏
这混蛋页游的加密真是蛋疼。简单说,用了对称加密,但是key要从php获取,我模拟http请求确获取不到。
先拿到LDLoader,找到:
private function loadFile() : void { var _loc_3:String = null ; var _loc_4:String = null ; var _loc_5:BigInteger = null ; var _loc_6:String = null ; var _loc_7:BigInteger = null ; var _loc_8:URLRequest = null ; var _loc_9:URLVariables = null ; var _loc_1:* = loaderInfo.parameters; var _loc_2:* = int (Math.random() * 5000 + 3000); this .daba = new BigInteger(_loc_2.toString(16)); this .pawa = new BigInteger(_loc_1.P); //21a1 this .wodA = new BigInteger(_loc_1.A); //5b2 _loc_8 = new URLRequest( "get_dec.php" ); _loc_8.method = URLRequestMethod.POST; _loc_9 = new URLVariables(); _loc_6 = _loc_1.KEY; //gjqx_key_pre_7 _loc_9.KEY = _loc_6; //gjqx_key_pre_7 _loc_5 = new BigInteger(_loc_1.G); //dd _loc_7 = _loc_5.modPow( this .daba, this .pawa); //175e m _loc_9.B = _loc_7.valueOf(); //1765 _loc_8.data = _loc_9; this ._urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES; this ._urlLoader.addEventListener(Event.COMPLETE, this .phpCompleteHandler); this ._urlLoader.addEventListener(IOErrorEvent.IO_ERROR, this .ioErrorHandler); this ._urlLoader.load(_loc_8); _loc_5.dispose(); _loc_5 = null ; _loc_7.dispose(); _loc_7 = null ; this ._ping = this ._ping + "ke" ; return ; } // end function |
这段代码就是获取key的。其中他又从swf的参数获取了3个babamama什么的。
public function startUp(param1:ByteArray, param2:String, param3: int ) : void { var k:BigInteger; var mk:String; var data:* = param1; var key:* = param2; var swfLen:* = param3; var mm:* = key; k = this .wodA.modPow( this .daba, this .pawa); this .appendText( "\nk:" + k.valueOf()); mk = MD5.hash(k.valueOf().toString()); k.dispose(); this .appendText( "\nmd5:" + mk); mm = this .getFileName( this ._keylab, mk); this ._okeymama = this .getFileName( this ._okeymama, mk); this .wodA.dispose(); this .daba.dispose(); this .pawa.dispose(); this .appendText( "\nmd5Encrypt:" + mm); this .appendText( "\nmd_okey:" + this ._okeymama); try { data = BytesCrypt.getInstance().decryptBytes(data, mm, 2000); this .loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this .completeHandler); this .loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this .errorHandler); this .loader.loadBytes(data, new LoaderContext( false , ApplicationDomain.currentDomain)); } catch (err:Error) { appendText( "BytesCrypt error" ); } return ; } // end function |
这段代码破解GameEntry.swf的。
下面开始破解:
CrackHelper.loadByteArray( '../GameEntry.swf' , function(path:String, byte :ByteArray): void { this ._keylab = 'vCFWJ8YwoftT9A==' ; for ( var k: int = 0;k<9999;k++) { var b:ByteArray = new ByteArray; b.writeBytes( byte , 0, byte .length); var mk = MD5.hash(k.valueOf().toString()); var mm = getFileName( this ._keylab, mk); try { b = BytesCrypt.getInstance().decryptBytes(b, mm, 2000); } catch (e:Error) { continue ; } if (b.length <= 50000000 && b.length > 0) trace(k, mm, byte .length); } trace( 'done' ); }); |
破解完毕。
基本上他用php返回的K,+本地一个随机数modPOw运算得到的子进行混合得到解密的des秘钥。但是郁闷的是我无法模拟php请求,所以我穷举了。正好这个算法的范围不超过9999.所以找到:
2534 íG*i@öÎí 185482
3414 j8G3LgWk3h 185482
各位明白了把。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述