12345

本地调试

挂代理,让所有网络请求走代理

在代理软件里面,拦截返回值

替换返回值

动态更改代码


md5 加密 32,16
sh1 40

定位关键字办法、
1 搜索
定位关键词 比较准确,搜索的位置多,自己进行筛选,容易搜不到

2 dom 事件

定位的位置比较靠前,可以通过删除事件的方式定位具体函数

用户明文 -> 经过一些办法->加密函数->拼装封包-》发包函数->浏览器的发包函数

元素 --时间监听器 --找点击事件点开代码 (可以删除一些监听器来判断是否是找对了事件位置)

3 xhr 断点

好处:定位的位置在发包函数 ,我们可以跟堆栈
坏处:只能用户xhr 的包

只能断掉xmlhttprequest 发包
不能断开html 表单发包

方法1 发包 ,找请求特征码
https://passport.gm99.com/login/login3?callback=jQuery171043825104545353954_1636722828440&encrypt=1&uname=15222222&password=H8VnhTvbucTZhBRyUqYtuX4QLq%252Ft11ArNsYQCZw3h2lVHPL9M8xAxtH%252BYkeGjn%252BPB1fiQ2qj7N0ZRMKrzZmAOVEsPKryEZp7qAYG4WMTDiFidwspIiFcq0bSYV2aeV0rTz%252BEahw3drRZnxLis2RWyxnU6juKo5T7PyPFPuhDqUM%253D&remember=&ckcode=8y8u&_=1636723443459
特征码: login/login3 (网络请求抓包后的路径,问候前面的路径)
打开 “源代码” 在右侧调试窗口 ,在XHR/提取断点里面添加 特征码

可以搜索open 函数定位ajax


方法 2 在network 面板抓包

在确定连接上,鼠标停止在发起程序上 ,找到第一个js,点击进去,设置断点,通过调试器堆栈来跟踪

js hook 的三种方法
1 方法覆盖
function xxx()
{
console.log("111");

}

xxx=function()
{
console.log("222");
}

2 覆盖方法,保留方法

function xxx()
{
console.log("111");
}

var xxxx=xxx;
xxx=function()
{
console.log("222");
}

3 覆盖浏览器环境的方法

window.alert=function(){console.log("?");}

hook 有时机的

Object.defineProperty 替换一个对象属性
属性可能是方法,后者一个值(geter ,seter)

(function() {
//严谨模式 检查所有错误
'use strict';
//document 为要hook的对象 这里是hook的cookie
var cookieTemp = "";
Object.defineProperty(document, 'cookie', {
//hook set方法也就是赋值的方法
set: function(val) {
//这样就可以快速给下面这个代码行下断点
//从而快速定位设置cookie的代码
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
//hook get方法也就是取值的方法
get: function()
{
return cookieTemp;
}
});
})();


document.cooke="1" //设置时出发,hook执行 ,点vm 可以看到console.log 断点

控制台刷新,js失效
二 hook 时机
1 在控制台注入hook 刷新失效
在网页加载丢一个js的位置,下断点,然后控制台输入hook
(可能注入时间会晚)
2 利用fd的替换向阳,注入hook

 

4 通过返回值来判断定位
https://www.to8to.com/new_login.php
1 复制帐号登陆返回信息查找定位连接(用户或密码错误!)
2 找到连接关键词,在元素中查找函数( https://www.to8to.com/new_login.php 其中new_login 是关键词)
3 通过连接上的的事件函数定位,再次查找(在元素找关键词new_login,找到from 上的clickcheck 等事件)
4 继续通过clickcheck,在下面艘索框里找js

js 本地调试

https://static.to8to.com/gb_js/to8torsaszb.js?_=1636819920120

类似后缀带时间抽得js , 无法下断点,页面刷新就消失

使用fd的AutoResponder

1抓包连接,点addrole

2 rule Editor

保存网站js 保存本地

写正则
选择本地js地址
regex:https://static\.to8to\.com/gb_js/to8torsaszb\.js\?_=\d+
C:\Users\Administrator\Desktop\js\1.js

3 在本地js 里面输入debuger:

刷新页面后断点断下


md5 拔算法
var _hex_md5;
!(function()
{
var hex_md5=function()
{
console.log("111");

}
_hex_md5=hex_md5;
}

)()

控制台输入
_hex_md5()

var _hex_md5;
!(function()
{
var j={
hex_md5:function()
{
console.log("111");
}
}
_hex_md5=j;
})()

控制台输入
_hex_md5.hex_md5()



扣代码

1 webpack

function(x)
{
function xx(yy)
{
x(yy).call(xxx,xxx,xxx);// 必有一个加载模块的方法 call,apply
}
xx(0)// 函数1 xx(1);
}(
[function(){},function(){}]
)

扣代码方法 1 找加载器(加载模块方法) 2 找到一个调用模块 3 构造一个自执行


js 你想常规流程

抓包
调试js
扣取js
1 扣全
2 this 对象是谁
例子1
var zhiyuan={
name:"zhiyuan",
md5:function()
{
return "";

},

md1:function()
{

}

}
改写
var md5= function()
{
return "";

}

方法2 改成例子1,形式

方法3 搜索zhiyuan,如果 搜索到全局zhiyuan ,看调用方法 ,包全部js,用函数调用

方法4 导出函数

var zhiyuan={
name:"zhiyuan",
md5:function()
{
return "";

}
window.md5=md5;

var md=md1:function()
{

}

}
运行
md5("111");

改写
本地运行出值
本地请求服务器出值

常见加密方式

取盐 加密方式,不可逆 crc 校验方式
md 系列 md1 md2 md4 带密码的m5 (hmac)

md5 (16,32,40) 默认填充值 key :0123456789agcdef

123456 加密
16位 49ba59abbe56e057
32位 e10adc39 49ba59abbe56e057 vf20f883e

123456 加密
sha sha256 sha512
40 64 128

7c4a8d09ca3762af61e59520943dc26494f8941b

对称加密(同一个秘要去解出明文)
aes des 3des

非对称加密 (同一个明文可以生成不同的密文,不同的密文可还原相同密文)
rsa (私钥 公钥)

1 16进制 (长度不是md,和sha 的长度,最大字母只到了0-9 a-f 例如123456 aes 加密 0be6b89ce0c263215d95fee4cb54d0)

2 base64 AL5riQzgwmMhXZX+5MtU0A== (A- Z a -z + _=)

 

 

js 混淆、原理

混淆变量名
混淆代码流程

btoa("zhiyuan")
"emhpeXVhbg=="


btoa("pcm")
"cGNt"
//以上控制台编码

var xxx=['emhpeXVhbg==','cGNt'];
function x1(id)
{
return atob(xxx[id]);
}
var zhiyuan="1";
var pcm="2";
console.log(window[x1(1)]);

eva 中的代码可以被完全btoa ,


sojson 里面的aa,oo ,jj混淆通用解决办法

设置尾部断点,重新定义eval 和Function 函数

eval=function(){debugger;}

Function=function(){debugger;}

断点断到以上两个函数上

然后输入 arguments 输出混淆的原来代码参数,和函数内容
如果失败,发现Function 一直是navite code

给选中的产生Function 的代码重写function

(゚Д゚)['_']=function(){debugger;}
然后产生 断点后
输入 arguments


js fuck

1 任何字符串+任意数据类型都是字符串 如 []+“”
2 true,false 与|返回true或者false

 


伪造的基础 浏览器和js关系

1 扣取js 删除环境的一些代码
2 伪造环境,伪造代码

简单的网站 扣js就行
复杂的网站 伪造环境可以解决


1 为什么要伪造
a 全部伪造 python jsdom (被检测) node.js (被检测)
b 给指定网站 伪造
如何知道网站检测了什么

1 通过看代码,
2 通过调试,全局异常捕获
3 本地环境报错



2 如何伪造 学员群 domwindow

 

反调试基础

检测是否在调试

1 键盘监听 如f12
2 检测浏览器内外的宽度差
3 检测开发者工具是否是true
4 console.log 是否被调用
5 代码的时间差
6 利用tostring()
7 检测站的层数 caller

 

分类
显示
debugger

虚拟机 eval, Function
var AA=Function.prototype.constructor;

Function.prototype.constructor=function(x)
{
if(x!="debugger")
{
return aa(x);
}
return function(){};

}//替换相同长度字符串

//过反调试

var _constructor = constructor;

Function.prototype.constructor = function(s) {

if (s == "debugger"){

console.log(s);

return null;

}

return _constructor(s);

}

非虚拟机 1 条件断点 false 2 直接替换代码 a 浏览器直接提供重写 :1 sources -〉override -> 选择一个文件夹,2 右键选择在线一个js文件 -〉save and override (出现紫色帐号) ,修改本地代码
3 hook 掉调用函数
死循环, 无限循环, 无限digui,计时器


打开新页面,写你的历史url
for(;;)
while(true)

隐性
引导错误逻辑

提交数据看是否正常,不行察看浏览器堆栈

http://www.sc.10086.cn/service/login.html

1 手工调试堆栈,hook 调用的debuger 的函数
2 var AA=Function.prototype.constructor;

Function.prototype.constructor=function(x)
{
if(x!="debugger")
{
return aa(x);
}
return function(){};

}

群内阿布插件


文件格式

xml ,json,文本

自定义格式

字节码 protobuf(游戏),tlv(通用)

套接字 tcp/dup (粘包)


websocket 笔记
http://kedou.workerman.net/


刷新页面 ,netwoke 筛选ws ,在消息里面可以看到服务器和客户端时刻发送消息


绿色表示服务器向客户端发送的消息

红色表示客户端向服务端发送的消息
请求 URL: ws://kedou.workerman.net:8280/

请求头
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: APuglZ0zwwd0eaCNvWuGYw== (随便写,只是个标示符)
Sec-WebSocket-Version: 13
Upgrade: websocket


Connection: Upgrade
Sec-WebSocket-Accept: LJOoa1Jh/kqbx1mEeVM6SuWFlPk= (服务器随生成)
Sec-WebSocket-Version: 13
Upgrade: websocket

webSocket = new WebSocket( model.settings.socketServer );
webSocket.onopen = app.onSocketOpen;
webSocket.onclose = app.onSocketClose;
webSocket.onmessage = app.onSocketMessage;

webSocketService = new WebSocketService(model, webSocket);



webSocke 不是v8引擎自带的,本身是个关键词
var socket =new webSocket(url,[protocol]);

webSocket 事件
socket.readystate

socket.onopen
socket.onmessage
socket.send

下断点 关键词 onopen,

https://www.huya.com/11633312


websocket hook 实践
1 搜索下断,搜很多
2 找到websocket( ,hooksend 方法
假设 p 是socket 对象
p.send_=p.send;

p.send=function(x)
{ debugger;
return p.send_(x);
}

 

js hook

连接服务器 拿回资源 渲染(解析) 资源 (js执行流程)

初始化(自执行) 页面逻辑 等待用户输入 加密数据 提交数据

在上面流程任意环节 拆入自己代码 让浏览器县执行自己的代码

然后再执行自己代码


作用域-〉变量产生的位置

上下文= 环境变量 (js v8虚拟机) (浏览器 新页面)

this 指向问题
全局作用域 this=window
方法作用域 this=调用者
类作用域 this=自己

hook=改变原方法或者原来的执行流程
覆盖原方法
es6 语法 object.defineProperty
给对象重新定义属性
监听属性的设置值 和获取值

proxy
给对象整体监听
属性初始化
设置值和获取值
构造函数

hook ajax

XMLHttpRequest.prototype.send=function(){debugger}

debuer 中断后,看堆栈 找出发包前数据

hook 时机
hook 只影响hook 完成后的操作

如果想网页初始化进行hook

油猴 或者fideer fiider 会在 httpreponse 最前面插入 js



如果遇到抓包遇到察看不了js, 开启fideer代理 会帮忙缓存 然后再开始断点跟踪
案例 https://bqcm0.cavip1.com/

定义方法三种方式 function functionname , var functionname ,functionname:


vscode 配置 无环境浏览器调试
安装 node inspecet, 配置 launch.json,
开启浏览器 实验入口


浏览器内存漫游解决方案 (根据参数结果,找跟踪位置)
ast-hook-for-js-RE

1 node 版本必须在14.0 以上、
2 安转项目依赖 cd 到项目目录 npm install
3 启动服务 anyproxy ca //启动代理服务 8001 代理端口,8002 开启的管理工具的端口
4 浏览器输入 127.0.0.1:8002 //进入代理管理工具
5 下载证书 安装证书
6 cd 到 proxy-server 运行 node proxy-server.js (运行后最小化窗口不要动)

7打开网站 ,开启proxy-server 代理地址(10086), f12抓包 ,找到参数结果 ,在控制台输入hook.search("xxx")


ast 插件 babel https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/README.md

npm install --save '@babel/core'


自主练习
hook hookdebuger

Function.prototype.constructor_=Function.prototype.constructor;

Function.prototype.constructor=function(x)
{

debugger;

return Function.prototype.constructor_(x);

}


window.setInterval_=setInterval;

setInterval=function(x,x2)
{
if(x2!=0x7d0) //0x7d0 实际代码为准
{
return window.setInterval_(x,x2);
}
}

//注意,就算hook了,setinterval还是会一直执行,这时候在 setinterval 设置断点,刷新网页,然后2个hook 一起输入console (或者fidder 用hook插件,输入js,挂代理,开启)

 


wroker 多线程


https://developer.mozilla.org/zh-CN/docs/Web/API/Worker

http://www.ruanyifeng.com/blog/2018/07/web-worker.html


不可混淆关键词 worker, onmessage ,postmessage, self

1 主线程不能直接调用自线程方法,只能发消息
2 主线程调试看不到子线程,子线程调试可以调试主线程
main.js
console.log("主线程启动");
var worker = new Worker('worker.js');
worker.postMessage('Hello World');
worker.onmessage=function(event)
{

console.log("revied mesage"+event.data);

}


worker.js

console.log(self);
self.addEventListener('message', function (e) {
console.log(e.data+"1");
self.postMessage(e.data+"1");
}, false);

//Y29uc29sZS5sb2coc2VsZik7IA0Kc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGUpIHsNCiAgICBjb25zb2xlLmxvZyhlLmRhdGErIjEiKTsNCglzZWxmLnBvc3RNZXNzYWdlKGUuZGF0YSsiMSIpOw0KfSwgZmFsc2UpOw0K
调试 worker 伪造环境,把多线程改成单线程

var CryptoJS=CryptoJS||(function (Math, undefined) {
var C = {};
var C_lib = C.lib = {};
var Base = C_lib.Base = (function () {
function F() {};
return {
extend: function (overrides) {
F.prototype = this;
var subtype = new F();
if (overrides) {
subtype.mixIn(overrides);
}
if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
subtype.init = function () {
subtype.$super.init.apply(this, arguments);
};
}
subtype.init.prototype = subtype;
subtype.$super = this;
return subtype;
}, create: function () {
var instance = this.extend();
instance.init.apply(instance, arguments);
return instance;
}, init: function () {}, mixIn: function (properties) {
for (var propertyName in properties) {
if (properties.hasOwnProperty(propertyName)) {
this[propertyName] = properties[propertyName];
}
}
if (properties.hasOwnProperty('toString')) {
this.toString = properties.toString;
}
}, clone: function () {
return this.init.prototype.extend(this);
}
};
}());
var WordArray = C_lib.WordArray = Base.extend({
init: function (words, sigBytes) {
words = this.words = words || [];
if (sigBytes != undefined) {
this.sigBytes = sigBytes;
} else {
this.sigBytes = words.length * 4;
}
}, toString: function (encoder) {
return (encoder || Hex).stringify(this);
}, concat: function (wordArray) {
var thisWords = this.words;
var thatWords = wordArray.words;
var thisSigBytes = this.sigBytes;
var thatSigBytes = wordArray.sigBytes;
this.clamp();
if (thisSigBytes % 4) {
for (var i = 0; i < thatSigBytes; i++) {
var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
}
} else if (thatWords.length > 0xffff) {
for (var i = 0; i < thatSigBytes; i += 4) {
thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
}
} else {
thisWords.push.apply(thisWords, thatWords);
}
this.sigBytes += thatSigBytes;
return this;
}, clamp: function () {
var words = this.words;
var sigBytes = this.sigBytes;
words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
words.length = Math.ceil(sigBytes / 4);
}, clone: function () {
var clone = Base.clone.call(this);
clone.words = this.words.slice(0);
return clone;
}, random: function (nBytes) {
var words = [];
var r = (function (m_w) {
var m_w = m_w;
var m_z = 0x3ade68b1;
var mask = 0xffffffff;
return function () {
m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask;
m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask;
var result = ((m_z << 0x10) + m_w) & mask;
result /= 0x100000000;
result += 0.5;
return result * (Math.random() > .5 ? 1 : -1);
}
});
for (var i = 0, rcache; i < nBytes; i += 4) {
var _r = r((rcache || Math.random()) * 0x100000000);
rcache = _r() * 0x3ade67b7;
words.push((_r() * 0x100000000) | 0);
}
return new WordArray.init(words, nBytes);
}
});
var C_enc = C.enc = {};
var Hex = C_enc.Hex = {
stringify: function (wordArray) {
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var hexChars = [];
for (var i = 0; i < sigBytes; i++) {
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
hexChars.push((bite >>> 4).toString(16));
hexChars.push((bite & 0x0f).toString(16));
}
return hexChars.join('');
}, parse: function (hexStr) {
var hexStrLength = hexStr.length;
var words = [];
for (var i = 0; i < hexStrLength; i += 2) {
words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
}
return new WordArray.init(words, hexStrLength / 2);
}
};
var Latin1 = C_enc.Latin1 = {
stringify: function (wordArray) {
var words = wordArray.words;
var sigBytes = wordArray.sigBytes;
var latin1Chars = [];
for (var i = 0; i < sigBytes; i++) {
var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
latin1Chars.push(String.fromCharCode(bite));
}
return latin1Chars.join('');
}, parse: function (latin1Str) {
var latin1StrLength = latin1Str.length;
var words = [];
for (var i = 0; i < latin1StrLength; i++) {
words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
}
return new WordArray.init(words, latin1StrLength);
}
};
var Utf8 = C_enc.Utf8 = {
stringify: function (wordArray) {
try {
return decodeURIComponent(escape(Latin1.stringify(wordArray)));
} catch (e) {
throw new Error('Malformed UTF-8 data');
}
}, parse: function (utf8Str) {
return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
}
};
var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
reset: function () {
this._data = new WordArray.init();
this._nDataBytes = 0;
}, _append: function (data) {
if (typeof data == 'string') {
data = Utf8.parse(data);
}
this._data.concat(data);
this._nDataBytes += data.sigBytes;
}, _process: function (doFlush) {
var data = this._data;
var dataWords = data.words;
var dataSigBytes = data.sigBytes;
var blockSize = this.blockSize;
var blockSizeBytes = blockSize * 4;
var nBlocksReady = dataSigBytes / blockSizeBytes;
if (doFlush) {
nBlocksReady = Math.ceil(nBlocksReady);
} else {
nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
}
var nWordsReady = nBlocksReady * blockSize;
var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
if (nWordsReady) {
for (var offset = 0; offset < nWordsReady; offset += blockSize) {
this._doProcessBlock(dataWords, offset);
}
var processedWords = dataWords.splice(0, nWordsReady);
data.sigBytes -= nBytesReady;
}
return new WordArray.init(processedWords, nBytesReady);
}, clone: function () {
var clone = Base.clone.call(this);
clone._data = this._data.clone();
return clone;
}, _minBufferSize: 0
});
var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
cfg: Base.extend(),
init: function (cfg) {
this.cfg = this.cfg.extend(cfg);
this.reset();
}, reset: function () {
BufferedBlockAlgorithm.reset.call(this);
this._doReset();
}, update: function (messageUpdate) {
this._append(messageUpdate);
this._process();
return this;
}, finalize: function (messageUpdate) {
if (messageUpdate) {
this._append(messageUpdate);
}
var hash = this._doFinalize();
return hash;
}, blockSize: 512 / 32,
_createHelper: function (hasher) {
return function (message, cfg) {
return new hasher.init(cfg).finalize(message);
};
}, _createHmacHelper: function (hasher) {
return function (message, key) {
return new C_algo.HMAC.init(hasher, key).finalize(message);
};
}
});
var C_algo = C.algo = {};
return C;
}(Math));
(function (Math) {
var C = CryptoJS;
var C_lib = C.lib;
var WordArray = C_lib.WordArray;
var Hasher = C_lib.Hasher;
var C_algo = C.algo;
var T = [];
(function () {
for (var i = 0; i < 64; i++) {
T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
}
}());
var MD5 = C_algo.MD5 = Hasher.extend({
_doReset: function () {
this._hash = new WordArray.init([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]);
}, _doProcessBlock: function (M, offset) {
for (var i = 0; i < 16; i++) {
var offset_i = offset + i;
var M_offset_i = M[offset_i];
M[offset_i] = ((((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00));
}
var H = this._hash.words;
var M_offset_0 = M[offset + 0];
var M_offset_1 = M[offset + 1];
var M_offset_2 = M[offset + 2];
var M_offset_3 = M[offset + 3];
var M_offset_4 = M[offset + 4];
var M_offset_5 = M[offset + 5];
var M_offset_6 = M[offset + 6];
var M_offset_7 = M[offset + 7];
var M_offset_8 = M[offset + 8];
var M_offset_9 = M[offset + 9];
var M_offset_10 = M[offset + 10];
var M_offset_11 = M[offset + 11];
var M_offset_12 = M[offset + 12];
var M_offset_13 = M[offset + 13];
var M_offset_14 = M[offset + 14];
var M_offset_15 = M[offset + 15];
var a = H[0];
var b = H[1];
var c = H[2];
var d = H[3];
a = FF(a, b, c, d, M_offset_0, 7, T[0]);
d = FF(d, a, b, c, M_offset_1, 12, T[1]);
c = FF(c, d, a, b, M_offset_2, 17, T[2]);
b = FF(b, c, d, a, M_offset_3, 22, T[3]);
a = FF(a, b, c, d, M_offset_4, 7, T[4]);
d = FF(d, a, b, c, M_offset_5, 12, T[5]);
c = FF(c, d, a, b, M_offset_6, 17, T[6]);
b = FF(b, c, d, a, M_offset_7, 22, T[7]);
a = FF(a, b, c, d, M_offset_8, 7, T[8]);
d = FF(d, a, b, c, M_offset_9, 12, T[9]);
c = FF(c, d, a, b, M_offset_10, 17, T[10]);
b = FF(b, c, d, a, M_offset_11, 22, T[11]);
a = FF(a, b, c, d, M_offset_12, 7, T[12]);
d = FF(d, a, b, c, M_offset_13, 12, T[13]);
c = FF(c, d, a, b, M_offset_14, 17, T[14]);
b = FF(b, c, d, a, M_offset_15, 22, T[15]);
a = GG(a, b, c, d, M_offset_1, 5, T[16]);
d = GG(d, a, b, c, M_offset_6, 9, T[17]);
c = GG(c, d, a, b, M_offset_11, 14, T[18]);
b = GG(b, c, d, a, M_offset_0, 20, T[19]);
a = GG(a, b, c, d, M_offset_5, 5, T[20]);
d = GG(d, a, b, c, M_offset_10, 9, T[21]);
c = GG(c, d, a, b, M_offset_15, 14, T[22]);
b = GG(b, c, d, a, M_offset_4, 20, T[23]);
a = GG(a, b, c, d, M_offset_9, 5, T[24]);
d = GG(d, a, b, c, M_offset_14, 9, T[25]);
c = GG(c, d, a, b, M_offset_3, 14, T[26]);
b = GG(b, c, d, a, M_offset_8, 20, T[27]);
a = GG(a, b, c, d, M_offset_13, 5, T[28]);
d = GG(d, a, b, c, M_offset_2, 9, T[29]);
c = GG(c, d, a, b, M_offset_7, 14, T[30]);
b = GG(b, c, d, a, M_offset_12, 20, T[31]);
a = HH(a, b, c, d, M_offset_5, 4, T[32]);
d = HH(d, a, b, c, M_offset_8, 11, T[33]);
c = HH(c, d, a, b, M_offset_11, 16, T[34]);
b = HH(b, c, d, a, M_offset_14, 23, T[35]);
a = HH(a, b, c, d, M_offset_1, 4, T[36]);
d = HH(d, a, b, c, M_offset_4, 11, T[37]);
c = HH(c, d, a, b, M_offset_7, 16, T[38]);
b = HH(b, c, d, a, M_offset_10, 23, T[39]);
a = HH(a, b, c, d, M_offset_13, 4, T[40]);
d = HH(d, a, b, c, M_offset_0, 11, T[41]);
c = HH(c, d, a, b, M_offset_3, 16, T[42]);
b = HH(b, c, d, a, M_offset_6, 23, T[43]);
a = HH(a, b, c, d, M_offset_9, 4, T[44]);
d = HH(d, a, b, c, M_offset_12, 11, T[45]);
c = HH(c, d, a, b, M_offset_15, 16, T[46]);
b = HH(b, c, d, a, M_offset_2, 23, T[47]);
a = II(a, b, c, d, M_offset_0, 6, T[48]);
d = II(d, a, b, c, M_offset_7, 10, T[49]);
c = II(c, d, a, b, M_offset_14, 15, T[50]);
b = II(b, c, d, a, M_offset_5, 21, T[51]);
a = II(a, b, c, d, M_offset_12, 6, T[52]);
d = II(d, a, b, c, M_offset_3, 10, T[53]);
c = II(c, d, a, b, M_offset_10, 15, T[54]);
b = II(b, c, d, a, M_offset_1, 21, T[55]);
a = II(a, b, c, d, M_offset_8, 6, T[56]);
d = II(d, a, b, c, M_offset_15, 10, T[57]);
c = II(c, d, a, b, M_offset_6, 15, T[58]);
b = II(b, c, d, a, M_offset_13, 21, T[59]);
a = II(a, b, c, d, M_offset_4, 6, T[60]);
d = II(d, a, b, c, M_offset_11, 10, T[61]);
c = II(c, d, a, b, M_offset_2, 15, T[62]);
b = II(b, c, d, a, M_offset_9, 21, T[63]);
H[0] = (H[0] + a) | 0;
H[1] = (H[1] + b) | 0;
H[2] = (H[2] + c) | 0;
H[3] = (H[3] + d) | 0;
}, _doFinalize: function () {
var data = this._data;
var dataWords = data.words;
var nBitsTotal = this._nDataBytes * 8;
var nBitsLeft = data.sigBytes * 8;
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
var nBitsTotalL = nBitsTotal;
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ((((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00));
dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ((((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00));
data.sigBytes = (dataWords.length + 1) * 4;
this._process();
var hash = this._hash;
var H = hash.words;
for (var i = 0; i < 4; i++) {
var H_i = H[i];
H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
}
return hash;
}, clone: function () {
var clone = Hasher.clone.call(this);
clone._hash = this._hash.clone();
return clone;
}
});
function FF(a, b, c, d, x, s, t) {
var n = a + ((b & c) | (~b & d)) + x + t;
return ((n << s) | (n >>> (32 - s))) + b;
}
function GG(a, b, c, d, x, s, t) {
var n = a + ((b & d) | (c & ~d)) + x + t;
return ((n << s) | (n >>> (32 - s))) + b;
}
function HH(a, b, c, d, x, s, t) {
var n = a + (b ^ c ^ d) + x + t;
return ((n << s) | (n >>> (32 - s))) + b;
}
function II(a, b, c, d, x, s, t) {
var n = a + (c ^ (b | ~d)) + x + t;
return ((n << s) | (n >>> (32 - s))) + b;
}
C.MD5 = Hasher._createHelper(MD5);
C.HmacMD5 = Hasher._createHmacHelper(MD5);
}(Math));
function MD5_Encrypt(word) {
return CryptoJS.MD5(word).toString();
//反转:
//return CryptoJS.MD5(word).toString().split("").reverse().join("");
}

var window=this;
// 所有线程缓存
var works={}
//线程本身(子线程)
var worker_self=function(){}
worker_self.prototype.postMessage=function(x)
{
if(!typeof(this.main.onmessage)=="undefined")
{
this.main.onmessage({data:x});
}
}

worker_self.prototype.onmessageEvents=[];

worker_self.prototype.onmessage=function(x)
{
for(var i=0;i<this.onmessageEvents.length;i++)
{

this.onmessageEvents[i](x);
}
}
worker_self.prototype.main=undefined;
worker_self.prototype.addEventListener=function(_type,func_,x)
{
if(_type=="message")
{
this.onmessageEvents.push(func_);

}

}


var Worker=function(jsname,jscode){
jsname= MD5_Encrypt(jsname);
jscode=atob(jscode);
if(typeof(works[jsname])=="undefined")
{
works[jsname]=new worker_self();
this.self_=works[jsname];
works[jsname].main=this;
eval("self=window.works[\""+jsname+"\"];"+jscode);

}



}
Worker.prototype.postMessage=function(x)
{
this.self_.onmessage({data:x});
}

Worker.prototype.self_=undefined;

Worker.prototype.onmessage=undefined;
Worker.prototype.self_=undefined;

var worker = new Worker('worker.js',"Y29uc29sZS5sb2coc2VsZik7IA0Kc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGUpIHsNCiAgICBjb25zb2xlLmxvZyhlLmRhdGErIjEiKTsNCglzZWxmLnBvc3RNZXNzYWdlKGUuZGF0YSsiMSIpOw0KfSwgZmFsc2UpOw0K");

worker.onmessage=function(event)
{
debugger;
console.log("revied mesage"+event.data);

}
worker.postMessage('Hello World');


http://www.iwencai.com