Java
  • About This Book
  • 🍖Prerequisites
    • 反射
      • 反射基本使用
      • 高版本JDK反射绕过
      • 反射调用命令执行
      • 反射构造HashMap
      • 方法句柄
    • 类加载
      • 动态加载字节码
      • 双亲委派模型
      • BCEL
      • SPI
    • RMI & JNDI
      • RPC Intro
      • RMI
      • JEP 290
      • JNDI
    • Misc
      • Unsafe
      • 代理模式
      • JMX
      • JDWP
      • JPDA
      • JVMTI
      • JNA
      • Java Security Manager
  • 👻Serial Journey
    • URLDNS
    • SerialVersionUID
    • Commons Collection 🥏
      • CC1-TransformedMap
      • CC1-LazyMap
      • CC6
      • CC3
      • CC2
    • FastJson 🪁
      • FastJson-Basic Usage
      • FastJson-TemplatesImpl
      • FastJson-JdbcRowSetImpl
      • FastJson-BasicDataSource
      • FastJson-ByPass
      • FastJson与原生反序列化(一)
      • FastJson与原生反序列化(二)
      • Jackson的原生反序列化利用
    • Other Components
      • SnakeYaml
      • C3P0
      • AspectJWeaver
      • Rome
      • Spring
      • Hessian
      • Hessian_Only_JDK
      • Kryo
      • Dubbo
  • 🌵RASP
    • JavaAgent
    • JVM
    • ByteCode
    • JNI
    • ASM 🪡
      • ASM Intro
      • Class Generation
      • Class Transformation
    • Rasp防御命令执行
    • OpenRASP
  • 🐎Memory Shell
    • Tomcat-Architecture
    • Servlet API
      • Listener
      • Filter
      • Servlet
    • Tomcat-Middlewares
      • Tomcat-Valve
      • Tomcat-Executor
      • Tomcat-Upgrade
    • Agent MemShell
    • WebSocket
    • 内存马查杀
    • IDEA本地调试Tomcat
  • ✂️JDBC Attack
    • MySQL JDBC Attack
    • H2 JDBC Attack
  • 🎨Templates
    • FreeMarker
    • Thymeleaf
    • Enjoy
  • 🎏MessageQueue
    • ActiveMQ CNVD-2023-69477
    • AMQP CVE-2023-34050
    • Spring-Kafka CVE-2023-34040
    • RocketMQ CVE-2023-33246
  • 🛡️Shiro
    • Shiro Intro
    • Request URI ByPass
    • Context Path ByPass
    • Remember Me反序列化 CC-Shiro
    • CB1与无CC依赖的反序列化链
  • 🍺Others
    • Deserialization Twice
    • A New Blazer 4 getter RCE
    • Apache Commons Jxpath
    • El Attack
    • Spel Attack
    • C3P0原生反序列化的JNDI打法
    • Log4j
    • Echo Tech
      • SpringBoot Under Tomcat
    • CTF 🚩
      • 长城杯-b4bycoffee (ROME反序列化)
      • MTCTF2022(CB+Shiro绕过)
      • CISCN 2023 西南赛区半决赛 (Hessian原生JDK+Kryo反序列化)
      • CISCN 2023 初赛 (高版本Commons Collections下其他依赖的利用)
      • CISCN 2021 总决赛 ezj4va (AspectJWeaver写字节码文件到classpath)
      • D^3CTF2023 (新的getter+高版本JNDI不出网+Hessian异常toString)
      • WMCTF2023(CC链花式玩法+盲读文件)
      • 第六届安洵杯网络安全挑战赛(CB PriorityQueue替代+Postgresql JDBC Attack+FreeMarker)
  • 🔍Code Inspector
    • CodeQL 🧶
      • Tutorial
        • Intro
        • Module
        • Predicate
        • Query
        • Type
      • CodeQL 4 Java
        • Basics
        • DFA
        • Example
    • SootUp ✨
      • Intro
      • Jimple
      • DFA
      • CG
    • Tabby 🔦
      • install
    • Theory
      • Static Analysis
        • Intro
        • IR & CFG
        • DFA
        • DFA-Foundation
        • Interprocedural Analysis
        • Pointer Analysis
        • Pointer Analysis Foundation
        • PTA-Context Sensitivity
        • Taint Anlysis
        • Datalog
Powered by GitBook
On this page
  • 0x01 What Is JNA
  • 0x02 Best Pratice

Was this helpful?

  1. 🍖Prerequisites
  2. Misc

JNA

0x01 What Is JNA

前面介绍了JNI,是用于Java调用本地方法的接口,也感受了实现一个native方法的繁琐。

首先得在Java代码中定义native方法,然后通过javah命令生成对应的头文件,再使用C实现头文件中声明的方法。Java和C++之间的数据类型映射也十分麻烦。

让一个Java程序员去开发C程序自然不好,专业问题得交给专业人士去完成。

JNA(Java Native Access)是一个Java框架,它会在运行期间动态访问本地共享类库,只要在Java接口中描述目标本地库的函数,JNA会自动实现映射,不需要编写任何JNI代码。

在实际开发中,共享类库就可以由专业的C++工程师去实现,Java调就完事了。

0x02 Best Pratice

首先得准备一个共享类库

CMakeLists.txt👇

cmake_minimum_required(VERSION 3.29)
project(myLib)

set(CMAKE_CXX_STANDARD 20)

add_library(myLib SHARED library.cpp)

library.h👇

#ifndef MYLIB_LIBRARY_H
#define MYLIB_LIBRARY_H
#ifdef __cplusplus
extern "C"
{
    int max(int, int);
}
#endif
#endif

由于C++支持函数重载,因此编译器在编译函数的过程中,会将函数的参数类型等也加入到编译后的代码中,因此编译出来的动态链接库中所含的函数名称与原函数名称是不同的。

这使得JNA调用动态链接库时无法找到原来的函数名,需要在头文件中对外提供的函数前面声明extern "C",让编译器以C语言的形式编译接口。否则会报如下错:

java.lang.UnsatisfiedLinkError: Error looking up function max

library.cpp👇

#include "library.h"

int max(int num1, int num2) {
    return num1 > num2 ? num1 : num2;
}

制作完动态链接库后,就可以看Java这侧了

引入JNA依赖

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.10.0</version>
</dependency>

C和Java的数据类型映射:

将编译好的 myLib.dll 放入 resources 文件夹下的 win32-x86-64 目录中

接着定义一个继承Library的接口

Native.load第一个参数为共享库文件的名称,它会先在当前类路径下找,找不到再去相应操作系统和位数的文件夹下找。

第二个参数为当前的接口类,它会根据这个接口类生成动态代理并返回

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

public interface JnaLibrary extends Library {
    JnaLibrary INSTANCE = Native.load("myLib", JnaLibrary.class);
    int max(int a, int b);
}

接着就用Native.load返回赋值给的静态成员INSTANCE来调用

int max = JnaLibrary.INSTANCE.max(125, 135);
System.out.println(max);  // 135
PreviousJVMTINextJava Security Manager

Last updated 7 months ago

Was this helpful?

image-20240928170247288