Domanda

I am using JNA to call methods of user32.dll and kernel32.dll. It is working fine as of now. I got stuck in some issue, and I got to know that I have to call this method.

void SendCommandToConsole( char* Cmd )
{
    DWORD dwCall = 0x004C1030;
    __asm
    {
        push Cmd;
        push 0;
        call dwCall;
    }
}

SendCommandToConsole ( "rp 2000" );

But I am not even getting it what it is? What this __asm is doing ?

Please add appropriate tags, if the tags I have used are not correct. :)

Edit Added .Net and C# tags as suggested. Above code is in either C# or .NET, may be someone with the knowledge of this language can tell us what actually it is, and how can we do this in java.

È stato utile?

Soluzione

Just to show what is happening under the hood:

Your call:

SendCommandToConsole ( "rp 2000" );

Is calling the function (SendCommandToConsole) with a parameter of type (char* Cmd).

In the case above, (char* Cmd) equates to the character string (sic) of "rp 2000".

Now what happens under the covers is that higher level languages (Java in your example) need to tell lower level languages how to interpret their instructions in a language that they understand.

So to take the example above of ("I want to call the function "SendCommandToConsole" with the string parameter of "rp 2000"), means that we need to communicate to the lower level language:

  • The "uppity-ups want us to run a command". "Oh yea, which one?"
  • "They're telling me 'SendCommandToConsole'"
  • "Oh, that dude? He lives at the address '0x004C1030' down here."
  • "Oh, you know the dude's address? Can you deliver this package that the uppity-ups want delivered?"
  • "Sure thing, but he only accepts packages in a certain order, and only of a certain type."
  • "No problem, I have their manifest right here... let's see if it matches the dude's requirements."

"First off, the dude at that address only wants to know 2 things, and they have to be in order:

  • What do you want me do do,
  • and who do I report the results to?"

"Ok, that's easy"

I'll assert what I want him to do:

  • "Cmd"
  • Now I'll assert who I want him to report the results to: "No one (0)"

All right, I'll ring him up... you can go on with your day now.

(Because it is a "void" return, which means you don't care about the result of the transaction)

Altri suggerimenti

This means that an assembly code block follows.

dwCall is the pointer to an assembly procedure that takes one argument -> a pointer to a zero terminated array of bytes on the stack. In order to call it properly, you must push the pointer on the stack and you can only do that via assembler.

In JNA, you can use Function.getFunction(Pointer) to obtain an object which you can use to control invocations on a particular address.

Function dwCall = Function.getFunction(new Pointer(0x12345678));
String CMD = "SomeCommand";
Integer ARG = new Integer(0);
dwCall.invoke(void.class, new Object[CMD, ARG]);

Assuming the function uses the C calling convention, the above code would work. Ultimately, you would probably want to dynamically look up the function address rather than hard-coding it, and you'd probably want to use a JNA Callback instead of invoking the Function object directly, but the above code provides the bare functionality you are asking for (you should rephrase your original question; you don't want to execute assembly code, you want to call a function at a given address).

Using a JNA Callback mapping will allow you to call the function more naturally.

// Use StdCallCallback if the function called uses stdcall rather than cdecl
public class MyCallback extends Callback {
    void invoke(String cmd, int arg);
}

Pointer addr = new Pointer(0x1235678);
MyCallback cb = (MyCallback)CallbackReference.getCallback(MyCallback.class, addr);
cb.invoke("SomeCommand", 0);

Note that both of these examples assume that you have already used JNA to load the DLL in question, usually via Native.loadLibrary().

Note also that the signature might actually be void dwCall(int arg, String cmd); cdecl and stdcall conventions push parameters on the stack from right to left, and my thinking isn't clear enough at the moment to map that through properly...

There is no Java equivalent, Java doesn't allow such low level control. You need to compile the C code as a DLL and use JNA/JNI to call it.

Edit 1: The above is only true for assembly code in general. See techomage's reply for calling a stdcall or cdecl function at an address using JNA.

The __asm block allows you to use assembly in a C source file. The assembly code calls the function at the address 0x004C1030 (whatever function that may be) passing the string by pointer and a zero as arguments.

Calling addresses directly is a bad idea. You probably won't get what you're expecting unless you know the low level internals of your program and your operating system really well. Calling it would most likely crash your program.

Why are you not just calling the SendCommandToConsole() function? What that function is doing is making a Windows System call and you should not be writing a function that does that, you should be calling a function that does that.

I guess the real question is what does "rp 2000" do? If it runs rp.exe with argument 2000 then you can use java.lang.Runtime to do the same thing. If we knew what it did, there might be something in java to do it.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top