java JNI調用動態庫 獲取硬件信息 製作軟件加密


一、java JNI 調用動態庫

     1、在MyEclipse 中創建一個test的web工程

     2、在工程下創建一個class文件  package名爲JNI ,類名test

     3、在test下面定義一個方法

    

  package JNI;

  public class getCPUID {
	//定義一個方法 該方法是在dll中實現
	public native static String getcpuID();
	static
	{
	 System.loadLibrary( "getCPUID" ); //加載dll庫
	}
  }


     4、發佈該web 程序(目的是把test類編譯成class文件,你也可以直接用編譯工具編譯該clss文件)

     5、 將在發佈後的文件中找到該 JNI文件夾  ,複製該文件夾所在路徑(發佈的是放在resin)

          D:\yys\resin-pro-3.1.7a\deploy\test2\WEB-INF\classes\JNI

     6、打開dos命令行 輸入cd  D:\yys\resin-pro-3.1.7a\deploy\test2\WEB-INF\classes\

         (如果cd 目錄沒變,那在後面在 輸入 d: 回車 一般不會出先這種問題 ,但是我很幸運的 遇到了)

     7、javah  JNI.getCPUID  此時生成JNI_getCPUID.h頭文件

     8、創建一個空的win32  dll項目 ,我這用的是vs2008   visual c++   win32項目  空項目 名稱

          getCPUID(注 這個要與System.loadLibrary( "getCPUID" ); //加載dll庫中名稱一致)

     9、分別把java安裝路徑下 C:\Program Files\Java\jdk1.5.0_06\include 文件夾中的  jni.h  與

          C:\Program Files\Java\jdk1.5.0_06\include\win32  jin_md.h 及先前生成的JNI_getCPUID.h

         拷貝到c++項目的工程目錄下。

    10、把剛拷貝過來的頭文件添加到項目的頭文件夾中

    11、創建一個 getCPUID.cpp文件   在該文件添加如下代碼

#include "JNI_getCPUID.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//彙編獲取 cpu編號
int getCPUID(char * cpuid)
{

  unsigned long s1,s2,s3,s4;
  unsigned long s11,s22,s33,s44;
 char p1[128]; char p2[128];  char p3[128]; char p4[128];
 unsigned int eax = 0;
 unsigned int ebx,ecx,edx;
__asm 
{ 
	mov  eax,   1;
	cpuid ; 
	mov  s1,   eax 
	mov  s2,   ebx 
	mov  s3,   ecx 
	mov  s4,   edx 
} 

 s11=s1;	s22=s2;	s33=s3;	s44=s4;
 //這裏猶豫cpu 真實的序列號在p4之後就被禁止使用只能取到第32 processorID
 sprintf(cpuid, "%08X%08X", s44,s11); 
 return 0;
}

//char  轉 jstring 
jstring stoJstring(JNIEnv* env,  char* pat) 
{ 
       jclass strClass = env->FindClass("Ljava/lang/String;"); 
       jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); 
       jbyteArray bytes = env->NewByteArray(strlen(pat)); 
       env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); 
       jstring encoding = env->NewStringUTF("utf-8"); 
       return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); 
} 
//數據類型轉換
JNIEXPORT jstring JNICALL Java_JNI_getCPUID_getcpuID
  (JNIEnv * env, jclass js)
{
	  char cpuid[40];
   getCPUID(cpuid);
    return stoJstring(env,cpuid);
}

  12、修改JNI_getCPUID.h 文件的<jni.h> 把<>改爲“” 否則 會包找不到頭文件錯誤。

  13、編譯項目把生成的 getCPUID.dll 拷貝到任何一個換件變量path 路勁下就可以 我這拷貝到

        C:\Program Files\Java\jdk1.5.0_06\bin 文件夾下

  14、做個一個是測試的jsp頁面 或者 在上面的java文件的類後面 加一個 main方法進行測試 加完mian如下

    

package JNI;


public class getCPUID {
	//定義一個方法 該方法是在dll中實現
	public native static String getcpuID();
	static
	{
	 System.loadLibrary( "getCPUID" ); //加載dll庫
	}

public static void main(String[] args) {
	//yysLic u=new yysLic();
	@SuppressWarnings("unused")
	String ls_cpuID=getCPUID.getcpuID();
	
	
}
}


調試  查看 ls_cpuID 變量的值 

      

  15、在寫jni代碼是常用的 java與c++類型轉換的 方法(注 int 不需要手動轉能自動轉換)

        //char * 轉java的jstring

     

jstring stoJstring(JNIEnv* env,  char* pat) 
{ 
       jclass strClass = env->FindClass("Ljava/lang/String;"); 
       jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); 
       jbyteArray bytes = env->NewByteArray(strlen(pat)); 
       env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); 
       jstring encoding = env->NewStringUTF("utf-8"); 
       return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); 
} 
//


       //jstring 轉 char*

//jstring to char* 
char* jstringTostring(JNIEnv* env, jstring jstr) 
{ 
       char* rtn = NULL; 
       jclass clsstring = env->FindClass("java/lang/String"); 
       jstring strencode = env->NewStringUTF("utf-8"); 
       jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); 
       jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); 
       jsize alen = env->GetArrayLength(barr); 
       jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); 
       if (alen > 0) 
       { 
                 rtn = (char*)malloc(alen + 1); 
                 memcpy(rtn, ba, alen); 
                 rtn[alen] = 0; 
       } 
       env->ReleaseByteArrayElements(barr, ba, 0); 
       return rtn; 
} 

  16、猶豫java不能直接獲取電腦硬件信息通過該方法能獲取到 電腦的信息也能通過該方法對公司的一些核心代碼算法
         進行加密 軟件論證等 這都是比較好用   。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章