1 line
14 KiB
JavaScript
1 line
14 KiB
JavaScript
var promise=require("promise");var duplex=require("stream").Duplex;var SW_HIDE=0;var SW_MINIMIZE=6;var STARTF_USESHOWWINDOW=1;var STD_INPUT_HANDLE=-10;var STD_OUTPUT_HANDLE=-11;var EVENT_CONSOLE_CARET=16385;var EVENT_CONSOLE_END_APPLICATION=16391;var WINEVENT_OUTOFCONTEXT=0;var WINEVENT_SKIPOWNPROCESS=2;var CREATE_NEW_PROCESS_GROUP=512;var EVENT_CONSOLE_UPDATE_REGION=16386;var EVENT_CONSOLE_UPDATE_SIMPLE=16387;var EVENT_CONSOLE_UPDATE_SCROLL=16388;var EVENT_CONSOLE_LAYOUT=16389;var EVENT_CONSOLE_START_APPLICATION=16390;var KEY_EVENT=1;var MAPVK_VK_TO_VSC=0;var WM_QUIT=18;var GM=require("_GenericMarshal");var si=GM.CreateVariable(GM.PointerSize==4?68:104);var pi=GM.CreateVariable(GM.PointerSize==4?16:24);si.Deref(0,4).toBuffer().writeUInt32LE(GM.PointerSize==4?68:104);si.Deref(GM.PointerSize==4?48:64,2).toBuffer().writeUInt16LE(SW_HIDE|SW_MINIMIZE);si.Deref(GM.PointerSize==4?44:60,4).toBuffer().writeUInt32LE(STARTF_USESHOWWINDOW);var MSG=GM.CreateVariable(GM.PointerSize==4?28:48);function windows_terminal(){this._ObjectID="windows_terminal";this._user32=GM.CreateNativeProxy("User32.dll");this._user32.CreateMethod("DispatchMessageA");this._user32.CreateMethod("GetMessageA");this._user32.CreateMethod("MapVirtualKeyA");this._user32.CreateMethod("PostThreadMessageA");this._user32.CreateMethod("SetWinEventHook");this._user32.CreateMethod("ShowWindow");this._user32.CreateMethod("TranslateMessage");this._user32.CreateMethod("UnhookWinEvent");this._user32.CreateMethod("VkKeyScanA");this._user32.terminal=this;this._kernel32=GM.CreateNativeProxy("Kernel32.dll");this._kernel32.CreateMethod("AllocConsole");this._kernel32.CreateMethod("CreateProcessA");this._kernel32.CreateMethod("CloseHandle");this._kernel32.CreateMethod("FillConsoleOutputAttribute");this._kernel32.CreateMethod("FillConsoleOutputCharacterA");this._kernel32.CreateMethod("GetConsoleScreenBufferInfo");this._kernel32.CreateMethod("GetConsoleWindow");this._kernel32.CreateMethod("GetLastError");this._kernel32.CreateMethod("GetStdHandle");this._kernel32.CreateMethod("GetThreadId");this._kernel32.CreateMethod("ReadConsoleOutputA");this._kernel32.CreateMethod("SetConsoleCursorPosition");this._kernel32.CreateMethod("SetConsoleScreenBufferSize");this._kernel32.CreateMethod("SetConsoleWindowInfo");this._kernel32.CreateMethod("TerminateProcess");this._kernel32.CreateMethod("WaitForSingleObject");this._kernel32.CreateMethod("WriteConsoleInputA");var b=0;var c=0;this._scrx=0;this._scry=0;this.SendCursorUpdate=function(){var g=GM.CreateVariable(22);if(this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput,g).Val==0){return}if(g.Deref(4,2).toBuffer().readUInt16LE()!=this.currentX||g.Deref(6,2).toBuffer().readUInt16LE()!=this.currentY){this.currentX=g.Deref(4,2).toBuffer().readUInt16LE();this.currentY=g.Deref(6,2).toBuffer().readUInt16LE()}};this.ClearScreen=function(){var h=GM.CreateVariable(22);if(this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput,h).Val==0){return}var i=GM.CreateVariable(4);var j=h.Deref(0,2).toBuffer().readUInt16LE(0)*h.Deref(2,2).toBuffer().readUInt16LE(0);var g=GM.CreateVariable(4);if(this._kernel32.FillConsoleOutputCharacterA(this._stdoutput,32,j,i.Deref(0,4).toBuffer().readUInt32LE(),g).Val==0){return}if(this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput,h).Val==0){return}if(this._kernel32.FillConsoleOutputAttribute(this._stdoutput,h.Deref(8,2).toBuffer().readUInt16LE(0),j,i.Deref(0,4).toBuffer().readUInt32LE(),g).Val==0){return}this._kernel32.SetConsoleCursorPosition(this._stdoutput,i.Deref(0,4).toBuffer().readUInt32LE());var k=GM.CreateVariable(8);var l=h.Deref(10,8).toBuffer();k.Deref(4,2).toBuffer().writeUInt16LE(l.readUInt16LE(4)-l.readUInt16LE(0));k.Deref(6,2).toBuffer().writeUInt16LE(l.readUInt16LE(6)-l.readUInt16LE(2));this._kernel32.SetConsoleWindowInfo(this._stdoutput,1,k)};this.PowerShellCapable=function(){if(require("os").arch()=="x64"){return(require("fs").existsSync(process.env.windir+"\\SysWow64\\WindowsPowerShell\\v1.0\\powershell.exe"))}else{return(require("fs").existsSync(process.env.windir+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"))}};this.StartEx=function d(h,g,k){if(this._stream!=null){throw ("Concurrent terminal sessions are not supported on Windows.")}this.stopping=null;if(this._kernel32.GetConsoleWindow().Val==0){if(this._kernel32.AllocConsole().Val==0){throw ("AllocConsole failed with: "+this._kernel32.GetLastError().Val)}}this._stdinput=this._kernel32.GetStdHandle(STD_INPUT_HANDLE);this._stdoutput=this._kernel32.GetStdHandle(STD_OUTPUT_HANDLE);this._connected=false;var i=GM.CreateVariable(4);i.Deref(0,2).toBuffer().writeUInt16LE(h);i.Deref(2,2).toBuffer().writeUInt16LE(g);var j=GM.CreateVariable(8);j.Deref(4,2).toBuffer().writeUInt16LE(h-1);j.Deref(6,2).toBuffer().writeUInt16LE(g-1);if(this._kernel32.SetConsoleWindowInfo(this._stdoutput,1,j).Val==0){throw ("Failed to set Console Screen Size")}if(this._kernel32.SetConsoleScreenBufferSize(this._stdoutput,i.Deref(0,4).toBuffer().readUInt32LE()).Val==0){throw ("Failed to set Console Buffer Size")}this._user32.ShowWindow(this._kernel32.GetConsoleWindow().Val,SW_HIDE);this.ClearScreen();this._hookThread(k).then(function(){this.terminal.StartCommand(this.userArgs[0])},console.log);this._stream=new duplex({write:function(l,m){if(!this.terminal.connected){if(!this._promise.chunk){this._promise.chunk=[]}if(typeof(l)=="string"){this._promise.chunk.push(l)}else{this._promise.chunk.push(Buffer.alloc(l.length));l.copy(this._promise.chunk.peek())}this._promise.chunk.peek().flush=m;this._promise.then(function(){var n;while(this.chunk.length>0){n=this.chunk.shift();this.terminal._WriteBuffer(n);n.flush()}})}else{this.terminal._WriteBuffer(l);m()}return(true)},"final":function(l){var m=this.terminal._stop();m.__flush=l;m.then(function(){this.__flush()})}});this._stream.terminal=this;this._stream._promise=new promise(function(m,l){this._res=m;this._rej=l});this._stream._promise.terminal=this;this._stream.prependOnceListener("end",function(){this.terminal._stream=null});return(this._stream)};this.Start=function d(h,g){return(this.StartEx(h,g,process.env.windir+"\\System32\\cmd.exe"))};this.StartPowerShell=function f(h,g){if(require("os").arch()=="x64"){return(this.StartEx(h,g,process.env.windir+"\\SysWow64\\WindowsPowerShell\\v1.0\\powershell.exe"))}else{return(this.StartEx(h,g,process.env.windir+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"))}};this._stop=function(){if(this.stopping){return(this.stopping)}this._ConsoleWinEventProc.removeAllListeners("GlobalCallback");this.stopping=new promise(function(i,h){this._res=i;this._rej=h});var g=this._kernel32.GetThreadId(this._user32.SetWinEventHook.async.thread()).Val;this._user32.PostThreadMessageA(g,WM_QUIT,0,0);this._stream.emit("end");return(this.stopping)};this._hookThread=function(){var i=new promise(function(k,j){this._res=k;this._rej=j});i.userArgs=[];for(var g in arguments){i.userArgs.push(arguments[g])}i.terminal=this;this._ConsoleWinEventProc=GM.GetGenericGlobalCallback(7);this._ConsoleWinEventProc.terminal=this;var h=this._user32.SetWinEventHook.async(EVENT_CONSOLE_CARET,EVENT_CONSOLE_END_APPLICATION,0,this._ConsoleWinEventProc,0,0,WINEVENT_OUTOFCONTEXT|WINEVENT_SKIPOWNPROCESS);h.ready=i;h.terminal=this;h.then(function(j){if(j.Val==0){this.ready._rej("Error calling SetWinEventHook")}else{this.terminal.hwinEventHook=j;this.ready._res();this.terminal._GetMessage()}});this._ConsoleWinEventProc.on("GlobalCallback",function(l,k,m,p,n,o,r){if(!this.terminal.hwinEventHook||this.terminal.hwinEventHook.Val!=l.Val){return}var j=null;switch(k.Val){case EVENT_CONSOLE_CARET:break;case EVENT_CONSOLE_UPDATE_REGION:if(!this.terminal.connected){this.terminal.connected=true;this.terminal._stream._promise._res()}if(this.terminal._scrollTimer==null){j=this.terminal._GetScreenBuffer(LOWORD(p.Val),HIWORD(p.Val),LOWORD(n.Val),HIWORD(n.Val));this.terminal._SendDataBuffer(j)}break;case EVENT_CONSOLE_UPDATE_SIMPLE:var q={data:[Buffer.alloc(1,LOWORD(n.Val))],attributes:[HIWORD(n.Val)],width:1,height:1,x:LOWORD(p.Val),y:HIWORD(p.Val)};this.terminal._SendDataBuffer(q);break;case EVENT_CONSOLE_UPDATE_SCROLL:this.terminal._SendScroll(p.Val,n.Val);break;case EVENT_CONSOLE_LAYOUT:break;case EVENT_CONSOLE_START_APPLICATION:break;case EVENT_CONSOLE_END_APPLICATION:if(p.Val==this.terminal._hProcessID){this.terminal._hProcess=null;this.terminal._stop().then(function(){console.log("STOPPED")})}break;default:console.log("Unknown event: "+k.Val);break}});return(i)};this._GetMessage=function(){if(this._user32.abort){console.log("aborting loop");return}this._user32.GetMessageA.async(this._user32.SetWinEventHook.async,MSG,0,0,0).then(function(g){if(g.Val!=0){if(g.Val==-1){}else{this.nativeProxy._user32.TranslateMessage.async(this.nativeProxy.user32.SetWinEventHook.async,MSG).then(function(){this.nativeProxy._user32.DispatchMessageA.async(this.nativeProxy.user32.SetWinEventHook.async,MSG).then(function(){this.nativeProxy.terminal._GetMessage()},console.log)},console.log)}}else{this.nativeProxy.UnhookWinEvent.async(this.nativeProxy.terminal._user32.SetWinEventHook.async,this.nativeProxy.terminal.hwinEventHook).then(function(){if(this.nativeProxy.terminal._hProcess==null){return}this.nativeProxy.terminal.stopping._res();if(this.nativeProxy.terminal._kernel32.TerminateProcess(this.nativeProxy.terminal._hProcess,1067).Val==0){var h=this.nativeProxy.terminal._kernel32.GetLastError().Val;console.log("Unable to kill Terminal Process, error: "+h)}this.nativeProxy.terminal.stopping=null},function(h){console.log("REJECTED_UnhookWinEvent: "+h)})}},function(g){console.log("REJECTED_GETMessage: "+g)})};this._WriteBuffer=function(g){for(var h=0;h<g.length;++h){if(typeof(g)=="string"){this._WriteCharacter(g.charCodeAt(h),false)}else{this._WriteCharacter(g[h],false)}}};this._WriteCharacter=function(i,g){var j=GM.CreateVariable(20);j.Deref(0,2).toBuffer().writeUInt16LE(KEY_EVENT);j.Deref(4,4).toBuffer().writeUInt16LE(1);j.Deref(16,4).toBuffer().writeUInt32LE(g);j.Deref(14,1).toBuffer()[0]=i;j.Deref(8,2).toBuffer().writeUInt16LE(1);j.Deref(10,2).toBuffer().writeUInt16LE(this._user32.VkKeyScanA(i).Val);j.Deref(12,2).toBuffer().writeUInt16LE(this._user32.MapVirtualKeyA(this._user32.VkKeyScanA(i).Val,MAPVK_VK_TO_VSC).Val);var h=GM.CreateVariable(4);if(this._kernel32.WriteConsoleInputA(this._stdinput,j,1,h).Val==0){return(false)}j.Deref(4,4).toBuffer().writeUInt16LE(0);return(this._kernel32.WriteConsoleInputA(this._stdinput,j,1,h).Val!=0)};this._GetScreenBuffer=function(t,u,g,h){var j=GM.CreateVariable(22);if(this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput,j).Val==0){throw ("Error getting screen buffer info")}var o=j.Deref(14,2).toBuffer().readUInt16LE()-j.Deref(10,2).toBuffer().readUInt16LE()+1;var n=j.Deref(16,2).toBuffer().readUInt16LE()-j.Deref(12,2).toBuffer().readUInt16LE()+1;if(arguments[3]==null){t=0;u=0;g=o-1;h=n-1}else{if(this._scrx!=0){t+=this._scrx;g+=this._scrx}if(this._scry!=0){u+=this._scry;h+=this._scry}this._scrx=this._scry=0}var m=GM.CreateVariable((g-t+1)*(h-u+1)*4);var r=GM.CreateVariable(4);r.Deref(0,2).toBuffer().writeUInt16LE(g-t+1,0);r.Deref(2,2).toBuffer().writeUInt16LE(h-u+1,0);var s=GM.CreateVariable(4);s.Deref(0,2).toBuffer().writeUInt16LE(0,0);s.Deref(2,2).toBuffer().writeUInt16LE(0,0);var p=GM.CreateVariable(8);p.buffer=p.toBuffer();p.buffer.writeUInt16LE(t,0);p.buffer.writeUInt16LE(u,2);p.buffer.writeUInt16LE(g,4);p.buffer.writeUInt16LE(h,6);if(this._kernel32.ReadConsoleOutputA(this._stdoutput,m,r.Deref(0,4).toBuffer().readUInt32LE(),s.Deref(0,4).toBuffer().readUInt32LE(),p).Val==0){throw ("Unable to read Console Output")}var q={data:[],attributes:[],width:g-t+1,height:h-u+1,x:t,y:u};var w,z,k,i,v,l=g-t+1;for(z=0;z<=(h-u);++z){q.data.push(Buffer.alloc(l));q.attributes.push(Buffer.alloc(l));k=m.Deref(z*l*4,l*4).toBuffer();for(w=0;w<l;++w){q.data.peek()[w]=k[w*4];q.attributes.peek()[w]=k[2+(w*4)]}}return(q)};this._SendDataBuffer=function(h){var i,j,g;for(i=0;i<h.height;++i){j=h.data[i];g=h.attributes[i];j.s=j.toString();this._stream.push(TranslateLine(h.x+1,h.y+i+1,j,g))}};this._SendScroll=function a(h,j){if(this._scrollTimer){return}var l=GM.CreateVariable(22);if(this._kernel32.GetConsoleScreenBufferInfo(this._stdoutput,l).Val==0){throw ("Error getting screen buffer info")}var n=l.Deref(14,2).toBuffer().readUInt16LE()-l.Deref(10,2).toBuffer().readUInt16LE()+1;var m=l.Deref(16,2).toBuffer().readUInt16LE()-l.Deref(12,2).toBuffer().readUInt16LE()+1;this._stream.push(GetEsc("H",[m-1,0]));for(var k=0;k>m;++k){this._stream.push(Buffer.from("\r\n"))}var g=this._GetScreenBuffer(0,0,n-1,m-1);this._SendDataBuffer(g);this._scrollTimer=setTimeout(function(q,p,o){var i=q._GetScreenBuffer(0,0,p-1,o-1);q._SendDataBuffer(i);q._scrollTimer=null},250,this,n,m)};this.StartCommand=function e(g){if(this._kernel32.CreateProcessA(GM.CreateVariable(g),0,0,0,1,CREATE_NEW_PROCESS_GROUP,0,0,si,pi).Val==0){console.log("Error Spawning CMD");return}this._kernel32.CloseHandle(pi.Deref(GM.PointerSize,GM.PointerSize).Deref());this._hProcess=pi.Deref(0,GM.PointerSize).Deref();this._hProcessID=pi.Deref(GM.PointerSize==4?8:16,4).toBuffer().readUInt32LE()}}function LOWORD(a){return(a&65535)}function HIWORD(a){return((a>>16)&65535)}function GetEsc(b,a){return(Buffer.from("\x1B["+a.join(";")+b))}function MeshConsole(a){require("MeshAgent").SendCommand({action:"msg",type:"console",value:JSON.stringify(a)})}function TranslateLine(r,s,f,a){var m,l,e,q,j,c,n,k,d,p,h,b,g=[],o=[GetEsc("H",[s,r])];if(typeof a=="number"){a=[a]}for(m=0;m<f.length;m++){if(n!=a[m]){k=(a[m]&7);k=((k&1)<<2)+(k&2)+((k&4)>>2);d=(a[m]&112)>>4;d=((d&1)<<2)+(d&2)+((d&4)>>2);p=(a[m]&16384);h=(a[m]&8)>>3;b=(a[m]&128);if(p!=q){if(p!=0){g.push(7)}else{g.push(0);l=7;e=0;j=0;c=0}q=p}if(k!=l){g.push(k+30);l=k}if(d!=e){g.push(d+40);e=d}if(h!=j){g.push(2-h);j=h}if(b!=c){if(b==0){g.push(e+40)}else{g.push(e+100);c=b}}if(g.length>0){o.push(GetEsc("m",g));g=[]}n=a[m]}o.push(Buffer.from(String.fromCharCode(f[m])))}return Buffer.concat(o)}module.exports=new windows_terminal(); |