我是新来的。同样,我需要一些帮助,使用JNA将一些C#代码转换为Java来调用本机Windows函数。
首先,这是我想要转换的代码: http://pastebin.com/0b5zMvBg
到目前为止,我编写了JNA接口来表示Kernel32和NtDll库。在Kernel32库中,我还定义了我需要使用的结构。
Kernel32.java http://pastebin.com/93xTvD0T
NtDll.java http://pastebin.com/giup88Tk
在我定义了库和结构后,我继续编写非本机函数。问题是,我不了解所有的C#语法。但是,我确实理解C#中的所有Java功能。
这是我到目前为止所写的内容;请注意,我已经评论了我不理解的内容以及我对转换的疑问。大多数问题都重复了,这意味着如果你为我提供甚至一次转换,我可能会弄清楚如何做其余的事情。在此先感谢任何帮助! : - )
答案 0 :(得分:2)
一般来说,你甚至没有做任何特定的C#,而是基本的C指针算法。
绕过数据块并在数据类型之间执行转换的最简单方法是使用com.sun.jna.Memory
而不是byte[]
。您可以使用Pointer.share(long offset)
执行指针运算(结果是原始指针偏移所请求的数量)。您可以使用各种Pointer.write()
或Pointer.readXXX()
变体来读取和写入本机内存。
您可以使用Structure
作为基址来初始化Java端Pointer
对象,只需记住显式调用Structure.read()
以将本机内存同步到Java。
一些例子,来自你的糊涂:
Memory data = ...;
// mzH = *(MZHeader*) dPtr;
MZHeader mzH = new MZHeader(data);
mzH.read(); // or put this in the MZHeader(Pointer) ctor
// peH = *(PE_Header*)&dPtr[mzH.offsetToPE];
PE_Header peH = new PE_Header(data.share(mzH.offsetToPE));
peH.read(); // or put this in the PE_Header(Pointer) ctor
// peXH = *(PE_ExtHeader*)&dPtr[mzH.offsetToPE + sizeof(PE_Header)];
PE_ExtHeader peXH = new PE_ExtHeader(data.share(mzH.offsetToPE + peH.size()));
peXH.read(); // or put this in the PE_ExtHeader(Pointer) actor
我认为你可以从那里得到这个想法......
修改强>
Pointer p = new Memory();
byte[] data = ...;
// Copy into Memory from data
p.write(0, data, 0, data.length);
// Copy out of Memory into data
p.read(0, data, 0, data.length);
答案 1 :(得分:1)
所以你的Kine.Run()看起来像这个代码的主要入口点。它的作用是获取给定的字节数组,分叉当前进程,然后用字节数组覆盖当前进程内存并开始执行它。如果实现了这一点,则将字节数组作为子进程运行。
现在,假设字节数组来自文件系统中的某个文件(或者可以在那里写入),您可以使用以下行替换所有这些代码:
Runtime.getRuntime().exec(filename);
假设文件名是包含字节数组的文件。不需要了解PE头或窗口内部。如果字节数组来自一些你无法在本地存储的地方,那么无论如何你都无法运行它。
答案 2 :(得分:-1)
不要迂腐,但不要这样做。您正在尝试在JVM中运行C#程序?编写一个抽象出应用程序的OS特定部分的层会更简单,更快捷。您可以在C#中执行一些无法在JVM中运行的操作。比如加载DLL然后调用它们中的方法。或者从Windows消息循环中获取消息。
现在,我同意您可能想要做的一些事情只能从本地库中完成。喜欢与其他窗口交互。但是你正在用Java重新实现CLR。这是一项巨大的工作,有些部分永远不会工作。
就是不要这样做。 (在这里插入耐克旋风)