Updated to use FFI/_wexecve() on windows

Bryan Roe committed Jan 16, 2021 at 02:00 UTC 060a34363f4442c3ace4d1c39f4ff1a7aa771901
2 files changed +58 -4
agents/meshcore.js
+29 -2
@@ -4306,6 +4306,34 @@ function createMeshCore(agent)
4306 require('MeshAgent').SendCommand({ action: 'sessions', type: 'msg', value: sendAgentMessage.messages });
4307 }
4308
4309 + function windows_execve(name, agentfilename, sessionid)
4310 + {
4311 + var libc;
4312 + try
4313 + {
4314 + libc = require('_GenericMarshal').CreateNativeProxy('msvcrt.dll');
4315 + libc.CreateMethod('_wexecve');
4316 + }
4317 + catch (xx)
4318 + {
4319 + sendConsoleText('Self Update failed because msvcrt.dll is missing', sessionid);
4320 + sendAgentMessage('Self Update failed because msvcrt.dll is missing', 3);
4321 + return;
4322 + }
4323 + var name = 'Mesh Agent';
4324 + var agentfilename = 'MeshAgent.exe';
4325 +
4326 + var cmd = require('_GenericMarshal').CreateVariable(process.env['windir'] + '\\system32\\cmd.exe', { wide: true });
4327 + var args = require('_GenericMarshal').CreateVariable(3 * require('_GenericMarshal').PointerSize);
4328 + var arg1 = require('_GenericMarshal').CreateVariable('cmd.exe', { wide: true });
4329 + var arg2 = require('_GenericMarshal').CreateVariable('/C wmic service "' + name + '" call stopservice & copy "' + process.cwd() + agentfilename + '.update" "' + process.execPath + '" & wmic service "' + name + '" call startservice & erase "' + process.cwd() + agentfilename + '.update"', { wide: true });
4330 +
4331 + arg1.pointerBuffer().copy(args.toBuffer());
4332 + arg2.pointerBuffer().copy(args.toBuffer(), require('_GenericMarshal').PointerSize);
4333 +
4334 + libc._wexecve(cmd, args, 0);
4335 + }
4336 +
4337 // Start a JavaScript based Agent Self-Update
4338 function agentUpdate_Start(updateurl, updateoptions)
4339 {
@@ -4407,8 +4435,7 @@ function createMeshCore(agent)
4435 if (process.platform == 'win32')
4436 {
4437 // Use _wexecve() equivalent to perform the update
4410 - this.child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe',
4411 - ['/C wmic service "' + name + '" call stopservice && copy "' + process.cwd() + agentfilename + '.update" "' + process.execPath + '" && wmic service "' + name + '" call startservice && erase "' + process.cwd() + agentfilename + '.update"'], { type: 4 | 0x8000 });
4438 + windows_execve(name, agentfilename, sessionid);
4439 }
4440 else
4441 {
agents/recoverycore.js
+29 -2
@@ -49,6 +49,34 @@ function sendAgentMessage(msg, icon)
49 require('MeshAgent').SendCommand({ action: 'sessions', type: 'msg', value: sendAgentMessage.messages });
50 }
51
52 +function windows_execve(name, agentfilename, sessionid)
53 +{
54 + var libc;
55 + try
56 + {
57 + libc = require('_GenericMarshal').CreateNativeProxy('msvcrt.dll');
58 + libc.CreateMethod('_wexecve');
59 + }
60 + catch (xx)
61 + {
62 + sendConsoleText('Self Update failed because msvcrt.dll is missing', sessionid);
63 + sendAgentMessage('Self Update failed because msvcrt.dll is missing', 3);
64 + return;
65 + }
66 + var name = 'Mesh Agent';
67 + var agentfilename = 'MeshAgent.exe';
68 +
69 + var cmd = require('_GenericMarshal').CreateVariable(process.env['windir'] + '\\system32\\cmd.exe', { wide: true });
70 + var args = require('_GenericMarshal').CreateVariable(3 * require('_GenericMarshal').PointerSize);
71 + var arg1 = require('_GenericMarshal').CreateVariable('cmd.exe', { wide: true });
72 + var arg2 = require('_GenericMarshal').CreateVariable('/C wmic service "' + name + '" call stopservice & copy "' + process.cwd() + agentfilename + '.update" "' + process.execPath + '" & wmic service "' + name + '" call startservice & erase "' + process.cwd() + agentfilename + '.update"', { wide: true });
73 +
74 + arg1.pointerBuffer().copy(args.toBuffer());
75 + arg2.pointerBuffer().copy(args.toBuffer(), require('_GenericMarshal').PointerSize);
76 +
77 + libc._wexecve(cmd, args, 0);
78 +}
79 +
80 // Start a JavaScript based Agent Self-Update
81 function agentUpdate_Start(updateurl, updateoptions)
82 {
@@ -150,8 +178,7 @@ function agentUpdate_Start(updateurl, updateoptions)
178 if (process.platform == 'win32')
179 {
180 // Use _wexecve() equivalent to perform the update
153 - this.child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe',
154 - ['/C wmic service "' + name + '" call stopservice && copy "' + process.cwd() + agentfilename + '.update" "' + process.execPath + '" && wmic service "' + name + '" call startservice && erase "' + process.cwd() + agentfilename + '.update"'], { type: 4 | 0x8000 });
181 + windows_execve(name, agentfilename, sessionid);
182 }
183 else
184 {