返回列表 发帖

[原创代码] js静态解密批处理变量加花v0.1

本帖最后由 CrLf 于 2015-4-27 20:58 编辑

碰到变量加花的加密批处理是一件很蛋疼的事情,手工解密费时费力,用预处理来解密又不能对代码中的 set 随机应变
现有的做法基本都是利用预处理来解析,其实之前也写过(嗯,代码在这儿),本来想写个加强版的 bat,后来觉得预处理易,解析 set 难...
考虑到日后改写 js 版 cmd 的可能性(就像联盟的那个在线 cmd——我是懒得搞的,不过如果有人要做,代码可以随便取用不客气),索性用 js 实现
写了个框架,基本实现了初步的语法解析,能够判断代码块、&&、||、句柄、内部命令名称、读写变量
函数名应该比较直观了,大概看一下带注释的主体内容(10~45行)也就知道怎么用了,再不懂就问我

本脚本的优势:
1、静态解析,可尝试解密安全性不确定的加密脚本
2、能解析出脚本中的 set 命令,并更新环境变量
3、支持代码块

目前的已知缺陷有:
1、静态解密天生的硬伤,因流程控制语句的结果不确定,所以无法预知脚本的执行顺序
2、目前只实现了 set 命令的基础语法,尚不能处理 set 命令的 /a、prompt、path 以及其他可改变环境变量的命令
3、还未添加对动态环境变量的支持,不过对解密的影响好像不大
4、对 if 命令的兼容性很差

加密.txt 的内容可以参照以下几贴:
http://www.bathome.net/thread-27912-1-1.html(此例效果最好,因为加密时未使用系统变量,比较恒定)
http://www.bathome.net/thread-35380-1-1.html(此例使用系统变量加密,可能因环境不同而无法执行)
http://www.bathome.net/thread-17490-1-1.html(同上)
1>1/* :
@echo off
cscript -nologo -e:jscript "%~0" <解密.txt | more
pause & exit /b
*/
var undefined = void 0
var arrCodeBlock = []
while(!WScript.StdIn.AtEndOfStream){
var line_base = WScript.StdIn.ReadLine()
//循环读取一行
var line_analyze = analyze_ExpandString(line_base)
//对该行中的 % 进行扩展
arrCodeBlock.push(line_analyze)
//“压栈”到代码块数组
if(!test_AtEndOfCodeBlock&&!WScript.StdIn.AtEndOfStream)continue
//若测试发现代码块未结束则继续读取下一行
var text_CodeBlock = arrCodeBlock.join('\n')
//连接代码块数组
WSH.Echo(text_CodeBlock)
//输出代码块
var text_CodeBlock = analyze_CleanCrLf(text_CodeBlock)
//行格式化
var split_CodeBlock = analyze_Split(text_CodeBlock)
//根据 | 和 & 拆分代码块为多条命令
for(var i=0;i<split_CodeBlock.length;i++){
split_CodeBlock[i] = analyze_Handle(split_CodeBlock[i])
//解析一条语句中的句柄
split_CodeBlock[i] = analyze_Command(split_CodeBlock[i])
//解析一条语句中的命令
}
arrCodeBlock = []
//清空代码块
}
function test_AtEndOfCodeBlock(strText){
var tmpText = strText
.replace(/[<>&|]/g,' ')
.replace(/\^[\s\S]|"[^"\n]*"|[^()]\(|\)[^()]/g,' ')
.replace(/[^()]+/g,'')
while(/\(\)/.test(tmpText)){
tmpText=tmpText.replace(/\(\)/g,'')
}
return tmpText.length == 0
}
function analyze_CleanCrLf(strText){
return strText
.replace(/\r\n/g,'\n')
.replace(/\^\n/g,'')
}
function analyze_ExpandString(strText){
return strText
.replace(
/%([0-9])|%:|%[^%]*%|%$/g,
function(strText,intArgv){
if(strText==='%')return ''
if(strText==='%%')return strText
if(strText==='%:')return ':'
if(intArgv !== undefined)return strText //return WScript.Arguments.length>intArgv ? WScript.Arguments(intArgv) : ''
return analyze_Variable(strText.replace(/%/g,''))
}
)
}
function analyze_Variable(strText){
var match = strText.match(/([^:]+)(?::(.*))?/)
var variableName = match[1]
var variableCode = match[2] ? match[2] : ''
var ws = new ActiveXObject("Wscript.Shell")
var variableValue = ws.ExpandEnvironmentStrings('%'+variableName+'%')
if(!variableCode)return variableValue
//扩展普通变量
var match = variableCode.match(/^~\s*(-?0x[0-9a-f]+|-?[0-9]+)?,?\s*(-?0x[0-9a-f]+|-?[0-9]+)?$/i)
if(match){
var splitStart = match[1] ? match[1]*1 : 0
var splitLength = match[2] ? match[2]*1 : 8191 - variableName.length
return cut(variableValue,splitStart,splitLength)
}
//扩展变量截取
var match = variableCode.match(/^([^=]+)=?(\*)?([s\S]+)?$/)
if(match){
var replaceFrom = match[1].replace(/\W/g,'\\$&')
var replaceHead = !!match[2]
var replaceTo = match[3] ? match[3].replace(/\$/g,'$$$$') : ''
if(replaceHead){
return variableValue.replace(new RegExp('^.*?'+replaceFrom,'i'),replaceTo)
} else {
return variableValue.replace(new RegExp(replaceFrom,'ig'),replaceTo)
}
}
//扩展变量替换
return strText
function cut(strText,intStart,intLength){
if(intStart<0){
variableValue = variableValue.substr(variableValue.length - -intStart)
} else {
variableValue = variableValue.substr(intStart)
}
if(intLength<0){
return variableValue.substring(0,-intLength)
} else {
return variableValue.substr(0,intLength)
}
}
}
function analyze_Split(strText){
var retArr = []
var strText = strText.replace(
/(^|&&?|\|\|?)?[\(\s]*([^\^\"&|]*(?:"[^"]*(?:"|$))*[^\^\"&|]*)?[\s\)]*/mg,
function(strMatch,strSpecial,strCommand){
retArr.push({strSpecial:strSpecial,strCommand:strCommand})
}
)
return retArr
}
function analyze_Handle(objCommand){
var tmpArr = []
var strCommand = objCommand.strCommand.replace(
/"[^"]*"|\^[<>]|([0-9]?)(&?[<>]|\>\>)([^\^\"\s&|<>]*(?:"[^"]*(?:"|$))*[^\^\"\s&|<>]*)?/mg,
function(strMatch,intHandle,strSpecial,strTarget){
intHandle = intHandle?intHandle:''
strTarget = strTarget?strTarget:''
if(strSpecial){
tmpArr.push(' '+intHandle+strSpecial+strTarget)
return ''
} else {
return strMatch
}
}
)
return {Command:strCommand,Handle:tmpArr}
}
function analyze_Command(objCommand){
var RegExp_command = /^\s*(ASSOC|BREAK|CALL|CD|CHDIR|CLS|COLOR|COPY|DEL|ENDLOCAL|ERASE|EXIT|FOR|FTYPE|GOTO|GRAFTABL|IF|MD|MKLINK|MOVE|PATH|PAUSE|POPD|PROMPT|PUSHD|RD|REM|REN|SET|SETLOCAL|SHIFT|START|TIME|TITLE|TYPE|VER|VERIFY|VOL)(?:([ \t,;=]*|$)(.*))?$/mi
var match = objCommand.Command.match(RegExp_command)
if(match){
objCommand.commandName = match[1]
objCommand.spaceChar = match[2] ? match[2] : ''
objCommand.commandValue = match[3] ? match[3] : ''
if(objCommand.commandName.toUpperCase()==='SET'){
Command_SET(objCommand.commandValue)
}
}
return objCommand
}
function Command_SET(strText){
strText = strText.replace(/^"(.*)"?$/,'$1')
var match = strText.match(/^\s*([^=]+)=?([^\^\"&|]*(?:"[^"]*(?:"|$))*[^\^\"&|]*)?\s*/)
if(match){
var variableName = match[1]
var variableCode = match[2] ? match[2] : ''
var ws = new ActiveXObject("Wscript.Shell")
ws.Environment("Process")(variableName) = variableCode
}
}COPY
1

评分人数

返回列表