Archived
0

Zond: убийство процесса через системный вызов

This commit is contained in:
2017-07-24 03:37:32 +03:00
parent b48f2fc7d4
commit 8eb42d64ad
8 changed files with 177 additions and 4 deletions

View File

@@ -45,4 +45,6 @@ dependencies {
includedEx group: 'org.apache.commons', name: 'commons-exec', version: '1.3' includedEx group: 'org.apache.commons', name: 'commons-exec', version: '1.3'
included group: 'io.netty', name: 'netty-codec', version: nettyVersion included group: 'io.netty', name: 'netty-codec', version: nettyVersion
included group: 'com.google.guava', name: 'guava', version: '21.0' included group: 'com.google.guava', name: 'guava', version: '21.0'
included group: 'com.sun.jna', name: 'jna', version: '3.0.9'
} }

View File

@@ -1,5 +1,7 @@
package asys.zond; package asys.zond;
import asys.zond.shell.Shell;
public class PingMonitor { public class PingMonitor {
private static final long STEP_PING = 5000; private static final long STEP_PING = 5000;
private final long delayStart; private final long delayStart;
@@ -22,10 +24,17 @@ public class PingMonitor {
while (!Thread.currentThread().isInterrupted()) { while (!Thread.currentThread().isInterrupted()) {
long currentTimeMillis = System.currentTimeMillis(); long currentTimeMillis = System.currentTimeMillis();
if ((currentTimeMillis - lastPingTime) >= (2*STEP_PING)) { // если пропущено два пинга if ((currentTimeMillis - lastPingTime) >= (1*STEP_PING)) {
Shell.getInstance().getOutput().println("[D] lost one ping....");
}
else if ((currentTimeMillis - lastPingTime) >= (2*STEP_PING)) { // если пропущено два пинга
Shell.getInstance().getOutput().println("[D] lost two ping....");
callback.run(); // запускаем код завершения процесса callback.run(); // запускаем код завершения процесса
return; // завершаем поток return; // завершаем поток
} }
else {
Shell.getInstance().getOutput().println("[D] check ping");
}
try { try {
Thread.sleep(STEP_PING); Thread.sleep(STEP_PING);

View File

@@ -74,7 +74,12 @@ public class ZondCommandHandler implements CommandHandler {
private void startProcess() { private void startProcess() {
if (watchdog == null || !watchdog.isWatching()) { if (watchdog == null || !watchdog.isWatching()) {
if (watchdog == null) { if (watchdog == null) {
watchdog = new ZondExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT, proxyStdIn); watchdog = new ZondExecuteWatchdog(
ExecuteWatchdog.INFINITE_TIMEOUT,
proxyStdIn,
Config.getInstance().getString("cmdkiller")
);
executor.setWatchdog(watchdog); executor.setWatchdog(watchdog);
} }
final long delay = Config.getInstance().getLong("pingmonitor.delay"); final long delay = Config.getInstance().getLong("pingmonitor.delay");

View File

@@ -4,19 +4,56 @@
*/ */
package asys.zond; package asys.zond;
import asys.zond.shell.Shell;
import asys.zond.win32.Kernel32;
import asys.zond.win32.W32API;
import com.sun.jna.Pointer;
import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.ExecuteWatchdog;
import java.io.IOException;
import java.lang.reflect.Field;
public class ZondExecuteWatchdog extends ExecuteWatchdog { public class ZondExecuteWatchdog extends ExecuteWatchdog {
private final PipeInputStream inputStream; private final PipeInputStream inputStream;
private long pid;
private String cmdkiller;
public ZondExecuteWatchdog(long timeout, PipeInputStream inputStream) { public ZondExecuteWatchdog(long timeout, PipeInputStream inputStream, String cmdkiller) {
super(timeout); super(timeout);
this.inputStream = inputStream; this.inputStream = inputStream;
this.cmdkiller = cmdkiller.trim();
}
private long get_pid(Process process) {
if (process.getClass().getName().equals("java.lang.Win32Process") ||
process.getClass().getName().equals("java.lang.ProcessImpl")) {
try {
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handl = f.getLong(process);
Kernel32 kernel32 = Kernel32.INSTANCE;
W32API.HANDLE handle = new W32API.HANDLE();
handle.setPointer(Pointer.createConstant(handl));
return kernel32.GetProcessId(handle); //pid
} catch (Throwable ignore) {
}
} else if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
try {
Field f = process.getClass().getDeclaredField("pid");
f.setAccessible(true);
return f.getLong(process); //pid
} catch (Throwable ignore) {
}
}
return -1;
} }
@Override @Override
public synchronized void start(Process processToMonitor) { public synchronized void start(Process processToMonitor) {
super.start(processToMonitor); super.start(processToMonitor);
pid = get_pid(processToMonitor);
inputStream.open(); inputStream.open();
} }
@@ -25,4 +62,19 @@ public class ZondExecuteWatchdog extends ExecuteWatchdog {
super.stop(); super.stop();
inputStream.close(); inputStream.close();
} }
@Override
public synchronized void destroyProcess() {
super.destroyProcess();
if (pid != -1 && cmdkiller != null && !cmdkiller.isEmpty()) {
try {
String cmd = cmdkiller.replace("%PID", String.valueOf(pid));
Shell.getInstance().getOutput().println("CMDKILL: '" + cmd + "'");
Runtime.getRuntime().exec(cmd);
} catch (IOException ignore) {
}
} else {
Shell.getInstance().getOutput().println("PID = -1");
}
}
} }

View File

@@ -0,0 +1,15 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2017-07-24
*/
package asys.zond.win32;
import com.sun.jna.Native;
/* https://jna.dev.java.net/ */
public interface Kernel32 extends W32API {
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, DEFAULT_OPTIONS);
/* http://msdn.microsoft.com/en-us/library/ms683179(VS.85).aspx */
HANDLE GetCurrentProcess();
/* http://msdn.microsoft.com/en-us/library/ms683215.aspx */
int GetProcessId(HANDLE Process);
}

View File

@@ -0,0 +1,65 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package asys.zond.win32;
import java.util.HashMap;
import java.util.Map;
import com.sun.jna.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIFunctionMapper;
import com.sun.jna.win32.W32APITypeMapper;
/** Base type for most W32 API libraries. Provides standard options
* for unicode/ASCII mappings. Set the system property w32.ascii
* to true to default to the ASCII mappings.
*/
public interface W32API extends StdCallLibrary, W32Errors {
/** Standard options to use the unicode version of a w32 API. */
Map UNICODE_OPTIONS = new HashMap<String, Object>() {
{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
}
};
/** Standard options to use the ASCII/MBCS version of a w32 API. */
Map ASCII_OPTIONS = new HashMap<String, Object>() {
{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);
}
};
Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS;
class HANDLE extends PointerType {
@Override
public Object fromNative(Object nativeValue, FromNativeContext context) {
Object o = super.fromNative(nativeValue, context);
if (INVALID_HANDLE_VALUE.equals(o))
return INVALID_HANDLE_VALUE;
return o;
}
}
/** Constant value representing an invalid HANDLE. */
HANDLE INVALID_HANDLE_VALUE = new HANDLE() {
{ super.setPointer(Pointer.createConstant(-1)); }
@Override
public void setPointer(Pointer p) {
throw new UnsupportedOperationException("Immutable reference");
}
};
}

View File

@@ -0,0 +1,23 @@
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package asys.zond.win32;
public interface W32Errors {
int NO_ERROR = 0;
int ERROR_INVALID_FUNCTION = 1;
int ERROR_FILE_NOT_FOUND = 2;
int ERROR_PATH_NOT_FOUND = 3;
}

View File

@@ -4,3 +4,5 @@ port = 8779
passcode = testpassphrase passcode = testpassphrase
bridge.port = 8710 bridge.port = 8710
pingmonitor.delay = 2100 pingmonitor.delay = 2100
#cmdkiller = taskkill /F /PID %PID
cmdkiller = kill -KILL %PID