java - 从 nasm 创建的 dll 使用 JNIEnv

标签 java assembly java-native-interface nasm jnienv

我一直在尝试调用 JNIEnv 函数 GetVersion (对于初学者来说), 其索引为 4(根据 this site )。

我一直在使用this site供引用,并使用 [ebp + x] 而不是参数名称将 masm 代码调整为 nasm。

以下类和程序集文件应该创建一个乱码输出,但错误消息会将我引导到日志文件。
在这个非常大的日志文件中,我发现特别有趣的是,所谓的寄存器到内存映射似乎并不将寄存器的内容识别为 JNIEnv 函数(在 eax 中),而是将其识别为未知值。

谁能告诉我我做错了什么?
我只会根据请求附加日志,因为它相当大。

Java 代码:

public class Ver {
  private static native int ver();
  public static void main(String[] args) {
    System.loadLibrary("my32");
    System.out.println(ver());
  }
}

ASM 代码:

;my32.asm
segment .text
;JNIEXPORT void JNICALL Java_Ver_ver
;  (JNIEnv *, jclass);
global _Java_Ver_ver
_Java_Ver_ver:
    push ebp
    mov ebp, esp
    push ebx

    mov ebx, [ebp+8]
    mov eax, [ebx]

    mov ebx, eax
    mov eax, 4
    mov ecx, 4
    mul ecx
    add ebx, eax
    mov eax, [ebx]
    push dword [ebp+8]
    call [eax]

    pop ebx
    pop ebp
    ret 8
;assembled using nasm -fwin32 my32.asm
;linked using gcc -o my32.dll -shared my32.obj
;with mingw-gcc

希望这对于 SSCE 来说是一个有趣的问题
此致

最佳答案

看来您的间接寻址太多了:

mov ebx, [ebp+8]   ; ebx = env
mov eax, [ebx]     ; eax = *env
...
mov eax, [ebx]     ; eax = (*env)->GetVersion
...
call [eax]         ; call *((*env)->GetVersion)

所以call应该是call eax(不带括号)。

此外,您可以删除偏移 ebx 的方法,只需执行 mov eax, [ebx + 16] 即可。或者使用call [ebx + 16]

关于java - 从 nasm 创建的 dll 使用 JNIEnv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23580204/

相关文章:

java - 用作 websphere 8 应用程序的 -javaagent 的 openjpa jar 位于哪里?

java - 我发现了很多关于抽象类和接口(interface)的问题,但请回答我这个 : Can an abstract class do everything an interface can?

java - 如何显示格式化的联系电话?

windows-mobile - 获取 ARM 汇编中的 PC 值

java - 调用JNI方法时如何获取Android上下文实例?

java - 如何使用 java 合并 .webm(音频)文件和 .mp4(视频)文件?

java - 如何获取这一天(例如 : Monday) from a time Instant in FreeMarker

c - 可执行文件中的数据位于奇怪的位置

assembly - 使用汇编中的 .reloc

java - 使用 JNI 时出现 UnsatisfiedLinkError?