Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add win32 DLL ordinal value function support #689

Closed
wants to merge 4 commits into from

Conversation

kobevaliant
Copy link

@kobevaliant kobevaliant commented Aug 12, 2016

add win32 DLL ordinal value function support
if funname is like '#123', a ordinal value will be used instead of a string representation

add win32 DLL ordinal value function support
@kobevaliant kobevaliant changed the title Update dispatch.c add win32 DLL ordinal value function support Aug 12, 2016
@twall
Copy link
Contributor

twall commented Aug 12, 2016

Looks reasonable. Tests?

@@ -310,6 +310,7 @@ w32_short_name(JNIEnv* env, jstring str) {

static HANDLE
w32_find_entry(JNIEnv* env, HANDLE handle, const char* funname) {
if (funcname[0] == '#') funname = (const char *)atoi(funname + 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check for NULL, too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's already checked in function 'Java_com_sun_jna_Native_findSymbol'

Copy link
Member

@dblock dblock Aug 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until someone removes it or calls this from another scope. The repercussions of security vulnerabilities caused by this in case that happens are pretty major, it costs nothing at runtime and is basic defensive programming, just my 0.02c.

add some test code about win32 ordinal number function
@matthiasblaesing
Copy link
Member

Is it safe to assume, that no ordinary function name begins with the #-mark? If (even just in theory) a function name could clash with this - I see the need for either an escape mechanism or a different implementation.

@dblock
Copy link
Member

dblock commented Aug 15, 2016

Is there a way to write this to avoid any ambiguity? Like @FuncNumber(1206)?

@matthiasblaesing
Copy link
Member

I think this could be handled completly without touching the dispatching mechanism, purely on the java side:

First I modified Kernel32.java to include the only necessary new function:

Pointer GetProcAddress(HMODULE hmodule, int ordinal);

This way I'll get access to the pointer leading me to the function itself. That used in the sample:

public class InvokeByOrdinal {
    static NativeLibrary user32;

    public static void main(String[] args) {
        // ensure user32 is loaded and hold it static
        user32 = NativeLibrary.getInstance("user32");
        // get module handle needed to resolve function pointer via GetProcAddress
        HMODULE module = Kernel32.INSTANCE.GetModuleHandle("user32");
        // resolve function pointer
        //
        // From link.exe /dump /exports c:\\Windows\\System32\\user32.dll:
        //    ordinal hint RVA      name
        //       1822  13A 00039220 GetDesktopID
        //       1823  13B 000176B0 GetDesktopWindow
        //       1824  13C 0002E710 GetDialogBaseUnits
        Pointer funcPointerGetDesktopWindow = Kernel32.INSTANCE.GetProcAddress(module, 1823);
        // Wrap Pointer into Function
        Function funcGetDesktopWindow = Function.getFunction(funcPointerGetDesktopWindow);
        // Invoke GetDesktopWindow via manually resolved ordinal lookup and output pointer value
        Pointer hwndPointer = funcGetDesktopWindow.invokePointer(new Object[]{});
        System.out.println(Pointer.nativeValue(hwndPointer));
        // Invoke GetDesktopWindow via JNA bindings
        HWND hwnd = User32.INSTANCE.GetDesktopWindow();
        System.out.println(Pointer.nativeValue(hwnd.getPointer()));
    }
}

leads to the same outputs. I also tried ShowCursor, but learned, that that does not effect the global cursor visiblity and without a window the effect is underwhelming.

This could be used for an InvocationHandler, that resolves the function pointers on first call/greedy and dispatches them through the bound functions.

@kobevaliant
Copy link
Author

I think it is elegant and consistent with my intuition by using '#', and it is implemented easily (A single line of code).
There's same usage in .NET, so I think it is somehow safe about ambiguity.
https://msdn.microsoft.com/en-us/library/f5xe74x8(v=vs.110).aspx

Surely I expect more elegant way using @Anotation, while it needs more code and change.

@matthiasblaesing
Copy link
Member

@kobevaliant please have a look at this different approach:

matthiasblaesing@5f1c191

While the naming is discussable, I think this is safer - there are no side effects for other architectures and no it is still reasonablely short.

What I'd like to know: Is there a real life sample, that demonstrates the need for this?

@kobevaliant
Copy link
Author

Nice job, It meets my need enough.
Sometimes the dll owner don't want to expose the minimal information about the dll functions, so they choose to hide their function names entirely for privacy.

@matthiasblaesing
Copy link
Member

@kobevaliant please have a look at this PR: #705 that PR implements the necessary functions for the OrdinalValueInvoker. These are general enhancements. For your concrete problem feel free to implementation from https://github.com/matthiasblaesing/jna/tree/ordinalvalue_invoker (I added a license statement as MIT, so feel free to integrate).

If someone makes a case why this is of general interest, I'll reevaluate pulling this into JNA itself.

If you agree, I'll merge #705 and close this request.

@matthiasblaesing
Copy link
Member

Ok - I cleaning up. Feel free to contact me if you need help with the OrdinalValueInvoker.

mstyura pushed a commit to mstyura/jna that referenced this pull request Sep 9, 2024
Motivation:

We should hide the annotation so someone will not import it by mistake

Modifications:

Move annotation to same package as the rest of the code and mark it as
package-private

Result:

Don't expose implementation details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants