mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-15 09:17:42 +00:00
- Added Win32Process which uses JNA to give us access to Windows APIs that give us more control over processes.
- Added killProcess() method to ExecUtil. This method can be used to terminate a process and its children.
This commit is contained in:
parent
f6be031c20
commit
882343a60f
@ -18,11 +18,13 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.coreutils;
|
||||
|
||||
import com.sun.javafx.PlatformUtil;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@ -108,12 +110,12 @@ public final class ExecUtil {
|
||||
do {
|
||||
process.waitFor(timeOut, units);
|
||||
if (process.isAlive() && terminator.shouldTerminateProcess()) {
|
||||
process.destroyForcibly();
|
||||
killProcess(process);
|
||||
}
|
||||
} while (process.isAlive());
|
||||
} catch (InterruptedException ex) {
|
||||
if (process.isAlive()) {
|
||||
process.destroyForcibly();
|
||||
killProcess(process);
|
||||
}
|
||||
Logger.getLogger(ExecUtil.class.getName()).log(Level.INFO, "Thread interrupted while running {0}", processBuilder.command().get(0));
|
||||
Thread.currentThread().interrupt();
|
||||
@ -121,6 +123,33 @@ public final class ExecUtil {
|
||||
return process.exitValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill a process and its children
|
||||
* @param process The parent process to kill
|
||||
*/
|
||||
public static void killProcess(Process process) {
|
||||
if (process == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
if (PlatformUtil.isWindows()) {
|
||||
Win32Process parentProcess = new Win32Process(process);
|
||||
List<Win32Process> children = parentProcess.getChildren();
|
||||
|
||||
children.stream().forEach((child) -> {
|
||||
child.terminate();
|
||||
});
|
||||
parentProcess.terminate();
|
||||
}
|
||||
else {
|
||||
process.destroyForcibly();
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Error occurred when attempting to kill process: {0}", ex.getMessage()); // NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExecUtil.class.getName());
|
||||
private Process proc = null;
|
||||
private ExecUtil.StreamToStringRedirect errorStringRedirect = null;
|
||||
|
115
Core/src/org/sleuthkit/autopsy/coreutils/Win32Process.java
Normal file
115
Core/src/org/sleuthkit/autopsy/coreutils/Win32Process.java
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012-2014 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.coreutils;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.Kernel32;
|
||||
import com.sun.jna.platform.win32.Kernel32Util;
|
||||
import com.sun.jna.platform.win32.Tlhelp32;
|
||||
import com.sun.jna.platform.win32.WinDef.DWORD;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class that represents a Windows process.
|
||||
* It uses JNA to access the Win32 API.
|
||||
* This code is based on http://stackoverflow.com/questions/10124299/how-do-i-terminate-a-process-tree-from-java
|
||||
*/
|
||||
public class Win32Process {
|
||||
WinNT.HANDLE handle;
|
||||
int pid;
|
||||
|
||||
/**
|
||||
* Create a Win32Process object for the given Process object.
|
||||
* Reflection is used to construct a Windows process handle.
|
||||
* @param process A Java Process object
|
||||
* @throws IOException
|
||||
*/
|
||||
Win32Process (Process process) throws Exception
|
||||
{
|
||||
if (process.getClass().getName().equals("java.lang.Win32Process") || // NON-NLS
|
||||
process.getClass().getName().equals("java.lang.ProcessImpl")) { // NON-NLS
|
||||
try {
|
||||
Field f = process.getClass().getDeclaredField("handle"); // NON-NLS
|
||||
f.setAccessible(true);
|
||||
long handleVal = f.getLong(process);
|
||||
handle = new WinNT.HANDLE(Pointer.createConstant(handleVal));
|
||||
}
|
||||
catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
|
||||
throw new Exception(ex.getMessage()); // NON-NLS
|
||||
}
|
||||
}
|
||||
this.pid = Kernel32.INSTANCE.GetProcessId(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Win32Process object for the given process id.
|
||||
* @param pid Process Id
|
||||
* @throws IOException
|
||||
*/
|
||||
Win32Process (int pid) throws Exception
|
||||
{
|
||||
handle = Kernel32.INSTANCE.OpenProcess (
|
||||
0x0400| /* PROCESS_QUERY_INFORMATION */
|
||||
0x0800| /* PROCESS_SUSPEND_RESUME */
|
||||
0x0001| /* PROCESS_TERMINATE */
|
||||
0x00100000 /* SYNCHRONIZE */,
|
||||
false,
|
||||
pid);
|
||||
if (handle == null)
|
||||
throw new Exception (Kernel32Util.formatMessageFromLastErrorCode (Kernel32.INSTANCE.GetLastError ()));
|
||||
this.pid = Kernel32.INSTANCE.GetProcessId(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize () throws Throwable
|
||||
{
|
||||
Kernel32.INSTANCE.CloseHandle (handle);
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill the process. Note that this does not kill children.
|
||||
*/
|
||||
public void terminate ()
|
||||
{
|
||||
Kernel32.INSTANCE.TerminateProcess (handle, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children of current process object.
|
||||
* @return list of child processes
|
||||
* @throws IOException
|
||||
*/
|
||||
public List<Win32Process> getChildren () throws Exception
|
||||
{
|
||||
ArrayList<Win32Process> result = new ArrayList<> ();
|
||||
WinNT.HANDLE hSnap = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new DWORD(0));
|
||||
Tlhelp32.PROCESSENTRY32.ByReference ent = new Tlhelp32.PROCESSENTRY32.ByReference ();
|
||||
if (!Kernel32.INSTANCE.Process32First (hSnap, ent)) return result;
|
||||
do {
|
||||
if (ent.th32ParentProcessID.intValue () == pid) result.add (new Win32Process (ent.th32ProcessID.intValue ()));
|
||||
} while (Kernel32.INSTANCE.Process32Next (hSnap, ent));
|
||||
Kernel32.INSTANCE.CloseHandle (hSnap);
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user