好久没写了,今天再灌一篇。
一个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 |
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 |
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