Is it possible that a module will have a call to a function in a different module?

I know about import tables and delayed import tables. But are there any more options to do so? How will it look in the binary? (Probably the opcode in this case will be indirect, but where will reside the address to jump to?)

Is it the same about jumps?

I know it's a bit of a general question, so a link to some relevant readings will be great also.


  • If the memory page is marked executable, what prevents you from calling an address in that page?
    – Viktor
    Mar 27 '16 at 21:35
  • Nothing of course. But from what I know, if you call some address, it has to appear somewhere in memory (the address itself). How the pre-compiled code can know where to jump to, when the base address of the (other) module to jump to isn't known in compile time (and, as stated, not in the import list) Mar 27 '16 at 21:41
  • something like ulong magic offset = 0x12345678; base = GetmoduleHandle("someMod"); mov reg,base+offset ; call reg
    – blabb
    Mar 28 '16 at 10:46
  • Will the runtime import table construction count for you? You can prepare your own import table, because you know what apis you want to call. During runtime your own resolver/IAT builder will add the needed inter-module addresses.
    – PhoeniX
    Mar 28 '16 at 22:32

The good news: Yes, of course it is possible, and done very very often. I will restrict my answer to Windows. In Linux or other systems exist similar scenarios, however different in detail.

First let's clarify what a "module" might be. I assume from your question that you mean by "module" a DLL e.g. loaded and called by some exe binary. This is a "tightly coupled" scenario: The module to be called resides in the same 2GB memory virtual address space as the calling module. In case of a "loosely coupled" scenario where both modules reside in different processes, you need one of the possibilities of "Remote Procedure Calls", like XML-RPC, SOAP or - in a .NET environment - Remoting. There exist many others. The following applies to a Windows DLL in tightly coupling.

Case1: Function is exported by the module. This is straightforward:

  1. Call the "LoadLibrary" API in one of its flavors to get the address of the module (Note that the handle returned is directly the module address). For this to work, you need the filename of the module.
  2. Call "GetProcAddress" to get the address of the function within the module. You need the name or the ordinal number of the exported function.
  3. Construct a function pointer with the correct signature from the obtained address.
  4. Call the function

This is the scenario for "normal" programs. It has the advantage that you do not need a static library to link the addresses of the DLL, and that the DLL needs not be present at startup of the exe. It has the disadvantage that the generation of the correct function pointer is a bit tedious.

Case2: Function is NOT exported by the module, base address of module to be called is not known.

This is the more interesting case where you e.g. want to patch an exe file and call the function of interest in the module DLL, or just want to jump to some known address relative to the modules starting address.

It works in principle - on an assembler and machine code level - in exactly the same way as described above, with one little difficulty: How do you call in your patch the "LoadLibrary" function? This is not so trivial as it might seem at first glance.

The "LoadLibrary" function resides in the module "Kernel32.dll", necessary for every windows program. You might call "LoadLibraryA("Kernel32.dll"), and you see the recursion problem of the "cat biting into its tail". This doesn't work. And don't rely on kernel32.dll having a fixed and not changing address. This will NOT work in the world of ASLR.

This is a general problem of all shellcode programming. Fortunately, there is a method how to reliably obtain the address of Kernel32.dll (and also ntdll.dll). You might want to download the excellent and rather old paper of Skape describing this and many other interesting things from here http://www.hick.org/code/skape/papers/win32-shellcode.pdf. The method worked for me identically in Windows XP, Windows7 and Windows10. Skapes approach works in the 32-bit world. For a corrsponding solution in 64 bit Windows, you might want to consult https://www.tophertimzen.com/blog/windowsx64Shellcode/ (but beware of possible bugs in the solution).

Have fun!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.