0

I have some questions about dynamic and static libraries. I know that a dll is a dynamic library whose image is loaded into memory and all processes can call functions and use them. And .lib is just an archive of object files, is this really the case?

My Russian MASM64 package (link) uses .lib libraries which I include in my .asm file, the same name as the system dll. But these .lib files are not an archive of object files, they tell the program which functions from the dll I can call and the address to them? I can use dumpbin to dump exports from kernel32.dll, which is in my system32 and create a .def file for the list of exported functions, then create a lib file with the lib utility.

Also a question about .inc files, I know they are just analog of .h from C/C++ projects, then what is the difference between these entries:

includelib "user32.lib"
extern __imp_ActivateKeyboardLayout:qword 
ActivateKeyboardLayout TEXTEQU <__imp_ActivateKeyboardLayout> 

is written in the .inc files in my package. And if I write it myself in my program:

includelib "user32.lib"
ActivateKeyboardLayout PROTO

and everything will also work, what's the difference. Can I use dumpbin to create .lib files for each .dll as I described above and write PROTO in the .inc files for all functions?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
mantissa
  • 132
  • 7
  • 1
    includelib is a directive supported by MASM, it embeds an instruction to the linker. In this case it will link user32.lib without you explicitly having to specify it. User32.lib is the import library for the operating system's user32.dll, it ensures that ActivateKeyboardLayout is defined. It has *two* exports for the function, the one with the imp prefix is actually a pointer to the function. Makes it more efficient at runtime. More about it [here](https://stackoverflow.com/a/4490536/17034) – Hans Passant Mar 23 '23 at 14:12

1 Answers1

0

Tnank you Hans Passant for the hint. In giving example ActivateKeyboardLayout replase with MessageBoxA and ExitProcess.

ExitProcess PROTO

It turns out that when we declare a function using the PROTO directive, the compiler doesn't know where it is, so when you compile in the debugger you can see the following:

enter image description here

For the function ExitProcess, creates a so-called Thunk, the essence of which is to call a function consisting of only one jmp, which jumps to the function that we need. I assume that this is done because, during the build, the linker realized that the ExitProcess function is actually imported, so it jumped to a pointer in the import table of the source file.

extern __imp_MessageBoxA:qword

In the case of the MessageBoxA function, however, we tell the compiler that it is a third-party (imported) function by specifying the extern keyword and the imp prefix for the MessageBoxA function. The debugger shows that calling the __imp_MessageBoxA function leads to calling MessageBoxA directly, since __imp_MessageBoxA is nothing but a pointer to MessageBoxA in the import table.

upload_2023-3-24_13-20-6.png

In general, the only difference is in code optimization, because it works both ways, but in the second case the processor executes one less instruction.

mantissa
  • 132
  • 7