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