2017-10-04 26 views
1

DLLから情報(キー)を抽出する小さなCライブラリを作成しました。JNA:無効なメモリアクセス

GetKey.h

#pragma once 

#include <stdint.h> 

#define getKey(x) getKeyL(x) 
#define getKey(x,y) getKeyP(x,y) 

void __declspec(dllexport) getKeyP(char *path, uint8_t key[]); 
void __declspec(dllexport) getKeyL(uint8_t key[]); 

GetKey.c

#include "getkey.h" 

#include <stdio.h> 
#include <string.h> 
#include <windows.h> 

void __declspec(dllexport) getKeyP(char *path, uint8_t key[]) 
{ 
    int lib = LoadLibraryA((path != NULL) ? path : "myLib"); 
    ((void(*)(void))(lib + 0x1340))(); 
    lib += 0x14020; 

    for (int i = 0; i < 8; ++i) 
    { 
     key[i] = *(uint8_t*)(lib + (i << 4)); 
    } 

    FreeLibrary(lib); 
} 

void __declspec(dllexport) getKeyL(uint8_t key[]) 
{ 
    getKeyP(NULL, key); 
} 
そうのような

私のJavaバインディングルックス:私はgetKeyPgetKeyL を起動するたびに、私はスローされた例外を取得し

public class GetKey 
{ 
    private static final GetKeyBinding INSTANCE; 

    static 
    { 
     System.setProperty("jna.library.path", "lib/dll/"); 

     GetKeyBinding lib; 

     try 
     { 
      lib = Native.loadLibrary("x86_64/GetKey.dll", GetKeyBinding.class); 
     } 
     catch (UnsatisfiedLinkError e) 
     { 
      try 
      { 
       lib = Native.loadLibrary("i386/GetKey.dll", GetKeyBinding.class); 
      } 
      catch (UnsatisfiedLinkError f) 
      { 
       System.err.println("Failed to load library"); 
       lib = null; 
      } 
     } 

     INSTANCE = lib; 
    } 

    public static void getKey(byte[] path, byte[] key) 
    { 
     INSTANCE.getKeyP(path, key); 
    } 

    public static void getKey(byte[] key) 
    { 
     INSTANCE.getKeyL(key); 
    } 

    private static interface GetKeyBinding extends Library 
    { 
     void getKeyP(byte[] path, byte[] key); 
     void getKeyL(byte[] key); 
    } 
} 

私はパラメータを変更しようとしましたbyte[]からPointerByteBufferのタイプもありますが、私もextend ing StdCallLibraryを試しました(当初はあまり意味がありませんでしたが、試しても痛いことはありませんか?)。

私はそれを印刷するように期待していまさにコンソールに出力します
#include <stdio.h> 
#include "GetKey.h" 


int main() 
{ 
    uint8_t key[8]; 
    getKeyP(NULL, key); 

    for (int i = 0; i < 8; ++i) 
    { 
     printf("%02X ", key[i]); 
    } 
    getchar(); 
    return 0; 
} 

を任意の助けを喜んで高く評価され ...:私はそれのために小さなテストアプリケーションを書いたので、私は、コードが動作する知っています!私はそうのように、Javaから私の関数を呼び出してい

編集私のDLLとデバッグにデバッガをアタッチした後

byte[] key = new byte[8]; 
GetKey.getKey(key); 
+0

あなたも、あなたが呼んでいる方法を含めることができます: - : 私は私のJavaコード変更することで、これを固定

public static void getKey(String path, byte[] key) { INSTANCE.getKeyP((path + '\0').getBytes(), key); } 

をそして意図したとおり、今では動作します(。 Javaの関数ですか? – cubrr

+0

その場合NullPointerExceptionが発生しないでしょうか?コードがDLLのロードを試みる順序を変更しようとしましたが、もちろん、32bit DLLであり、もう1つは64bit代替です(または、おそらく私はここで完全にオフになっています) – user3320529

+0

'lib == 0'なら' 0x1340'で関数を呼び出そうとしています。セグメンテーションフォールトや不正なメモリアクセスが起こるでしょう。 – cubrr

答えて

0

、私は例外の理由は「ゴミ」であることを発見しました文字は意図した文字列の後に渡されます。あなたは `LoadLibrary`が失敗することを考慮すべき

+0

最初のパラメータの型を 'String'に変更できます。 JNAはそれをマーシャリングすることができます。 – cubrr

関連する問題