Windows x86 ASM: How to call DLL functions?
Hello! I've been studying stack based overflows in Linux and Windows and I've come to notice calling different functions (such as system) in windows requires an imported DLL.
My main question is in ASM, assuming I have EIP control and have it point to my shell code, is how would I make a call to the function 'system' that would execute 'cmd.exe' and give a shell. But that is very specific, I would also like to know generally how to call any function from any DLL.
Thanks a lot for any answers!
for use function into DLL, use Rundll32 and use this tools
you want write custom Shellcode(I use Msfvenum or other tools for generate Shellcode )manually check this link.
You'll need to compile with MASM probably so it'll link win32 DLLs automatically. Or at least kernel32.dll. As long as that's linked, you're set.

Usually in C or C++, you use LoadLibraryA() with the string for the DLL (which should be found in $PATH or in the same directory as the binary, else you need full path.) Then, you make your function call by declaring the function pointer/struct, setting it to the address of the function retrieved by GetModuleHandle()/GetProcAddress().

You do the same thing in ASM tbh. Although it'll require a little more grunt work on your end.

On Windows systems, the modules/DLLs will always be loaded in the same order, starting at the same memory address (and because of the same order, they retain the same offsets between each other.)

Your job is to find those offsets (hint: printf("%p", GetProcAddress()) or open a win32 application in your favourite debugger) and then find the offsets of the functions when they are loaded into memory. Two ways to do the latter, either open it in a debugger and look at the exports, or use a nifty tool called CFFExplorer.

From there, you do your pointer arithmetic for the function you want to call:
(base address of loaded win32 modules) +
(offset to desired module w/ function) +
(offset from base of module to function)

Move that value into rax or whatever, then call rax.

Now, you'll need to do a lot of debugging to find the 'assembly' documentation of how to call a win32 function. So write your code in C first just to test, but for the most part, most win32 functions use the stack to hold arguments, not other registers (i.e. Linux write() uses rdx, rax, rdi, rsi, win32 applications will involve a lot of push instructions before call).

You don't need to do everything with pure assembly, though. Here's an example of me hybriding it:

And here's a way to get offsets of all DLLs loaded into the address space (in C)
This sounds too late since the post is almost a year behind though I would still like to add this for new users or users with the same interest who would like to execute payload via RunDLL32.exe.

Check the source out. I hope it helps for others finding answers.

Possibly Related Threads…
Thread Author Replies Views Last Post
  ASM Learning Resources Insider 2 15,818 07-14-2021, 10:11 PM
Last Post: Insider
  Windows Source-Code Collection (1.3TB) Insider 2 19,574 08-09-2020, 09:59 PM
Last Post: Insider
  ASM question - Push and Pop functions Ahmed 2 16,493 12-08-2017, 03:25 AM
Last Post: Ahmed
  Starting out with Common Lisp to "learn how to think" programmatically before C/ASM? hworth 3 17,143 05-23-2016, 02:44 AM
Last Post: Starfall