mirror of
https://git.mirrors.martin98.com/https://github.com/cilame/v_jstools
synced 2025-08-14 05:05:57 +08:00
add
This commit is contained in:
parent
87588ef581
commit
230e8cd669
@ -7,6 +7,7 @@
|
||||
<script src="./tools/cheerio.js"></script>
|
||||
<script src="./tools/replacer.js"></script>
|
||||
<script src="./tools/error_front.js"></script>
|
||||
<script src="./tools/cryptojs.js"></script>
|
||||
<script src="background.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
146
background.js
146
background.js
@ -11,17 +11,33 @@
|
||||
// });
|
||||
// background.js
|
||||
chrome.contextMenus.create({
|
||||
title: "打开 v_jstools 动态调试",
|
||||
title: "打开 ast 动态挂钩",
|
||||
contexts: ['all'],
|
||||
onclick: function(){
|
||||
ast_dyn_hook = true
|
||||
AttachDebugger();
|
||||
}
|
||||
});
|
||||
chrome.contextMenus.create({
|
||||
title: "打开 html 调试拷贝",
|
||||
contexts: ['all'],
|
||||
onclick: function(){
|
||||
html_copy = true
|
||||
AttachDebugger();
|
||||
}
|
||||
});
|
||||
var ast_dyn_hook = false
|
||||
var html_copy = false
|
||||
function close_debugger(){
|
||||
attached = false
|
||||
ast_dyn_hook = false
|
||||
html_copy = false
|
||||
}
|
||||
function sendCommand(method, params, source, chainfun){
|
||||
chrome.debugger.sendCommand(source, method, params, function(result){
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error('chrome.runtime.lastError', chrome.runtime.lastError)
|
||||
if (chrome.runtime.lastError.message.indexOf('Cannot access a chrome://') != -1){ attached = false }
|
||||
if (chrome.runtime.lastError.message.indexOf('Cannot access a chrome://') != -1){ close_debugger() }
|
||||
} else { if (chainfun){ chainfun(result) } }
|
||||
});
|
||||
}
|
||||
@ -45,48 +61,56 @@ chrome.debugger.onEvent.addListener(function (source, method, params){
|
||||
break; }
|
||||
sendCommand("Fetch.getResponseBody", { requestId: params.requestId }, source, function(result){
|
||||
var fillfunc = fillresponse.bind(null, params, source)
|
||||
|
||||
if ( params.resourceType == 'Script'
|
||||
|| params.resourceType == 'Document'
|
||||
|| params.resourceType == 'Stylesheet'
|
||||
|| params.resourceType == 'Image'
|
||||
|| params.resourceType == 'Font'
|
||||
|| params.resourceType == 'Other'
|
||||
){
|
||||
if (params.resourceType == 'Script'){ var save_info = decodeURIComponent(escape(atob(result.body))) }
|
||||
if (params.resourceType == 'Document'){ var save_info = decodeURIComponent(escape(atob(result.body))) }
|
||||
if (params.resourceType == 'Stylesheet'){ var save_info = decodeURIComponent(escape(atob(result.body))) }
|
||||
if (params.resourceType == 'Image'){ var save_info = result.body }
|
||||
if (params.resourceType == 'Font'){ var save_info = result.body }
|
||||
if (params.resourceType == 'Other'){ var save_info = result.body }
|
||||
function save_html_info(save_info, type, url){
|
||||
save_cache[url] = {data: save_info, type: type}
|
||||
chrome.storage.local.get(["config-fetch_hook"], function (res) {
|
||||
if (!result.body){ fillfunc(result.body); return }
|
||||
// save html
|
||||
if (html_copy){
|
||||
if ( params.resourceType == 'Script'
|
||||
|| params.resourceType == 'Document'
|
||||
|| params.resourceType == 'Stylesheet'
|
||||
|| params.resourceType == 'Image'
|
||||
|| params.resourceType == 'Font'
|
||||
|| params.resourceType == 'Other'
|
||||
){
|
||||
if (params.resourceType == 'Script'){ var save_info = decodeURIComponent(escape(atob(result.body))) }
|
||||
if (params.resourceType == 'Document'){ var save_info = decodeURIComponent(escape(atob(result.body))) }
|
||||
if (params.resourceType == 'Stylesheet'){ var save_info = decodeURIComponent(escape(atob(result.body))) }
|
||||
if (params.resourceType == 'Image'){ var save_info = result.body }
|
||||
if (params.resourceType == 'Font'){ var save_info = result.body }
|
||||
if (params.resourceType == 'Other'){ var save_info = result.body }
|
||||
function save_html_info(save_info, type, url){
|
||||
save_cache[url] = {data: save_info, type: type}
|
||||
}
|
||||
save_html_info(save_info, params.resourceType, params.request.url)
|
||||
console.log(params.resourceType, params.request.url)
|
||||
}
|
||||
}
|
||||
save_html_info(save_info, params.resourceType, params.request.url)
|
||||
}
|
||||
console.log(params.resourceType, params.request.url)
|
||||
if (result.body !== undefined){ // 收到的 result.body 是 base64(代码) 的代码,使用时需要解码一下
|
||||
if (params.resourceType == 'Script' || params.resourceType == 'Document'){
|
||||
chrome.storage.local.get(["config-fetch_hook"], function (res) {
|
||||
// ast hook
|
||||
if (ast_dyn_hook){
|
||||
if ( params.resourceType == 'Script'
|
||||
|| params.resourceType == 'Document'
|
||||
){
|
||||
try{
|
||||
var respboby = decodeURIComponent(escape(atob(result.body)))
|
||||
var replacer = eval((res["config-fetch_hook"]||'')+';fetch_hook')
|
||||
if (params.resourceType == 'Script'){ var replbody = (replacer(respboby, params.request.url)) }
|
||||
if (params.resourceType == 'Document'){ var replbody = (html_script_replacer(respboby, replacer, params.request.url)) }
|
||||
fillfunc(btoa(unescape(encodeURIComponent(replbody)))) }
|
||||
fillfunc(btoa(unescape(encodeURIComponent(replbody))))
|
||||
return }
|
||||
catch(e){
|
||||
send_error_info_to_front(e.stack, currtab.tabId, params.request.url)
|
||||
fillfunc(result.body) }
|
||||
})
|
||||
return
|
||||
send_error_info_to_front(e.stack, currtab.tabId, params.request.url) }
|
||||
}
|
||||
}
|
||||
}
|
||||
fillfunc(result.body) // body 只能传 base64(指定代码)
|
||||
fillfunc(result.body) // body 只能传 base64(指定代码)
|
||||
})
|
||||
return
|
||||
});
|
||||
break; }
|
||||
}
|
||||
})
|
||||
chrome.debugger.onDetach.addListener(function(){ attached = false })
|
||||
chrome.debugger.onDetach.addListener(function(){
|
||||
close_debugger()
|
||||
})
|
||||
var attached = false
|
||||
var currtab;
|
||||
function AttachDebugger() {
|
||||
@ -315,6 +339,36 @@ function get_html(url){
|
||||
return $.html()
|
||||
}
|
||||
|
||||
|
||||
var typeMap = {
|
||||
"txt" : "text/plain",
|
||||
"html" : "text/html",
|
||||
"htm" : "text/html",
|
||||
"css" : "text/css",
|
||||
"js" : "text/javascript",
|
||||
"json" : "text/json",
|
||||
"xml" : "text/xml",
|
||||
"jpg" : "image/jpeg",
|
||||
"gif" : "image/gif",
|
||||
"png" : "image/png",
|
||||
"webp" : "image/webp"
|
||||
}
|
||||
|
||||
function getLocalFileUrl(url) {
|
||||
var arr = url.split('.');
|
||||
var type = arr[arr.length-1];
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('get', url, false);
|
||||
xhr.send(null);
|
||||
var content = xhr.responseText || xhr.responseXML;
|
||||
if (!content) {
|
||||
return false;
|
||||
}
|
||||
var wordArray = CryptoJS.enc.Utf8.parse(content);
|
||||
var base64 = CryptoJS.enc.Base64.stringify(wordArray);
|
||||
return ("data:" + (typeMap[type] || typeMap.txt) + ";charset=utf-8;base64," + base64);
|
||||
}
|
||||
|
||||
chrome.storage.local.get(['config-hook-global'], function(e){
|
||||
chrome.browserAction.setBadgeBackgroundColor({color: '#BC1717'});
|
||||
if (e['config-hook-global']){
|
||||
@ -322,4 +376,32 @@ chrome.storage.local.get(['config-hook-global'], function(e){
|
||||
}else{
|
||||
chrome.browserAction.setBadgeText({text: ''});
|
||||
}
|
||||
})
|
||||
|
||||
chrome.webRequest.onBeforeRequest.addListener(function (details) {
|
||||
var url = details.url;
|
||||
for (var i = 0; i < webRedirect.length; i++) {
|
||||
var [mstr, rurl] = webRedirect[i]
|
||||
if (url.indexOf(mstr) != -1){
|
||||
if (rurl.trim().indexOf('file:///') == 0){
|
||||
var rdata = getLocalFileUrl(rurl)
|
||||
if (rdata){
|
||||
return { redirectUrl: rdata };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {}
|
||||
},
|
||||
{urls: ["<all_urls>"]},
|
||||
["blocking"]
|
||||
);
|
||||
|
||||
var webRedirect = []
|
||||
window.addEventListener('storage', function(){
|
||||
webRedirect = JSON.parse(localStorage.webRedirect || "[]")
|
||||
}, false);
|
||||
chrome.storage.local.get(["response_changer"], function(res){
|
||||
var init_data = JSON.parse(res["response_changer"] || "[]")
|
||||
webRedirect = init_data
|
||||
})
|
@ -35,15 +35,17 @@
|
||||
"name": "v_jstools",
|
||||
"version": "0.0.0",
|
||||
"description": "v_jstools js hook工具",
|
||||
"permissions": ["storage",
|
||||
"unlimitedStorage",
|
||||
"permissions": ["unlimitedStorage",
|
||||
"activeTab",
|
||||
"webRequest",
|
||||
"webRequestBlocking",
|
||||
"tabs",
|
||||
"debugger",
|
||||
"storage",
|
||||
"contextMenus",
|
||||
"http://*/*",
|
||||
"https://*/*",
|
||||
"<all_urls>",
|
||||
"cookies",
|
||||
"downloads",
|
||||
"proxy"
|
||||
|
12
options.html
12
options.html
@ -17,7 +17,7 @@
|
||||
<ul>
|
||||
<button class="act">dom对象 hook 配置</button>
|
||||
<button>注入代码</button>
|
||||
<button>高级 hook ,修改 response 返回值</button>
|
||||
<button>修改返回值</button>
|
||||
<button>AST混淆解密</button>
|
||||
<button>代码模板(RPC...)</button>
|
||||
<button>混淆器</button>
|
||||
@ -132,7 +132,14 @@
|
||||
<!-- <div>修改代理:<input type="text" data-key="config-proxy_config" id="proxy_config"></div> -->
|
||||
</section>
|
||||
<section class="tab">
|
||||
<div>这里的功能:在目标网页上右键菜单选择 “打开 v_jstools 动态调试” 即可开启,使用用插件的方式 hook 住目标页面的所有代码,像是在 node 里面一样使用 ast 将原始的代码修改成期望的样子</div>
|
||||
<h2 style="margin-bottom: 0px;margin-top: 50px;">修改匹配URL的返回值</h2>
|
||||
<hr>
|
||||
<div>适用的本地文件后缀:txt,html,htm,css,js,json,xml,jpg,gif,png,webp</div>
|
||||
<table id="response_changer"></table>
|
||||
|
||||
<h2 style="margin-bottom: 0px;margin-top: 50px;">动态修改被调试页面的所有js代码</h2>
|
||||
<hr>
|
||||
<div>这里的功能:在目标网页上右键菜单选择 “打开 ast 动态挂钩” 即可开启,使用用插件的方式 hook 住目标页面的所有代码,像是在 node 里面一样使用 ast 将原始的代码修改成期望的样子</div>
|
||||
<div>这里的 hook 功能在一定的扩展之后,能 hook 住 script 链接中的 js 代码,也能 hook 到 html 内的 js 代码。</div>
|
||||
<div>*能直接用插件的方式实现 ast 修改代码,用处还是非常大的。不过目前感觉功能稍微有点干瘪,因为暂时还在想有什么 ast 修改模板代码会更好的捕捉代码信息,让代码更方便的调试。</div>
|
||||
<HR>
|
||||
@ -230,6 +237,7 @@
|
||||
<textarea id='jsobfuscator_code' style="width: 100%; height: 500px" placeholder="输出代码"></textarea>
|
||||
</section>
|
||||
</div>
|
||||
<script src="tools/jquery.min.js"></script>
|
||||
<script src="options.js"></script>
|
||||
<script src="tools/model_funcs.js"></script>
|
||||
<script src="tools/babel_asttool.js"></script>
|
||||
|
102
options.js
102
options.js
@ -678,3 +678,105 @@ document.getElementById('mydec').addEventListener('click', function(e){
|
||||
mycode_dec.value = e
|
||||
}
|
||||
})
|
||||
|
||||
function response_changer_init(idname, titlenames, init_data, callback) {
|
||||
var cid = "#" + idname
|
||||
var trlast = cid + " tr:last"
|
||||
var opindex = titlenames.length
|
||||
var title = "<tr>"
|
||||
for (var i = 0; i < titlenames.length; i++) {
|
||||
title += "<td>" + titlenames[i] + "</td>"
|
||||
}
|
||||
title += "<td>操作</td>"
|
||||
title += "</tr>"
|
||||
title += '<tr><td colspan="5"><button>添加行</button><button>添加示例</button></td></tr>'
|
||||
$(cid).html(title)
|
||||
$($(trlast).find("button")[0]).click(function() {
|
||||
addRow()
|
||||
})
|
||||
$($(trlast).find("button")[1]).click(function() {
|
||||
addRow(["baidu.com", "file:///C:/Users/Administrator/Desktop/test.html"])
|
||||
__cache_data()
|
||||
})
|
||||
init_data = init_data || []
|
||||
for (var i = 0; i < init_data.length; i++) {
|
||||
addRow(init_data[i])
|
||||
}
|
||||
function __cache_data(){
|
||||
var data_list = []
|
||||
var trs = $(cid).find("tr")
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
var tds = $(trs[i]).find("td")
|
||||
var data_line = []
|
||||
for (var j = 0; j < tds.length; j++) {
|
||||
var ipt = $(tds[j]).find("input")[0]
|
||||
if (ipt){
|
||||
data_line.push(ipt.value)
|
||||
}
|
||||
}
|
||||
if (data_line.length){
|
||||
data_list.push(data_line)
|
||||
}
|
||||
}
|
||||
while(init_data.length){ init_data.pop() }
|
||||
while(data_list.length){ init_data.unshift(data_list.pop()) }
|
||||
callback(init_data)
|
||||
}
|
||||
function __add_remover(index){
|
||||
$(cid).find("tr").eq(index).find("td").eq(opindex).remove();
|
||||
var htmlStr = "<td><button>删除行</button></td>"
|
||||
$(cid).find("tr").eq(index).append(htmlStr)
|
||||
$(cid).find("tr").eq(index).find("td").find("button").click(function(){
|
||||
removeRow(index)
|
||||
})
|
||||
}
|
||||
function __add_changer(index){
|
||||
var tds = $(cid).find("tr").eq(index).find("td")
|
||||
for (var i = 0; i < tds.length; i++) {
|
||||
var ipt = $(tds[i]).find("input")[0]
|
||||
if (ipt){
|
||||
$(ipt).on("input", function(){
|
||||
__cache_data()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
function addRow(data) {
|
||||
var trArray = $(cid).find("tr");
|
||||
var thisIndex = trArray.length - 1;
|
||||
var addRowHtmlStr = "<tr>"
|
||||
for (var i = 0; i < titlenames.length; i++) {
|
||||
addRowHtmlStr += "<td style='width: 300px'><input type='text' style='width: 300px'></td>"
|
||||
}
|
||||
"<td></td></tr>"
|
||||
$(trlast).before(addRowHtmlStr);
|
||||
__add_changer(thisIndex)
|
||||
__add_remover(thisIndex)
|
||||
if (data){
|
||||
var ctds = $(cid).find("tr").eq(thisIndex).find("td")
|
||||
var leng = Math.min(data.length, titlenames.length)
|
||||
for (var i = 0; i < leng; i++) {
|
||||
$(ctds[i]).find('input').val(data[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
function removeRow(index) {
|
||||
$(cid).find("tr").eq(index).remove();
|
||||
var trArrayNow = $(cid).find("tr");
|
||||
for (var i = index; i < trArrayNow.length - 1; i++) {
|
||||
__add_remover(i)
|
||||
}
|
||||
__cache_data()
|
||||
}
|
||||
}
|
||||
|
||||
chrome.storage.local.get(["response_changer"], function(res){
|
||||
var init_data = JSON.parse(res["response_changer"] || "[]")
|
||||
localStorage.webRedirect = JSON.stringify(init_data)
|
||||
response_changer_init("response_changer", ["(URL)字符串匹配", "重定向地址"], init_data, function(data){
|
||||
chrome.storage.local.set({
|
||||
response_changer: JSON.stringify(data)
|
||||
})
|
||||
localStorage.webRedirect = JSON.stringify(data)
|
||||
})
|
||||
})
|
2
popup.js
2
popup.js
@ -86,7 +86,7 @@ document.getElementById('clone_page').addEventListener('click', function(e){
|
||||
filename: 'clone_html.html'
|
||||
});
|
||||
}else{
|
||||
alert('获取html结构失败,请右键需要拷贝的页面的空白处,选择“打开 v_jstools 动态调试”。刷新页面后,确保页面资源加载充足后再重新点击“拷贝当前页面”')
|
||||
alert('获取html结构失败,请右键需要拷贝的页面的空白处,选择“打开 html 调试拷贝”。刷新页面后,确保页面资源加载充足后再重新点击“拷贝当前页面”')
|
||||
}
|
||||
});
|
||||
})
|
||||
|
4
tools/jquery.min.js
vendored
Normal file
4
tools/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user