Skip to content

Instantly share code, notes, and snippets.

@Sascha-T
Last active February 17, 2024 02:59
Show Gist options
  • Save Sascha-T/ead50dffdd1845fd6d085160b72cd893 to your computer and use it in GitHub Desktop.
Save Sascha-T/ead50dffdd1845fd6d085160b72cd893 to your computer and use it in GitHub Desktop.
CPUID Java 21 :p

You need --enable-preview to compile/run this file.

/*
Demonstrates usage of CPUID on Windows in a single Java file, and prints the processor vendor string.
Uses Java 21 language features.
*/
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
void main() throws Throwable {
System.loadLibrary("kernel32");
MethodHandle virtualAlloc = Linker.nativeLinker().downcallHandle(
SymbolLookup.loaderLookup().find("VirtualAlloc").get(),
FunctionDescriptor.of(
ValueLayout.ADDRESS,
ValueLayout.ADDRESS,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT
)
); // VirtualAlloc of Kernel32.dll
MethodHandle virtualFree = Linker.nativeLinker().downcallHandle(
SymbolLookup.loaderLookup().find("VirtualFree").get(),
FunctionDescriptor.of(
ValueLayout.JAVA_BOOLEAN,
ValueLayout.ADDRESS,
ValueLayout.JAVA_INT,
ValueLayout.JAVA_INT
)
); // VirtualFree of Kernel32.dll
ByteBuffer text = ByteBuffer.allocate(12);
// 00,00,00,00
byte[] base = new byte[]{
(byte) 0xB8, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // mov eax, 0
(byte) 0x0F, (byte) 0xA2, // cpuid
(byte) 0x89, (byte) 0x00, // mov ?, ?
(byte) 0xC3 // ret
};
byte[] its = new byte[]{(byte) 0xD8, (byte) 0xD0, (byte) 0xC8}; // ebx, edx, ecx
var alloc = ((MemorySegment) virtualAlloc.invoke(
MemorySegment.NULL,
base.length,
0x00001000 /* commit */ | 0x00002000 /* reserve */,
0x40 /* exec + read + write */
)).reinterpret(base.length); // allocate an rwx page that contains our code
for (int i = 0; i < base.length; i++)
alloc.set(ValueLayout.JAVA_BYTE, i, base[i]); // copy the initial code
var cpuid = Linker.nativeLinker().downcallHandle(alloc, FunctionDescriptor.of(ValueLayout.JAVA_INT)); // prepare the downcall
text.order(ByteOrder.LITTLE_ENDIAN); // :p
for (int i = 0; i < its.length; i++) {
alloc.set(ValueLayout.JAVA_BYTE, 8, its[i]); // modify the codes returned registers in order
int ret = (int) cpuid.invoke();
text.putInt(ret);
}
String output = new String(text.array()); // ta daa
System.out.println(output); // yep
if ((boolean) virtualFree.invoke(alloc, base.length, 0x4000 /* decommit */))
System.err.println("VirtualFree failed.");
}
@Sascha-T
Copy link
Author

i read this again and i puked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment