0
点赞
收藏
分享

微信扫一扫

maven的settings.xml配置

7dcac6528821 2024-09-23 阅读 23
javawindows

使用jna调用windows api,前提是jna提供了dll的一些操作方法, 但是具体接口映射需要在java实现一遍映射

这里分了几个小文件做映射

先看main class

/*
 * This source file was generated by the Gradle 'init' task
 */
package wpcap.app;

import java.net.InetAddress;

import com.sun.jna.ptr.IntByReference;

import wpcap.library.WinSock2Library;
import wpcap.library.structure.WsaDataStructure;
import wpcap.library.structure.SockaddrInStructure;


public class Main {
    public static void main(String[] args) {
        // 开启 WSAStartup
        WsaDataStructure WsaDataStructure = new WsaDataStructure();  
        int errno = WinSock2Library.INSTANCE.WSAStartup((short)0x0202, WsaDataStructure);  

        if (errno != 0) {  
            System.out.println("WSAStartup: " + errno);  
            return;
        }

        System.out.println(new String( WsaDataStructure.szDescription ) );  

        // 创建 socket
        long raw_socket = WinSock2Library.INSTANCE.socket(WinSock2Library.AF_INET, WinSock2Library.SOCK_RAW, WinSock2Library.IPPROTO_IP);
        System.out.println("socket: " + raw_socket);  
        if (raw_socket == 0) {  
            System.out.println("socket: " + errno);  
            return;
        }

        // 允许接收ip头
        byte[] enable = {1};
        WinSock2Library.INSTANCE.setsockopt(
            raw_socket, 
            WinSock2Library.IPPROTO_IP, 
            WinSock2Library.IP_HDRINCL, 
            enable, 
            Integer.SIZE
        );

        // 绑定监听的ip和端口
        SockaddrInStructure SockaddrInStructure = new SockaddrInStructure();
        SockaddrInStructure.sin_family = (short)WinSock2Library.AF_INET;
        SockaddrInStructure.sin_port = (short)0;
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            byte[] ip = localHost.getAddress();

            System.arraycopy(ip, 0, SockaddrInStructure.sin_addr, 0, 4);
        } catch (Exception e) {
            System.out.println(e);  
        }
    
        errno = WinSock2Library.INSTANCE.bind(raw_socket, SockaddrInStructure, SockaddrInStructure.size());
        if (errno != 0) {  
            System.out.println("bind: " + errno);  
            return;
        }

        // 设置混杂模式
        IntByReference dwValue = new IntByReference( WinSock2Library.SIO_RCVALL_ON );
        errno = WinSock2Library.INSTANCE.ioctlsocket( raw_socket, WinSock2Library.SIO_RCVALL, dwValue );
        if (errno != 0) {  
            System.out.println("WSAGetLastError: " + errno);  
            return;
        }

        System.out.println("启动成功");  

        // 开始接收数据包
        byte[] buf = new byte[512]; 
        while (true) {
            int rec = WinSock2Library.INSTANCE.recv(raw_socket, buf, 512, 0);
            if ( rec != -1 ) {
                System.out.println("rec: " + rec);  
            }
        }
    }


}

接着是WinSock2Library.java 映射WinSock2.h

package wpcap.library;

import com.sun.jna.Library;  
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;

import wpcap.library.structure.WsaDataStructure;  
import wpcap.library.structure.SockaddrInStructure;  

// char*	ByteByReference或Pointer
// char**	PointerByReference
// char&	PointerByReference

// int*	    IntByReference或Pointer
// int&	    IntByReference

// float*	FloatByReference或Pointer
// double*	DoubleByReference或Pointer

// void **	PointerByReference
// void*	Pointer

// LPCVOID  byte[]/Pointer
// DWORD    int/long
// LPDWORD  IntByReference/LongByReference
// LPOVERLAPPED com.sun.jna.platform.win32.WinBase.OVERLAPPED
// OVERLAPPED com.sun.jna.platform.win32.WinNT.OVERLAPPED_COMPLETION_ROUTINE
// LPCWSTR  String
// LPWSTR   char[]/String
// HANDLE   com.sun.jna.platform.win32.WinNT.HANDLE
// SIZE_T   int/long
// PDWORD   DWORDByReference

// Pointer  Memory
// DWORD    DWORD

public interface WinSock2Library extends Library {
    WinSock2Library INSTANCE = (WinSock2Library) Native.load("ws2_32", WinSock2Library.class);

    int WSAStartup(short wVersionRequired, WsaDataStructure lpWSAData);

    long socket(int family, int socktype, int protocol);

    int setsockopt(long socket, int protocol, int opt, byte[] optVal, int optLen);

    int bind(long socket, SockaddrInStructure sockaddr, int sockaddr_len);

    int ioctlsocket(long socket, long dwIoControlCode, IntByReference lpvInBuffer);

    int recv(long socket, byte[] buf, int len, int flags);

    int WSAGetLastError();

    int AF_INET = 2;

    int SOCK_RAW = 3;

    int IPPROTO_IP = 0;

    long SIO_RCVALL = 0x98000001L; // 2550136833

    int SIO_RCVALL_ON = 0x00000001;

    int IP_HDRINCL = 2;
}

接着是结构体映射

WsaDataStructure.java

package wpcap.library.structure;

import com.sun.jna.Structure;  
import com.sun.jna.Structure.FieldOrder;  

@FieldOrder({"wVersion", "wHighVersion", "szDescription", "szSystemStatus", "iMaxSockets", "iMaxUdpDg", "lpVendorInfo"})
public class WsaDataStructure extends Structure {
    public short wVersion;  
    public short wHighVersion;  
    public short iMaxSockets;  
    public short iMaxUdpDg;  
    public char lpVendorInfo;  
    public byte[] szDescription = new byte[WSADESCRIPTION_LEN + 1];  
    public byte[] szSystemStatus = new byte[WSASYS_STATUS_LEN + 1];  

    public static final int WSADESCRIPTION_LEN = 256;  
    public static final int WSASYS_STATUS_LEN = 128;  
}

SockaddrInStructure.java

package wpcap.library.structure;

import com.sun.jna.Structure;  
import com.sun.jna.Structure.FieldOrder;  

@FieldOrder({"sin_family", "sin_port", "sin_addr", "sin_zero"})
public class SockaddrInStructure extends Structure {
    public short sin_family;
    public short sin_port;
    public byte[] sin_addr = new byte[4];
    public byte[] sin_zero = new byte[8];
}

Library是映射对应的dll接口

Struture是映射一些数据结构

以这种映射的方法达到java使用jna来调用windows api实现抓包

举报

相关推荐

0 条评论