visual-c++x86dllimportkernel32import-libraries

How to create an import library for kernel32.dll using a .def file on x86?


I have a small project that does not depend on the CRT or windows sdk. In order to link against kernel32.dll I created a minimal .def file with only the couple functions I need:

LIBRARY kernel32.dll
EXPORTS
ExitProcess

I then create the .lib during the build with this command: lib /DEF:kernel32.def /OUT:kernel32.lib /MACHINE:x86.

The declaration of the function in my code looks like this:

#ifdef __cplusplus
extern "C"{
#endif
__declspec(dllimport) __declspec(noreturn) void __stdcall ExitProcess(UINT uExitCode);
#ifdef __cplusplus
}
#endif

This works perfectly fine when compiling and linking for x64 (with a a lib created with /MACHINE:x64) but when I switch over to x86 I get an unresolved symbol error for __imp__ExitProcess@4.

This linker error is resolved by changing the name of the export in the def file to ExitProcesss@4 but when running the program, an error appears saying The procedure entry point 'ExitProcess@4' was not found in MyProgram.exe.

Everything works fine if I link against the kernel32.lib from the windows sdk. So the issue must be somewhere between creating the def file and creating an import library.

The only reference I could find was a .def file from mingw which looks exactly like mine: https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/lib32/kernel32.def Although since this file is probably consumed by mingw tools it might have a different output than the lib tool from msvc.


Solution

  • have only def file is not enouth in case x86 here.

    if will be name ExitProcess in def - will be exactly __imp_ExitProcess in lib too. but client wait for __imp__ExitProcess@4. so you fail at build time.

    if you set ExitProcess@4 your PE will be import _ExitProcess@4 from kernel32.dll and fail at runtime

    solution here use c/cpp/asm file in conjunction with def

    minimal solution: first use such kernel32.asm

    .686
    .model flat
    
    .code
    
    _ExitProcess@4 proc
    _ExitProcess@4 endp
    
    end
    

    and compile it as ml /c /Cp kernel32.asm

    def is simply

    EXPORTS
    ExitProcess
    

    and finally use next command

    link /DLL /NOENTRY /MACHINE:x86 /def:kernel32.def kernel32.obj 
    

    after this you got correct kernel32.lib ( kernel32.dll and kernel32.exp simple for delete)