如何在ASM中编写本机代码

时间:2018-04-29 11:46:17

标签: java java-native-interface java-bytecode-asm

我是一名狂热的ASM作家。我试图在asm中编写本机java代码。 我遇到的问题是从Java传递的参数似乎没有被asm代码接收。 C ++代码似乎使用windows 64位调用约定接收参数,即rcx,rdx,r8,r9,stack,最初我假设它对于asm是相同的但是它似乎不是这样。我花了很长时间寻找可能的解释和例子,但还没找到,所以我想我会问。我将非常熟悉一些确定我出错的地方。非常感谢你。下面是代码snipets解释我到目前为止开发的内容......

在NativeInterface.java中

public native static String test(int _number);

在Calling.java中

String s=NativeInterface.test(123);

在NativeJava.asm中

.data
dString     db  "This is my string",0
.code
java_test PROC _iNumber:QWORD
 invoke dialog_showMessageInteger,"ASM CODE","Number=",_iNumber
 mov rax,rv(java_createStringUTF8,JNIenv,ADDR dString)
 ret
java_test ENDP

在asm中打开的对话框不显示“123”而是显示“1918844240” 上面的代码成功地将字符串传递给java。

似乎我可以成功地从asm将参数传递给java。 此时我无法将参数从java传递给asm。

我希望使用标准的Windows 64位调用约定,但似乎不是这样。我在任何地方都找不到任何文件。有人可以解释我应该在asm中期待什么。 很多,非常感谢。

2 个答案:

答案 0 :(得分:2)

感谢Peter Cordes建议可能会传递一些隐藏的参数并反汇编一些C ++代码以便确定。

我不需要那么远。我一直在看C ++代码,我注意到所有的本机例程都有JNIenv和jclass作为前两个参数。

我将我的代码改为阅读......

java_test PROC _JNIenv:QWORD,_jclass:QWORD,_iNumber:QWORD

确实给出了123的值。

猜测前两个参数是JNIenv和调用类,但考虑到它是如何形成C ++函数的,我认为这是一个非常好的猜测。

感谢您的帮助和支持。 问候 一分钱 保重

答案 1 :(得分:0)

使用JNI:

  1. 在类中编写native方法。
  2. 编译课程。
  3. 使用javah(或Java 10,javac)生成C / C ++头文件。
  4. 使用您选择的语言,实现生成的签名的功能,就像C或C ++与Java供应商提供的头文件和库一样。务必逐字导出函数名称。
  5. 当您需要进行Java调用时:

    1. 使用javap -s查找相应的Java签名和类型说明。
    2. 选择一个JNI调用函数,具体取决于传递参数的方式以及您调用的方法类型。