好久没写了,今天再灌一篇。
一个flash小游戏里的TEA算法,hack一把,结果发现,decompile出来的as,改成js运行后,得到的结果跟原游戏运算出的结果是不一样的。
心想难道js跟as有些差别?不得已,去下了一个adobe flash cs3。
发现自己快不会用flash了,还是flash5时学了几天,做了点皮毛,主要也是那时为了应付交了一下某堂课的作业。想起来当时那老师也很好心,这个flash作业给了我满分。
不过今天对flash cs3感觉 很不顺手了。一开始就遇到个问题 ,在cs3中如何使用外部类?直接写一个,报错误“类不能嵌套”,搜了一把是写在一个.as文件里,就写在一个TEA.as里。
加入代码 import TEA; 结果又报错,说TEA没有实现,查文档,原来说是要放到一个包(package)里。那就放吧,放完发现还是不对,最后看了一下flash自己的实现,终于整明白了。先建一个crypto的文件夹,在里面建个TEA.as,代码这样:
package crypto{ //crypto要跟文件夹名一致。
public class TEA{ //TEA跟文件名即TEA.as一致。public好像不能少。
…//省略
}
}
OK,可以运行了,然后发现,其实另存为flash 8的文档,就可以直接用不放在包里的TEA.as!晕倒。
运行发现,这个flash得到的结果跟html里的js算出来是一样的。敢情从下载flash起,事情就白做了。
最后没办法,回到sothink swf decompiler中,仔细看,看到一个疑点:
var _loc11 = 2.671213E+009;
为什么是这样呢?算法中不应有这样的代码。打开raw code,找到这一行:
//96 09 00 06 ef e6 e3 41 00 00 20 37
_push 2.67121e+009
对比一下其它的_push语句,发现ef e6 e3 41 00 00 20 37 是一个double值。
写个小程序:
debian:~# cat t2.c #include <stdio.h> int main() { double d = 2.67121e+009; unsigned char * p = (unsigned char*)&d; int i; for ( i=0; i<8; ++i) { printf("%02x ", p[i]); } printf("\n"); return 0; } debian:~# gcc t2.c debian:~# ./a.out 00 00 00 c2 ed e6 e3 41 |
对比00 00 00 c2 ed e6 e3 41 与ef e6 e3 41 00 00 20 37
只有一点儿不同,原double值应该是00 00 20 37 ef e6 e3 41
好,这样: printf(“%.14g\n”, *(double*)”\x00\x00\x20\x37\xef\xe6\xe3\x41″);
得到: 2671212985
这就是正确的原flash的设定值。
修改一下TEA.as:
var _loc11 = 2.671213E+009;改为:
var _loc11 = 2671212985;
再运行一把,成功!算出来的值跟原flash是一样的,可以互相加/解密。
总结一下:sothink swf decompiler太土,居然不会用最恰当的方法格式化double值。bs之。
另外把TEA.as贴出来,版权不归我所有,是RE出来的,原作者如果有意见,请聊系本人删除。
hilight不支持actionscript,当就是javascript好了,反正差不多。
贴的这个是flash8格式,在CS3中使 用要放入一个 package里,前面说过了。
class TEA { function TEA() { } // End of the function static function encrypt(src, key) { if (!key || key.length == 0) { key = "9F3779B99F3779B9"; } // end if var _loc4 = TEA.charsToLongs(TEA.strToChars(src)); var _loc9 = TEA.charsToLongs(TEA.strToChars(key)); var _loc8 = _loc4.length; if (_loc8 == 0) { return (""); } // end if if (_loc8 == 1) { _loc4[_loc8++] = 0; } // end if var _loc2 = _loc4[_loc8 - 1]; var _loc3 = _loc4[0]; var _loc11 = 2671212985; var _loc5; var _loc7; var _loc10 = Math.floor(6 + 52 / _loc8); var _loc6 = 0; while (_loc10-- > 0) { _loc6 = _loc6 + _loc11; _loc7 = _loc6 >>> 2 & 3; for (var _loc1 = 0; _loc1 < _loc8 - 1; ++_loc1) { _loc3 = _loc4[_loc1 + 1]; _loc5 = (_loc2 >>> 5 ^ _loc3 << 2) + (_loc3 >>> 3 ^ _loc2 << 4) ^ (_loc6 ^ _loc3) + (_loc9[_loc1 & 3 ^ _loc7] ^ _loc2); _loc2 = _loc4[_loc1] = _loc4[_loc1] + _loc5; } // end of for _loc3 = _loc4[0]; _loc5 = (_loc2 >>> 5 ^ _loc3 << 2) + (_loc3 >>> 3 ^ _loc2 << 4) ^ (_loc6 ^ _loc3) + (_loc9[_loc1 & 3 ^ _loc7] ^ _loc2); _loc2 = _loc4[_loc8 - 1] = _loc4[_loc8 - 1] + _loc5; } // end while return (TEA.charsToHex(TEA.longsToChars(_loc4))); } // End of the function static function decrypt(src, key) { if (!key || key.length == 0) { key = "9F3779B99F3779B9"; } // end if var _loc4 = TEA.charsToLongs(TEA.hexToChars(src)); var _loc9 = TEA.charsToLongs(TEA.strToChars(key)); var _loc8 = _loc4.length; if (_loc8 == 0) { return (""); } // end if var _loc2 = _loc4[_loc8 - 1]; var _loc3 = _loc4[0]; var _loc10 = 2671212985; var _loc6; var _loc7; var _loc12 = Math.floor(6 + 52 / _loc8); for (var _loc5 = _loc12 * _loc10; _loc5 != 0; _loc5 = _loc5 - _loc10) { _loc7 = _loc5 >>> 2 & 3; for (var _loc1 = _loc8 - 1; _loc1 > 0; --_loc1) { _loc2 = _loc4[_loc1 - 1]; _loc6 = (_loc2 >>> 5 ^ _loc3 << 2) + (_loc3 >>> 3 ^ _loc2 << 4) ^ (_loc5 ^ _loc3) + (_loc9[_loc1 & 3 ^ _loc7] ^ _loc2); _loc3 = _loc4[_loc1] = _loc4[_loc1] - _loc6; } // end of for _loc2 = _loc4[_loc8 - 1]; _loc6 = (_loc2 >>> 5 ^ _loc3 << 2) + (_loc3 >>> 3 ^ _loc2 << 4) ^ (_loc5 ^ _loc3) + (_loc9[_loc1 & 3 ^ _loc7] ^ _loc2); _loc3 = _loc4[0] = _loc4[0] - _loc6; } // end of for return (TEA.charsToStr(TEA.longsToChars(_loc4))); } // End of the function static function charsToLongs(chars) { var _loc3 = new Array(Math.ceil(chars.length / 4)); for (var _loc1 = 0; _loc1 < _loc3.length; ++_loc1) { _loc3[_loc1] = chars[_loc1 * 4] + (chars[_loc1 * 4 + 1] << 8) + (chars[_loc1 * 4 + 2] << 16) + (chars[_loc1 * 4 + 3] << 24); } // end of for return (_loc3); } // End of the function static function longsToChars(longs) { var _loc3 = new Array(); for (var _loc1 = 0; _loc1 < longs.length; ++_loc1) { _loc3.push(longs[_loc1] & 255, longs[_loc1] >>> 8 & 255, longs[_loc1] >>> 16 & 255, longs[_loc1] >>> 24 & 255); } // end of for return (_loc3); } // End of the function static function charsToHex(chars) { var _loc4 = new String(""); var _loc3 = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"); for (var _loc1 = 0; _loc1 < chars.length; ++_loc1) { _loc4 = _loc4 + (_loc3[chars[_loc1] >> 4] + _loc3[chars[_loc1] & 15]); } // end of for return (_loc4); } // End of the function static function hexToChars(hex) { var _loc3 = new Array(); for (var _loc1 = hex.substr(0, 2) == "0x" ? (2) : (0); _loc1 < hex.length; _loc1 = _loc1 + 2) { _loc3.push(parseInt(hex.substr(_loc1, 2), 16)); } // end of for return (_loc3); } // End of the function static function charsToStr(chars) { var _loc3 = new String(""); for (var _loc1 = 0; _loc1 < chars.length; ++_loc1) { _loc3 = _loc3 + String.fromCharCode(chars[_loc1]); } // end of for return (_loc3); } // End of the function static function strToChars(str) { var _loc3 = new Array(); for (var _loc1 = 0; _loc1 < str.length; ++_loc1) { _loc3.push(str.charCodeAt(_loc1)); } // end of for return (_loc3); } // End of the function } // End of Class |