回主页 我的日志 联系我                          

破解金山WPS表格密码

金山WPS的COM接口方法同微软的基本相同,常用的接口定义完全一样。 不过在打开密码文档的时候金山的WPS如果密码错了会提示一个弹出框阻止程序继续运行, 对暴力破解有一点点麻烦。基本的脚本如下:

exl = new ActiveXObject("Excel.Application");
exl = new ActiveXObject("ET.Application");

// 如果密码正确下面这行不操作,否则抛出异常
exl.Workbooks.Open("<filepath>",0,true,1,"<pwd>");
exl.Quit();

最后的版本为:

// main.js
//定义可能的字符
var allc = "";
allc += "0123456789";
//allc += "abcdefghijklmnopqrstuvwxyz";
//allc += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//allc += "!@#$%^&*()_+/?<>,.'\":;";

//定义密码的最大最小长度
var minl = 3;
var maxl = 3;

var iswps = false; //不是的话设置为 true

/// !!!警告!!! 除非你非常明白在做什么,否则不要修改下面的内容



////////////////////////////////////////////////////////
// 参数检查
var objArgs = WScript.Arguments;
if (objArgs.length < 1)
    exit("没有文件!");

objArgs = objArgs(0);
if(!isfile(objArgs))
    exit("文件不存在!");

////////////////////////////////////////////////////////
//破解部分
var cl = allc.length;

var carr = null;
++maxl;
for(var i=minl;i<maxl;++i){
    carr = initcarr(i);
    if(carr==null)
        exit("内存溢出");
    WScript.Echo("尝试 " + i + " 位长度密码!");
    var pwd;
    while((pwd=addcarr(carr,cl))!=null){
        //WScript.Echo(pwd);
        try{
            var etobj = trytodec(objArgs,pwd);
            if(etobj==null)
                continue;
            objArgs = objArgs.replace(/(\.[a-z]+)$/,"_已破解$1");
            saveto(etobj,objArgs);
            getETObject("deleteobj");
            WScript.Echo("破解成功,密码为: " + pwd +"\n"
                    + "破解后的文件为: \"" + objArgs + "\"");
            WScript.Quit(0);
        }catch(e){
            exit(e);
        }
    }
}

WScript.Quit();

////////////////////////////////////////////////////////
function getETObject(){
    if(getETObject.etobj!=null && arguments.length==1 && typeof(arguments[0])=="string"
           && arguments[0] == "deleteobj"){
        getETObject.etobj.Quit();
        getETObject.etobj=null;
        return null;
    }

    if(getETObject.etobj == null){
        if(arguments.length == 0){
            try{
                getETObject.etobj = new ActiveXObject("Excel.Application");
                return getETObject.etobj;
            }catch(e){ }
        }
        try{
            getETObject.etobj = new ActiveXObject("ET.Application");
        }catch(e){ }
    }
    return getETObject.etobj;
}

function trytodec(fp,pwd){
    var etobj;
    if(iswps)
        etobj = getETObject(iswps);
    else
        etobj = getETObject();
    if(etobj==null)
        throw "找不到 Excel 或 WPS !";
    try{
        etobj = etobj.Workbooks.Open(fp,0,true,1,pwd);
    }catch(e){
        return null;
    }
    return etobj;
}

function saveto(etobj,nfp){
    try{
        etobj.SaveAs(nfp,18,"");
    }catch(e){
        WScript.Echo(e.message);
        return false;
    }
    return true;
}

////////////////////////////////////////////////////////
function exit(ec){
    WScript.Echo(ec);
    WScript.Quit(1);
}

function isfile(fp){
    var fso;
    try{
        fso = new ActiveXObject("Scripting.FileSystemObject");
    }catch(e){
        return false;
    }
    return fso.FileExists(fp);
}

function initcarr(len){
    var carr = new Array(len);
    for(var i=0;i<len;++i)
        carr[i] = 0;
    return carr;
}

function addcarr(ca,mn){
    var cl = ca.length;

    var i;
    do{
        i = false;
        --cl
        ++ca[cl];
        if(ca[cl]==mn){
            if(cl==0) //最大
                return null;
            ca[cl] = 0;
            i = true;
        }
    }while(i);

    cl = "";
    for(i=0;i<ca.length;++i)
        cl += allc.charAt(ca[i]);

    return cl;
}

因为WPS需要点掉对话框,所以写了一个专门发送ESC字符的脚本:

//设置要发送多少时间的ESC
var sendtime = 20; //单位为秒

/////////////////////////////////////
var dt = new Date();
var last = dt.getTime();
last += 1000 * sendtime; //多少秒

var wss = new ActiveXObject("WScript.Shell");
while(new Date().getTime()<last)
    for(var i=0;i<1000;++i)
        wss.SendKeys("{ESC}");

©2012-2020 Mark (冀ICP备19037432号-1)