Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Mattiwatti committed Jun 3, 2017
0 parents commit d988ee6
Show file tree
Hide file tree
Showing 11 changed files with 6,729 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Directories
bin/
obj/
ipch/
Win32/
x86/
x64/
Debug/
Release/
.svn/
.hg/
.vs/

# File types
*.dll
*.exe
*.sys
*.lib
*.exp
*.pdb
*.aps
*.sdf
*.user
*.obj
*.opensdf
*.suo
*.VC.db
*.VC.opendb
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Overview
Dumplib is a helper tool to create import libraries (.lib files) with correct `extern "C"` name decorations for **x86** PE files compiled by MSVC. (This means not x64 because x64 files do not have decorated export names; for x64, see Remarks below.) Its main use is to allow creating import libraries for DLLs for which no import library is available, and to customize existing import libraries, e.g. to remove unwanted exports that cause linker collisions.

Dumplib mostly just applies a bunch of regexes and hacks. Most of the actual work is done by `dumpbin.exe` which generates the export listing dumplib parses. Executing dumplib generates three files:
- A **.cpp** file containing dummy function definitions;
- A **.def** file containing the names and ordinals of functions to be exported;
- A **.bat** file to invoke the compiler and linker to produce a (useless) DLL file and the import library for it, which will be compatible with the original DLL and can be linked against.

# Usage
1. Create an export listing of the target file using the **x86** version of `dumpbin`. To do so, open a 'VS2017 **x86** Native Tools Command Prompt' (or similar depending on your version). Note the part that says **x86**, this is important because each tool invoked from this prompt will generate a different (wrong) output in x64 mode. Assuming you want to create an import library for `ucrtbase.dll`, execute `dumpbin /EXPORTS ucrtbase.dll > ucrtbase-exports.txt`.
2. Execute `dumplib ucrtbase-exports.txt ucrtbase.dll`. The second argument supplies the name of the executable to be generated, which will usually be the same as the original, but can be changed if desired.
3. Depending on the size and complexity of your file, you may see a number of warnings scroll by. If you missed the part that said to open an **x86** prompt, this number will be large. Otherwise, take note of what, if anything, was not parsed correctly so you can make manual fixups later if needed.
4. The aforementioned three files (.cpp, .def, .bat) should now be present in the directory. You can edit these to remove any declarations you don't want. Removing the declaration from the .def file is sufficient for this.
5. Once you are done, open the .bat file in notepad to modify the first path to point to the same batch file you used to open the VS command prompt. The other filenames and paths should already be correct.
6. Run the .bat file.
7. There should now be an `output` directory (to prevent accidental overwriting of the input files) containing your import library and DLL.

# Remarks
- Dumplib does not and will not ever parse C++ exports. It is intended for Windows system files, which tend to use `extern "C"` exports. `Dumpbin` on the other hand **does** undecorate C++ function names, so if your DLL has a small number of C++ functions it is still possible to do this with some added manual copy and paste work (this is why dumpbin generates .cpp files, not .c). I am not interested in adding support for this however.
- The 'x64 version' of dumplib is significantly more ghetto and fits in this README, because `extern "C"` declarations are not decorated by MSVC on x64. The following batch file will suffice in most cases:
```Batch
@echo off
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
dumpbin /EXPORTS "%1" > %2-exports.txt
echo LIBRARY %2 > %2-exports.def
echo EXPORTS >> %2-exports.def
for /f "skip=19 tokens=4" %%a in (%2-exports.txt) do (
if "%%a" NEQ "" echo %%a>> %2-exports.def
)
lib /nologo /DEF:%2-exports.def /OUT:%2.lib /MACHINE:X64
del %2.exp 1>nul
pause
```
Example usage: `dumplib.bat C:\Windows\System32\ntdll.dll ntdll.dll`. It should hopefully be clear that the first path should in fact point to the **x64** version of your VS vars batch file this time.

One limitation of this method compared to dumplib is that it does not understand forward exports. I may add some minimal amount of x64 support in the future to correct this.
27 changes: 27 additions & 0 deletions dumplib.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dumplib", "src\dumplib.vcxproj", "{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}.Debug|Win32.ActiveCfg = Debug|Win32
{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}.Debug|Win32.Build.0 = Debug|Win32
{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}.Debug|x64.ActiveCfg = Debug|x64
{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}.Debug|x64.Build.0 = Debug|x64
{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}.Release|Win32.ActiveCfg = Release|Win32
{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}.Release|Win32.Build.0 = Release|Win32
{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}.Release|x64.ActiveCfg = Release|x64
{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
29 changes: 29 additions & 0 deletions src/dumplib.exe.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
name="dumplib"
type="win32"
version="1.0.0.0"
processorArchitecture="*"
/>
<description>Import library generator for x86</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 7 / Server 2008 R2 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 / Server 2012 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 / Server 2012 R2 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 / Server 2016 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>
229 changes: 229 additions & 0 deletions src/dumplib.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1AB1CEE9-8C5D-4923-BF2F-661A01894EF1}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>NtCreateUserProcess</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<CharacterSet />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<CharacterSet />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet />
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>obj\$(Platform)-$(Configuration)\</IntDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>obj\$(Platform)-$(Configuration)\</IntDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>obj\$(Platform)-$(Configuration)\</IntDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>obj\$(Platform)-$(Configuration)\</IntDir>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;NTDDI_VERSION=0x05010000;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<StringPooling>true</StringPooling>
<MinimalRebuild>false</MinimalRebuild>
<ControlFlowGuard>false</ControlFlowGuard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/permissive- /Gw %(AdditionalOptions)</AdditionalOptions>
<DiagnosticsFormat>Caret</DiagnosticsFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProfileGuidedDatabase />
<SetChecksum>true</SetChecksum>
<Version>5.01</Version>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WINVER=0x0502;_WIN32_WINNT=0x0502;NTDDI_VERSION=0x05020000;_WIN64;_AMD64_;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<StringPooling>true</StringPooling>
<MinimalRebuild>false</MinimalRebuild>
<ControlFlowGuard>false</ControlFlowGuard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/permissive- /Gw %(AdditionalOptions)</AdditionalOptions>
<DiagnosticsFormat>Caret</DiagnosticsFormat>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProfileGuidedDatabase />
<SetChecksum>true</SetChecksum>
<Version>5.02</Version>
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;NTDDI_VERSION=0x05010000;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/permissive- /Gw %(AdditionalOptions)</AdditionalOptions>
<DiagnosticsFormat>Caret</DiagnosticsFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<ProfileGuidedDatabase />
<EntryPointSymbol>
</EntryPointSymbol>
<SetChecksum>true</SetChecksum>
<Version>5.01</Version>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
<MergeSections>.rdata=.text</MergeSections>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WINVER=0x0502;_WIN32_WINNT=0x0502;NTDDI_VERSION=0x05020000;_WIN64;_AMD64_;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
<OmitFramePointers>true</OmitFramePointers>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/permissive- /Gw %(AdditionalOptions)</AdditionalOptions>
<DiagnosticsFormat>Caret</DiagnosticsFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<ProfileGuidedDatabase />
<EntryPointSymbol>
</EntryPointSymbol>
<SetChecksum>true</SetChecksum>
<Version>5.02</Version>
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
<MergeSections>.rdata=.text</MergeSections>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc" />
</ItemGroup>
<ItemGroup>
<Manifest Include="dumplib.exe.manifest" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
28 changes: 28 additions & 0 deletions src/dumplib.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{93BA8950-095D-4405-ADC6-8B3AEFCE752C}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{0963FE89-D375-413D-A0DB-F8B58AFB7ED6}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Manifest Include="dumplib.exe.manifest">
<Filter>Resource Files</Filter>
</Manifest>
</ItemGroup>
</Project>
Loading

0 comments on commit d988ee6

Please sign in to comment.