Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

Java 

I need help on using the Java Native Interface (JNI)

I want to make some mods for a popular game known as "Minecraft". However, I hate the Java programming language, but do know a lot about it. I also know a lot of the C programming language, and would like to make some native methods to process my functions in C. I tried looking online, but I could not understand any of the tutorials. If anyone here is experienced with Java, C, and the JNI, please help me on setting it up, and using it. Thank-you.
You're a fucking idiot if you think it's a good idea to have a Minecraft client that uses any form of native bridge. Minecraft is Java, you wanna write mods for it? Write them in Java. I'd love to see your attempts at writing process memory in the JVM address space or whatever fucking Windows C exploit your gonna pull for this one.

Anyways, it's really easy and I'm surprised a self-acclaimed C programmer like you can't do it. Fail.
All I can say is: read the tutorials again, it's really very simple.
Just learn Java, I don't understand why anyone would make mods with native code unless it is like some advanced graphics shit that you can't get lwjgl to do for you.
Besides that, there's the System.loadLibrary method which can load in your native mods (I think Java 8 allows static linking, but I would go with dynamic links cas you should do that). You can use javah to generate header files.
(Jun 29, 2015 02:14 PM)WildeThing Wrote:  You're a fucking idiot if you think it's a good idea to have a Minecraft client that uses any form of native bridge. Minecraft is Java, you wanna write mods for it? Write them in Java. I'd love to see your attempts at writing process memory in the JVM address space or whatever fucking Windows C exploit your gonna pull for this one.

Anyways, it's really easy and I'm surprised a self-acclaimed C programmer like you can't do it. Fail.
All I can say is: read the tutorials again, it's really very simple.

No need to be rude. Also, all of the libraries in Java lead up to C or C++. Without natives, you couldn't do anything in Java, really. You're not very smart for not thinking about that. I can't do it, because I cannot understand any of the tutorials online. And, if it's very simple, please help me out, as that is the point of this thread. Thank-you.
JNI is very useful, however it's cons outweigh it's pros unless it is something that can be improved by faster native processing(ie a String Replace is 144x faster than Java in C), or if you need to do native calls(in Linux, setuid, etc). You may be able to use it in this case, but the overhead of JNI will be very bad for performance in such a high-throughput way. In rendering, you'll likely see issues with OpenGL context. You really should never mix and match unless it's either of these two cases.

If you still want to do it, I always thought it was harder than it really was. Run javah on a file containing methods with native flags, fill in a C/C++ file for them, compile, and then do System.load/loadLibrary on the file.

JNI has a considerable invokation overhead, you can see specific benchmarks online, or run them yourself to put them in perspective.
(Jun 30, 2015 01:20 PM)JavaProphet Wrote:  JNI is very useful, however it's cons outweigh it's pros unless it is something that can be improved by faster native processing(ie a String Replace is 144x faster than Java in C), or if you need to do native calls(in Linux, setuid, etc). You may be able to use it in this case, but the overhead of JNI will be very bad for performance in such a high-throughput way. In rendering, you'll likely see issues with OpenGL context. You really should never mix and match unless it's either of these two cases.

If you still want to do it, I always thought it was harder than it really was. Run javah on a file containing methods with native flags, fill in a C/C++ file for them, compile, and then do System.load/loadLibrary on the file.

JNI has a considerable invokation overhead, you can see specific benchmarks online, or run them yourself to put them in perspective.

Thank-you for being the only helpful (and respectful) individual on HackForums to me. I never knew that it had an overhead. I tried your steps, and they worked. I will stick to Java for modifying Java software. Again, thanks a lot. You taught me something today.
(Jun 30, 2015 01:20 PM)JavaProphet Wrote:  JNI is very useful, however it's cons outweigh it's pros unless it is something that can be improved by faster native processing(ie a String Replace is 144x faster than Java in C), or if you need to do native calls(in Linux, setuid, etc). You may be able to use it in this case, but the overhead of JNI will be very bad for performance in such a high-throughput way. In rendering, you'll likely see issues with OpenGL context. You really should never mix and match unless it's either of these two cases.

If you still want to do it, I always thought it was harder than it really was. Run javah on a file containing methods with native flags, fill in a C/C++ file for them, compile, and then do System.load/loadLibrary on the file.

JNI has a considerable invokation overhead, you can see specific benchmarks online, or run them yourself to put them in perspective.
There are no string replaces functions in C.
It's up to the programmer himself to optimize the function for 'string replacing' which is really a subset of finding individual bytes in memory and comparing them with the comparison operand. !memcmp is one way of coming by it, but using bitwise operations and assembly you can decrease the amount of time it takes to find it, also keep in mind with memcmps return value. That also plays a part.
@peak Yeah, that's implicit. I ported my C algorithm into Java as closely as possible, and it was 6x faster then.
(Jun 30, 2015 01:51 PM)JavaProphet Wrote:  @peak Yeah, that's implicit. I ported my C algorithm into Java as closely as possible, and it was 6x faster then.

You have to also take into account the fact that all code that is ran by the machine, is understood by the machine. The JVM optimizes the byte code into it's machine code equivalent.

It's all dependant on the programmer himself to create a faster algorithm, not the language.

I've written sorting algorithms in assembler and c that far exceed the speed of java's equivalents.
(Jun 30, 2015 01:51 PM)JavaProphet Wrote:  @peak Yeah, that's implicit. I ported my C algorithm into Java as closely as possible, and it was 6x faster then.

What algorithm are you talking about? If you just use mutable strings in Java it's going to be faster no matter what secret string replacement algo you use.
Mutable strings are always faster, as it doesn't require as much reallocation, memory copying, etc. My algorithm ported from C to Java only worked on char arrays, and I just wrote a wrapper for immutable strings. I've personally come more and more to loathe immutable strings, as they are a real performance drain. A 1kb immutable string is horrible to do parsing on. All C 'strings' are mutable, unless you enforce immutability on your own code.

C replace:
Spoiler (Click to View)

Java replace(custom):
Spoiler (Click to View)
(Jun 30, 2015 04:00 PM)JavaProphet Wrote:  Mutable strings are always faster, as it doesn't require as much reallocation, memory copying, etc. My algorithm ported from C to Java only worked on char arrays, and I just wrote a wrapper for immutable strings. I've personally come more and more to loathe immutable strings, as they are a real performance drain. A 1kb immutable string is horrible to do parsing on. All C 'strings' are mutable, unless you enforce immutability on your own code.

C replace:
Spoiler (Click to View)

Java replace(custom):
Spoiler (Click to View)

There are many redundancies in your C representation.

calculating null terminated strings in the function itself is redundant (pass them onto the stack).

Your replace function should 1. Locate the string you want to replace in memory
2. Overwrite that string.

Instead of reallocating memory for the buffer block (What if this is a local buffer? undefined behaviour...)
You would want to copy the entire string onto the heap, along with the new size + (New string to replace length - initial string to replace length)

Something along the lines of this

Code
BOOL CompareMemoryWithMask(unsigned char* ucSignature, DWORD dwAddress,DWORD dwSig)
{
    for (; dwSig > 0; --dwSig, ++ucSignature, ++dwAddress)
    {
        if (*ucSignature != '?' && *ucSignature != *(unsigned char*)dwAddress)
            return FALSE;
    }
    return TRUE;
}

DWORD FindMemory(unsigned char* ucSignature, DWORD dwModuleBase, DWORD dwModuleSize,DWORD dwSig)
{
    DWORD i = 0;
    for (i = 0; i < dwModuleSize; i++)
    {
        if (CompareMemoryWithMask(ucSignature,dwModuleBase+i,dwSig))
        {
            return dwModuleBase+i;
        }
    }
    return 0;
}

Compile with intrinsic option, or you can create an intrinsic function.

For the signature you'd pass the string you want to find the buffer, the module size is the buffer size, the module base is the start of the buffer, dwsig is the string length you want to find in the buffer.
(Jun 30, 2015 04:04 PM)peaksoonpeak Wrote:  There are many redundancies in your C representation.

calculating null terminated strings in the function itself is redundant (pass them onto the stack).

Your replace function should 1. Locate the string you want to replace in memory
2. Overwrite that string.

Instead of reallocating memory for the buffer block (What if this is a local buffer? undefined behaviour...)
You would want to copy the entire string onto the heap, along with the new size + (New string to replace length - initial string to replace length)

Not a bad idea. I'm still new to C. Thanks!

EDIT: What exactly do you mean by calculating the null terminated string? The lengths?
How exactly do I copy a larger/smaller string onto the heap? Avoiding overflows?
(Jun 30, 2015 04:08 PM)JavaProphet Wrote:  Not a bad idea. I'm still new to C. Thanks!

EDIT: What exactly do you mean by calculating the null terminated string? The lengths?
How exactly do I copy a larger/smaller string onto the heap? Avoiding overflows?

I've posted code above for finding a said string in a said buffer.

For example, let's take this buffer

"IAMTHEBUFFER"

I'd like to replace THE with A

So the function above will find 'THE' at Buffer+0x03.

You will then allocate memory with malloc with the size defined as,

dwNewBufferSize = dwCurrentBufferSize + (Length of A - Length of THE)

dwNewBufferSize = dwCurrentBufferSize - 2

You then allocate memory, copy the first 3 bytes of the initial buffer (iam) then copy the new string (a) then copy the rest.

memcpy(lpNewBuffer, Buffer, (DWORD)((Buffer) - (Buffer+0x03)); Remember, buffer+0x03 was the location of the string in the buffer. We want to copy the first portion of the buffer into the newly allocated block.

Then you copy the new string

memcpy(lpNewBuffer+((DWORD)((Buffer) - (Buffer+0x03)), NewStringWhatEver, lengthofnewstring);

In this line of code we will be copying 'A' to lpnewbuffer + the previous portion

Then you finally copy the rest.

The first portions of the initial buffer were IAMTHE so what we are going to do is define the location of the initial buffer as,
LPVOID lpTempBuffer = (LPVOID)(Buffer+strlen("IAMTHE"));
and the length we copy over

DWORD dwTempBuffer = ((DWORD)Buffer + strlen(Buffer)) - (DWORD)lpTempBuffer

memcpy(lpNewBuffer+((DWORD)(Buffer)-(Buffer+0x03))+Lengthofnewstring, lpTempBuffer, dwTempBuffer);
@peaksoonpeak I do this. I posted an old function, perhaps you looked at that? I updated it quickly after I posted. I loop over the function, and get the match count, then multiply it by the equivalent of THE-A length, then allocate it all at once.

Anyways, here's what I have now:
Code
char* replace(char* input, char* rf, char* rt) {
    size_t isl = strlen(input);
    size_t rfsl = strlen(rf);
    size_t rtsl = strlen(rt);
    size_t ml = 0;
    size_t mc = 0;
    int i = 0;
    for (; i < isl; i++) {
        bool im = input[i] == rf[ml];
        if (im) {
            ml++;
            if (ml == rfsl) {
                mc++;
                ml = 0;
                continue;
            }
        } else if (ml > 0) {
            ml = 0;
        }
    }
    i = 0;
    ml = 0;
    char* output = malloc(isl - ((rfsl - rtsl) * mc));
    output[0] = '\0';
    int mi = 0;
    for (; i < isl; i++) {
        bool im = input[i] == rf[ml];
        if (im) {
            ml++;
            if (ml == rfsl) {
                size_t os = mi - ml + 1;
                strcpy(output + os, rt);
                mi += ml - rtsl - 1;
                ml = 0;
                continue;
            }
        } else if (ml > 0) {
            ml = 0;
        }
        output[mi++] = input[i];
    }
    output[mi] = '\0';
    return output;
}


Possibly Related Threads...
Thread / Author Replies Views Last Post
[Java] by kinsellaAug 11, 2018 01:32 PM 3 325 Aug 11, 2018 01:32 PM
Last Post: XMR
[Java] by JavaProphetApr 21, 2015 07:38 PM 0 284 Apr 21, 2015 07:38 PM
Last Post: JavaProphet
[C] by Zy0nApr 10, 2015 12:55 PM 3 77 Apr 10, 2015 12:55 PM
Last Post: g4143