java windowsapi_Java操作windows API

本文展示了如何使用Java JNA库来调用Windows API,实现通过窗口名称或PID获取进程句柄,并读写指定地址的内存值。提供了一系列静态方法,包括读取和写入int、double、float、long以及byte数组到进程内存中。
摘要由CSDN通过智能技术生成

使用jna自带的功能进行调用

maven依赖如下:

net.java.dev.jna

jna

5.4.0

net.java.dev.jna

jna-platform

5.4.0

代码如下:

package com.fly.jna.window.util;

import com.sun.jna.Memory;

import com.sun.jna.Pointer;

import com.sun.jna.platform.win32.Kernel32;

import com.sun.jna.platform.win32.User32;

import com.sun.jna.platform.win32.WinDef.HWND;

import com.sun.jna.platform.win32.WinNT;

import com.sun.jna.platform.win32.WinNT.HANDLE;

import com.sun.jna.ptr.IntByReference;

public class WindowsUtils {

private static final Kernel32 KERNEL = Kernel32.INSTANCE;

private static final User32 USER = User32.INSTANCE;

/**

* 通过窗口名称获取句柄

* @param windowName 窗口名称

* @return 句柄

*/

public static HANDLE getHandleByWindowName(String windowName) {

HWND hwnd = USER.FindWindow(null, windowName);

IntByReference pidReference = new IntByReference();

USER.GetWindowThreadProcessId(hwnd, pidReference);

int pid = pidReference.getValue();

return KERNEL.OpenProcess(WinNT.PROCESS_ALL_ACCESS, false, pid);

}

/**

* 通过pid获取句柄

* @param pid pid

* @return 句柄

*/

public static HANDLE getHandleByPid(int pid) {

return KERNEL.OpenProcess(WinNT.PROCESS_ALL_ACCESS, false, pid);

}

/**

* 将int值写入到指定地址

* @param handle 程序句柄

* @param address 地址

* @param value 值

* @return 写入多少 -1为失败

*/

public static int writeIntToAddress(HANDLE handle, int address, int value) {

Memory memory = new Memory(4);

memory.setInt(0, value);

IntByReference readByteNumber = new IntByReference();

KERNEL.WriteProcessMemory(handle, Pointer.createConstant(address), memory, 4, readByteNumber);

return readByteNumber.getValue();

}

/**

* 读取指定地址的int值

* @param handle 程序句柄

* @param address 地址

* @return 值

*/

public static int readIntOfAddress(HANDLE handle, int address) {

Memory memory = new Memory(4);

IntByReference readByteNumber = new IntByReference();

KERNEL.ReadProcessMemory(handle, Pointer.createConstant(address), memory, 4, readByteNumber);

return memory.getInt(0);

}

/**

* 读取指定地址的int值

* @param handle 程序句柄

* @param pointer 地址

* @return 值

*/

public static int readIntOfPointer(HANDLE handle, Pointer pointer) {

Memory memory = new Memory(4);

IntByReference readByteNumber = new IntByReference();

KERNEL.ReadProcessMemory(handle, pointer, memory, 4, readByteNumber);

return memory.getInt(0);

}

/**

* 读取指定地址的int值

* @param pointer 地址

* @return 值

*/

public static int readIntOfExPointer(ExPointer pointer) {

Memory memory = new Memory(4);

IntByReference readByteNumber = new IntByReference();

KERNEL.ReadProcessMemory(pointer.getHandle(), pointer.getPointer(), memory, 4, readByteNumber);

return memory.getInt(0);

}

/**

* 读取指定地址的double值

* @param exPointer 地址

* @return 值

*/

public static double readDoubleOfExPointer(ExPointer exPointer) {

Memory memory = new Memory(8);

IntByReference readByteNumber = new IntByReference();

KERNEL.ReadProcessMemory(exPointer.getHandle(), exPointer.getPointer(), memory, 8, readByteNumber);

return memory.getDouble(0);

}

/**

* 读取指定地址的float值

* @param exPointer 地址

* @return 值

*/

public static float readFloatOfExPointer(ExPointer exPointer) {

Memory memory = new Memory(8);

IntByReference readByteNumber = new IntByReference();

KERNEL.ReadProcessMemory(exPointer.getHandle(), exPointer.getPointer(), memory, 8, readByteNumber);

return memory.getFloat(0);

}

/**

* 读取指定地址的float值

* @param exPointer 地址

* @return 值

*/

public static long readLongOfExPointer(ExPointer exPointer) {

Memory memory = new Memory(8);

IntByReference readByteNumber = new IntByReference();

KERNEL.ReadProcessMemory(exPointer.getHandle(), exPointer.getPointer(), memory, 8, readByteNumber);

return memory.getLong(0);

}

/**

* 读取指定地址的float值

* @param exPointer 地址

* @return 值

*/

public static byte readByteOfExPointer(ExPointer exPointer) {

Memory memory = new Memory(1);

IntByReference readByteNumber = new IntByReference();

KERNEL.ReadProcessMemory(exPointer.getHandle(), exPointer.getPointer(), memory, 1, readByteNumber);

return memory.getByte(0);

}

/**

* 读取指定地址的float值

* @param exPointer 地址

* @return 值

*/

public static byte[] readByteArray(ExPointer exPointer, int size) {

Memory memory = new Memory(size);

IntByReference readByteNumber = new IntByReference();

KERNEL.ReadProcessMemory(exPointer.getHandle(), exPointer.getPointer(), memory, size, readByteNumber);

return memory.getByteArray(0, size);

}

/**

* 写入到地址

* @param exPointer 指针

* @param value 值

*/

public static void writeValueToExPointer(ExPointer exPointer, Object value) {

Memory memory = null;

if (value instanceof Integer) {

memory = new Memory(4);

memory.setInt(0, (Integer) value);

} else if (value instanceof Float) {

memory = new Memory(4);

memory.setFloat(0, (Float) value);

} else if (value instanceof Double) {

memory = new Memory(8);

memory.setDouble(0, (Double) value);

} else if (value instanceof Long) {

memory = new Memory(8);

} else if (value instanceof byte[]) {

byte[] bytes = (byte[]) value;

memory = new Memory(bytes.length);

memory.write(0, bytes, 0, bytes.length);

}

IntByReference readByteNumber = new IntByReference();

KERNEL.WriteProcessMemory(exPointer.getHandle(), exPointer.getPointer(), memory, 4, readByteNumber);

}

}

一个自定义的指针类

package com.fly.jna.window.util;

import com.sun.jna.Pointer;

import com.sun.jna.platform.win32.WinNT.HANDLE;

import lombok.Data;

import lombok.experimental.Accessors;

@Data

@Accessors(chain = true)

public class ExPointer {

private Pointer pointer;

private HANDLE handle;

public ExPointer() {

}

public ExPointer(HANDLE handle, int address) {

this.handle = handle;

pointer = Pointer.createConstant(address);

}

public ExPointer(Pointer pointer, HANDLE handle) {

this.pointer = pointer;

this.handle = handle;

}

public static ExPointer of(HANDLE handle, int address) {

return new ExPointer(handle, address);

}

public ExPointer offset(int offset) {

int value = WindowsUtils.readIntOfExPointer(this);

int newAddress = value + offset;

return new ExPointer(handle, newAddress);

}

/**

* 获取指针的地址

* @return 地址

*/

public int getAddress() {

return (int) Pointer.nativeValue(pointer);

}

/**

* 读取指针指向的值

* @return int

*/

public int readInt() {

return WindowsUtils.readIntOfExPointer(this);

}

public void writeInt(int value) {

WindowsUtils.writeValueToExPointer(this, value);

}

public double readDouble() {

return WindowsUtils.readDoubleOfExPointer(this);

}

}

Java调用Windows系统API需要使用Java Native Interface(JNI),其主要步骤如下: 1.定义Native方法,用于声明要调用的Windows API函数。 2.编写C/C++代码实现Native方法。 3.将C/C++代码编译成动态链接库(DLL)。 4.在Java代码中加载动态链接库,并调用Native方法。 具体实现步骤如下: 1.定义Native方法 在Java代码中,使用native关键字声明要调用的Windows API函数,例如: ``` public class WinAPI { public static native int MessageBoxA(int hWnd, String lpText, String lpCaption, int uType); } ``` 2.编写C/C++代码实现Native方法 在C/C++代码中,实现声明的Native方法,并使用Windows API函数实现其功能。例如: ``` #include <windows.h> #include "WinAPI.h" JNIEXPORT jint JNICALL Java_WinAPI_MessageBoxA(JNIEnv *env, jclass cls, jint hWnd, jstring lpText, jstring lpCaption, jint uType) { const char *c_lpText = env->GetStringUTFChars(lpText, NULL); const char *c_lpCaption = env->GetStringUTFChars(lpCaption, NULL); int result = MessageBoxA((HWND)hWnd, c_lpText, c_lpCaption, (UINT)uType); env->ReleaseStringUTFChars(lpText, c_lpText); env->ReleaseStringUTFChars(lpCaption, c_lpCaption); return result; } ``` 3.将C/C++代码编译成动态链接库(DLL) 使用Visual Studio等工具编译C/C++代码,生成动态链接库(DLL)文件。 4.在Java代码中加载动态链接库,并调用Native方法 使用System.loadLibrary()方法加载动态链接库,例如: ``` public class Main { static { System.loadLibrary("WinAPI"); } public static void main(String[] args) { WinAPI.MessageBoxA(0, "Hello World!", "Message", 0); } } ``` 以上是Java调用Windows系统API的基本流程,需要注意的是,由于Java是跨平台的语言,因此在使用Windows API时需要特别注意函数参数和返回值的类型和大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值