├── LibGen ├── LibGen.def ├── VerInfo.rc ├── LibFactory.h ├── HowTo.txt ├── LibInterfaces.h ├── LibGen.vcxproj.filters ├── testmain.cpp ├── LibGen.vcxproj └── LibImpl.cpp ├── VerInfo.rc ├── CoffGen ├── VerInfo.rc ├── CoffGen.def ├── CoffGen.vcxproj.user ├── cofffactory.h ├── HowTo.txt ├── CoffGen.vcxproj.filters ├── testmain.cpp ├── coffInterfaces.h ├── CoffGen.vcxproj └── coffImpl.cpp ├── ImpGen ├── VerInfo.rc ├── resource.h ├── ImpGen.def ├── ImpFactory.h ├── HowTo.txt ├── ImpGen.vcxproj.filters ├── ImpInterfaces.h ├── testmain.cpp ├── ImpGen.vcxproj └── impImpl.cpp ├── MakeImpLib ├── VerInfo.rc ├── MakeImpLib.vcxproj.filters ├── MakeImpLib.vcxproj └── main.cpp ├── ImpLibFix ├── ImpLibFix.def ├── ImpLibFix.vcxproj.user ├── ImpLibFix.h ├── testmain.cpp ├── ImpLibFix.vcxproj.filters ├── ImpLibFix.cpp └── ImpLibFix.vcxproj ├── LibGenHelper ├── VerInfo.rc ├── LibGenHelper.def ├── LibGenHelperFactory.h ├── LibGenHelperInterfaces.h ├── HowTo.txt ├── LibGenHelper.vcxproj.filters ├── LibGenHelperImpl.cpp └── LibGenHelper.vcxproj ├── LICENSE ├── README └── implib.sln /LibGen/LibGen.def: -------------------------------------------------------------------------------- 1 | LIBRARY LibGen 2 | EXPORTS 3 | CreateLibraryBuilder 4 | -------------------------------------------------------------------------------- /VerInfo.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sorayuki/implibGenerator/HEAD/VerInfo.rc -------------------------------------------------------------------------------- /CoffGen/VerInfo.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sorayuki/implibGenerator/HEAD/CoffGen/VerInfo.rc -------------------------------------------------------------------------------- /ImpGen/VerInfo.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sorayuki/implibGenerator/HEAD/ImpGen/VerInfo.rc -------------------------------------------------------------------------------- /ImpGen/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sorayuki/implibGenerator/HEAD/ImpGen/resource.h -------------------------------------------------------------------------------- /LibGen/VerInfo.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sorayuki/implibGenerator/HEAD/LibGen/VerInfo.rc -------------------------------------------------------------------------------- /MakeImpLib/VerInfo.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sorayuki/implibGenerator/HEAD/MakeImpLib/VerInfo.rc -------------------------------------------------------------------------------- /ImpLibFix/ImpLibFix.def: -------------------------------------------------------------------------------- 1 | LIBRARY ImpLibFix 2 | EXPORTS 3 | GetMaxNameLength 4 | RenameImpLibObjects 5 | -------------------------------------------------------------------------------- /LibGenHelper/VerInfo.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sorayuki/implibGenerator/HEAD/LibGenHelper/VerInfo.rc -------------------------------------------------------------------------------- /ImpGen/ImpGen.def: -------------------------------------------------------------------------------- 1 | LIBRARY ImpGen 2 | EXPORTS 3 | GetX86ImpSectionBuilder 4 | GetX64ImpSectionBuilder 5 | -------------------------------------------------------------------------------- /LibGenHelper/LibGenHelper.def: -------------------------------------------------------------------------------- 1 | LIBRARY LibGenHelper 2 | EXPORTS 3 | CreateX86ImpLibBuilder 4 | CreateX64ImpLibBuilder 5 | -------------------------------------------------------------------------------- /CoffGen/CoffGen.def: -------------------------------------------------------------------------------- 1 | LIBRARY CoffGen 2 | EXPORTS 3 | GetX86CoffFactory 4 | GetX64CoffFactory 5 | GetIA64CoffFactory 6 | -------------------------------------------------------------------------------- /CoffGen/CoffGen.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /LibGen/LibFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBFACTORY_H 2 | #define LIBFACTORY_H 3 | 4 | #include "LibInterfaces.h" 5 | 6 | namespace Sora 7 | { 8 | extern "C" ILibraryBuilder* WINAPI CreateLibraryBuilder(); 9 | }; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /ImpGen/ImpFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPFACTORY_H 2 | #define IMPFACTORY_H 3 | 4 | #include "ImpInterfaces.h" 5 | 6 | namespace Sora { 7 | extern "C" { 8 | IImpSectionBuilder* WINAPI GetX86ImpSectionBuilder(); 9 | IImpSectionBuilder* WINAPI GetX64ImpSectionBuilder(); 10 | } 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /CoffGen/cofffactory.h: -------------------------------------------------------------------------------- 1 | #ifndef COFFFACTORIES_H 2 | #define COFFFACTORIES_H 3 | 4 | #include "coffInterfaces.h" 5 | 6 | namespace Sora { 7 | extern "C" { 8 | ICoffFactory* WINAPI GetX86CoffFactory(); 9 | ICoffFactory* WINAPI GetX64CoffFactory(); 10 | ICoffFactory* WINAPI GetIA64CoffFactory(); 11 | } 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /ImpLibFix/ImpLibFix.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(OutputPath) 5 | WindowsLocalDebugger 6 | 7 | -------------------------------------------------------------------------------- /LibGenHelper/LibGenHelperFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBGENHELPERFACTORY_H 2 | #define LIBGENHELPERFACTORY_H 3 | 4 | #include "LibGenHelperInterfaces.h" 5 | 6 | namespace Sora 7 | { 8 | extern "C" IImportLibraryBuilder* WINAPI CreateX86ImpLibBuilder(LPCSTR szDllName, LPCSTR szMemberName); 9 | extern "C" IImportLibraryBuilder* WINAPI CreateX64ImpLibBuilder(LPCSTR szDllName, LPCSTR szMemberName); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /ImpLibFix/ImpLibFix.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPLIBFIX_H 2 | #define IMPLIBFIX_H 3 | 4 | #include 5 | 6 | namespace Sora { 7 | //not include the \0 8 | extern "C" int WINAPI GetMaxNameLength(); 9 | 10 | //return: how many members renamed. 11 | //first link member and second link member and longname member won't be renamed 12 | extern "C" int WINAPI RenameImpLibObjects(LPCSTR szNewName, PBYTE pData, int nDataLen); 13 | }; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ImpLibFix/testmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ImpLibFix.h" 3 | 4 | int main() 5 | { 6 | FILE* f = fopen("ims.lib", "rb+"); 7 | fseek(f, 0, SEEK_END); 8 | int fs = ftell(f); 9 | fseek(f, 0, SEEK_SET); 10 | 11 | PBYTE buf = new BYTE[fs]; 12 | fread(buf, 1, fs, f); 13 | 14 | Sora::RenameImpLibObjects("member/", buf, fs); 15 | 16 | fseek(f, 0, SEEK_SET); 17 | fwrite(buf, 1, fs, f); 18 | 19 | fclose(f); 20 | 21 | delete[] buf; 22 | } 23 | -------------------------------------------------------------------------------- /ImpGen/HowTo.txt: -------------------------------------------------------------------------------- 1 | This module is used for build sections for import data from DLL. 2 | 3 | How to use: 4 | 1. Create CoffBuilder object by using the CoffGen module 5 | 2. Call methods of ImpSectionBuilder to add section(s) to CoffBuilder 6 | 3. Call PushRelocs of CoffBuilder object 7 | 4. Get data from CoffBuilder object 8 | 9 | I think the method name is self-explaining. 10 | 11 | Recommend usage: 12 | Put ImportDescriptor, ImportThunk, NullDescriptor, NullThunk in different coff object files, 13 | or I don't know if it works. 14 | -------------------------------------------------------------------------------- /LibGen/HowTo.txt: -------------------------------------------------------------------------------- 1 | This module is used for creating Object Archive (library, .lib) file. 2 | 3 | How to use: 4 | 1. Create CoffBuilder object by using CoffGen module, and add section to it 5 | 2. Call PushRelocs of CoffBuilder object, like what you do before save this object file 6 | 3. Call AddObject method of LibraryBuilder object with member name. For import library, all member name is the same. 7 | 4. Call FillOffsets to calculate and fill all member's offset(file pointer) for first link member and second link member 8 | 5. Get raw data from LibraryBuilder object and save them into file. 9 | -------------------------------------------------------------------------------- /LibGen/LibInterfaces.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBINTERFACES_H 2 | #define LIBINTERFACES_H 3 | 4 | #include "coffInterfaces.h" 5 | 6 | namespace Sora 7 | { 8 | class ILibraryBuilder : public IDispose, public IHasRawData 9 | { 10 | public: 11 | //the name is limited to 14 bytes. No longname is supported. 12 | virtual void WINAPI AddObject(LPCSTR szName, ICoffBuilder*) = 0; 13 | 14 | //call this method to calculate the offset for first and second link member before retrive raw data 15 | virtual void WINAPI FillOffsets() = 0; 16 | }; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /LibGenHelper/LibGenHelperInterfaces.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBGENHELPERINTERFACES_H 2 | #define LIBGENHELPERINTERFACES_H 3 | 4 | #include "coffInterfaces.h" 5 | 6 | namespace Sora 7 | { 8 | class IImportLibraryBuilder : public IHasRawData, public IDispose 9 | { 10 | public: 11 | //szImpName: __imp__Sleep@8 12 | //szFuncName: _Sleep@8, can be null, will not generate stub 13 | //szImportName: Sleep 14 | virtual void WINAPI AddImportFunctionByName(LPCSTR szImpName, LPCSTR szFuncName, LPCSTR szImportName) = 0; 15 | virtual void WINAPI AddImportFunctionByOrdinal(LPCSTR szImpName, LPCSTR szFuncName, int nOrdinal) = 0; 16 | 17 | //call after add all import items 18 | virtual void WINAPI Build() = 0; 19 | 20 | //hint means ordinal 21 | virtual void WINAPI AddImportFunctionByNameWithHint(LPCSTR szImpName, LPCSTR szFuncName, LPCSTR szImportName, int nOrdinal) = 0; 22 | }; 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /CoffGen/HowTo.txt: -------------------------------------------------------------------------------- 1 | This module is used for build Coff Object File. 2 | 3 | How to build a coff file using this module: 4 | 5 | 1. Get the proper factory to create other objects. 6 | 2. Create a CoffBuilder object 7 | 3. Create SectionBuilder object 8 | 4. Add the SectionBuilder object to CoffBuilder 9 | 5. Set section name and characteristic, add data to the section 10 | 6. Add necessary symbols to symbol table of CoffBuilder 11 | 7. Call PushRelocs to generate necessary symbols from relocation table 12 | 8. Call methods of CoffBuilder object from IHasRawData to get the Coff Object File's raw data 13 | 9. Save the data to file, then you get a Coff Object File. 14 | 15 | Notice: 16 | 1. If you need aux symbols, create these symbols by CreateAuxSymbol method from SectionBuilder 17 | 2. Currently longname section is not supported 18 | 3. SymbolTable and StringTable is automately created during creating the CoffBuilder object, 19 | RelocationTable is automately created during creating the SectionBuilder object. 20 | -------------------------------------------------------------------------------- /MakeImpLib/MakeImpLib.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 23 | 24 | 资源文件 25 | 26 | 27 | -------------------------------------------------------------------------------- /LibGenHelper/HowTo.txt: -------------------------------------------------------------------------------- 1 | This module offsets simple interfaces to create import library. 2 | 3 | How to use: 4 | 1. Create a ImportLibraryBuilder object, specified the dll's filename and the member name in library (often the same as dll's name, but others is also accepted). 5 | 2. Add import functions. 6 | 3. Call Builde method. 7 | 4. Get raw data from the object and save them into file. 8 | 9 | Notice: 10 | szFuncName can be null (0), for that the function stub is not a must. 11 | 12 | What is function stub: 13 | 14 | When calling a function from DLL, there are two ways declare the function, 15 | take Sleep as example, 16 | 1. extern "C" void __stdcall Sleep(unsigned int); 17 | 2. extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned int); 18 | For 1, the linker will link it to _Sleep@8 symbol, which is a function; 19 | for 2, the linker will link it to __imp__Sleep@8 symbol, which is a function pointer. 20 | 21 | In x86 architecture, the first one will generate the code 22 | call _Sleep@8 23 | and the second one will generate the code 24 | call dword ptr [__imp__Sleep@8] 25 | Then what happened? the first one will jump to a function like this 26 | jmp dword ptr [__imp__Sleep@8] 27 | 28 | So they work as the same. 29 | But for 1, it's a must for _Sleep@8 existing. 30 | -------------------------------------------------------------------------------- /ImpLibFix/ImpLibFix.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 26 | 27 | 头文件 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, sorayuki 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of implibGenerator nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /LibGenHelper/LibGenHelper.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 26 | 27 | 源文件 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 资源文件 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ImpGen/ImpGen.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 26 | 27 | 源文件 28 | 29 | 30 | 源文件 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 资源文件 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /LibGen/LibGen.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 26 | 27 | 源文件 28 | 29 | 30 | 源文件 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 资源文件 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /CoffGen/CoffGen.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 源文件 6 | 7 | 8 | 源文件 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {df62f9c9-d624-47ec-81af-aa65e5bb8c2a} 17 | h;hh;hpp;hxx;hm;inl;inc;xsd 18 | 19 | 20 | {f91026dd-fe0b-4127-93c1-b9d585a41855} 21 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 22 | 23 | 24 | {10571c3b-10d8-4883-a5a8-4d7a8f8b5547} 25 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 26 | 27 | 28 | 29 | 30 | 头文件 31 | 32 | 33 | 头文件 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 资源文件 42 | 43 | 44 | -------------------------------------------------------------------------------- /ImpGen/ImpInterfaces.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPINTERFACES_H 2 | #define IMPINTERFACES_H 3 | 4 | #include "coffInterfaces.h" 5 | 6 | namespace Sora { 7 | class IImpSectionBuilder { 8 | public: 9 | virtual ICoffFactory* GetCoffFactory() = 0; 10 | 11 | //the pointer length. 4 for x86 and 8 for x64 12 | virtual int GetPtrSize() = 0; 13 | 14 | virtual void WINAPI BuildImportDescriptor(LPCSTR szDllName, ICoffBuilder*) = 0; 15 | 16 | //szImpName: __imp__xxx@nn, referred by linker 17 | //szDllExpName: the name that exported from dll 18 | //szFuncName: _xxx@nn, used if declared without __declspec(dllimport). will not generated if szStubName is NULL 19 | //include Thunk, OriginalThunk, importbyname 20 | virtual void WINAPI BuildImportByNameThunk(LPCSTR szDllName, LPCSTR szImpName, LPCSTR szFuncName, LPCSTR szDllExpName, ICoffBuilder*) = 0; 21 | virtual void WINAPI BuildImportByOrdinalThunk(LPCSTR szDllName, LPCSTR szImpName, LPCSTR szFuncName, WORD szDllExpOrdinal, ICoffBuilder*) = 0; 22 | 23 | virtual void WINAPI BuildNullThunk(LPCSTR szDllName, ICoffBuilder*) = 0; 24 | virtual void WINAPI BuildNullDescriptor(ICoffBuilder*) = 0; 25 | 26 | //import by name, but with [hint of import_by_name] = nDllExpOrdinal 27 | //when szDllExpName = NULL, it equals BuildImportByOrdinalThunk 28 | //when nDllExpOrdinal = 0, it equals BuildImportByNameThunk 29 | //don't let both = 0 (NULL) 30 | virtual void WINAPI BuildImportThunk(LPCSTR szDllName, LPCSTR szImpName, LPCSTR szFuncName, LPCSTR szDllExpName, WORD nDllExpOrdinal, ICoffBuilder* cb) = 0; 31 | }; 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /ImpGen/testmain.cpp: -------------------------------------------------------------------------------- 1 | #include "../CoffGen/coffInterfaces.h" 2 | #include "../CoffGen/cofffactory.h" 3 | #include "ImpInterfaces.h" 4 | #include "ImpFactory.h" 5 | 6 | using namespace Sora; 7 | 8 | bool SaveCoff(LPCTSTR fn, ICoffBuilder* cb) 9 | { 10 | cb->PushRelocs(); 11 | 12 | HANDLE hFile = CreateFile(fn, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); 13 | if (hFile != INVALID_HANDLE_VALUE) { 14 | int len = cb->GetDataLength(); 15 | BYTE* buf = new BYTE[len]; 16 | cb->GetRawData(buf); 17 | 18 | DWORD olen; 19 | WriteFile(hFile, buf, len, &olen, 0); 20 | CloseHandle(hFile); 21 | 22 | return olen == len; 23 | } 24 | return false; 25 | } 26 | 27 | int main() 28 | { 29 | IImpSectionBuilder* isf = GetX86ImpSectionBuilder(); 30 | ICoffFactory* cf = isf->GetCoffFactory(); 31 | 32 | LPCSTR dllname = "a.dll"; 33 | 34 | ICoffBuilder* desc = cf->CreateCoffBuilder(); 35 | isf->BuildImportDescriptor(dllname, desc); 36 | SaveCoff(TEXT("_impdesc.obj"), desc); 37 | desc->Dispose(); 38 | 39 | ICoffBuilder* NullThunk = cf->CreateCoffBuilder(); 40 | isf->BuildNullThunk(dllname, NullThunk); 41 | SaveCoff(TEXT("_NullThunk.obj"), NullThunk); 42 | NullThunk->Dispose(); 43 | 44 | ICoffBuilder* impadd = cf->CreateCoffBuilder(); 45 | isf->BuildImportByNameThunk(dllname, "__imp__add@8", "_add@8", "add", impadd); 46 | SaveCoff(TEXT("func1.obj"), impadd); 47 | impadd->Dispose(); 48 | 49 | ICoffBuilder* impsub = cf->CreateCoffBuilder(); 50 | isf->BuildImportByNameThunk(dllname, "__imp__sub@8", "_sub@8", "sub", impsub); 51 | SaveCoff(TEXT("func2.obj"), impsub); 52 | impsub->Dispose(); 53 | 54 | ICoffBuilder* nuldesc = cf->CreateCoffBuilder(); 55 | isf->BuildNullDescriptor(nuldesc); 56 | SaveCoff(TEXT("nuldesc.obj"), nuldesc); 57 | nuldesc->Dispose(); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This tool is inspired by implib sdk project( http://implib.sourceforge.net ). 2 | 3 | For "stdcall" convention exported from DLL file without decoration 4 | (prefix, suffix, like _ and @4, @8, etc) like Windows APIs, it seems to be 5 | not easy to get an import library by yourself. The LIB.exe tool from VC can 6 | construct .lib from .def but it doesn't allow importing without decoration 7 | and linking with decoration. 8 | 9 | For example, I want to use Sleep function from kernel32.dll. I would like to 10 | build an import library from a def file like this: 11 | 12 | LIBRARY kernel32.dll 13 | EXPORTS 14 | Sleep 15 | 16 | and create it by 17 | 18 | lib /def:k32.def /out:k32.lib 19 | 20 | but when linking, it will say 21 | error LNK2019: unresolved external symbol _Sleep@4 referenced 22 | ( use "cl test.c k32.lib /link /nodefaultlib" to have this test please. ) 23 | 24 | The linker looks for _Sleep@4 instead of Sleep. 25 | 26 | But if the .lib is build from this: 27 | 28 | LIBRARY kernel32.dll 29 | EXPORTS 30 | Sleep@4 31 | 32 | The build exe file won't run because there is no function named Sleep@4 33 | in kernel32.dll. 34 | 35 | So I need a .lib that imports Sleep from kernel32.dll and offers _Sleep@4 36 | for linking. 37 | 38 | ImpLib SDK project make use of fasm preprocess macros to construct a binary 39 | formed import library of DLL. It's very amazing. 40 | 41 | After some trying, I found it has some limitation, like long DLL file name is 42 | not supported, unicode function name is not supported, no x86-64 architecture 43 | supported, etc. 44 | 45 | But I have a lack of knowledge of fasm macro usage. To overcome these 46 | limitation, I decided to write my own. 47 | 48 | The structure of .obj file and .lib file is from Microsoft: 49 | http://download.microsoft.com/download/e/b/a/eba1050f-a31d-436b-9281-92cdfeae4b45/pecoff.doc 50 | 51 | No dependency library is required except standard c runtime and windows sdk. 52 | 53 | LeiMing (sorayuki) 54 | 2016-01-27 -------------------------------------------------------------------------------- /LibGen/testmain.cpp: -------------------------------------------------------------------------------- 1 | #include "LibInterfaces.h" 2 | #include "LibFactory.h" 3 | 4 | #include "../CoffGen/coffInterfaces.h" 5 | #include "../ImpGen/ImpInterfaces.h" 6 | #include "../ImpGen/ImpFactory.h" 7 | 8 | using namespace Sora; 9 | 10 | bool SaveRawData(LPCTSTR fn, IHasRawData* cb) 11 | { 12 | HANDLE hFile = CreateFile(fn, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); 13 | if (hFile != INVALID_HANDLE_VALUE) { 14 | int len = cb->GetDataLength(); 15 | BYTE* buf = new BYTE[len]; 16 | cb->GetRawData(buf); 17 | 18 | DWORD olen; 19 | WriteFile(hFile, buf, len, &olen, 0); 20 | CloseHandle(hFile); 21 | 22 | return olen == len; 23 | } 24 | return false; 25 | } 26 | 27 | int main() 28 | { 29 | IImpSectionBuilder* isf = GetX86ImpSectionBuilder(); 30 | ICoffFactory* cf = isf->GetCoffFactory(); 31 | 32 | LPCSTR dllname = "a.dll"; 33 | 34 | ICoffBuilder* desc = cf->CreateCoffBuilder(); 35 | isf->BuildImportDescriptor(dllname, desc); 36 | desc->PushRelocs(); 37 | 38 | ICoffBuilder* NullThunk = cf->CreateCoffBuilder(); 39 | isf->BuildNullThunk(dllname, NullThunk); 40 | NullThunk->PushRelocs(); 41 | 42 | ICoffBuilder* impadd = cf->CreateCoffBuilder(); 43 | isf->BuildImportByNameThunk(dllname, "__imp__add@8", "_add@8", "add", impadd); 44 | impadd->PushRelocs(); 45 | 46 | ICoffBuilder* impsub = cf->CreateCoffBuilder(); 47 | isf->BuildImportByNameThunk(dllname, "__imp__sub@8", "_sub@8", "sub", impsub); 48 | impsub->PushRelocs(); 49 | 50 | ICoffBuilder* nuldesc = cf->CreateCoffBuilder(); 51 | isf->BuildNullDescriptor(nuldesc); 52 | nuldesc->PushRelocs(); 53 | 54 | ILibraryBuilder* lib = CreateLibraryBuilder(); 55 | lib->AddObject("a.dll", desc); 56 | lib->AddObject("a.dll", nuldesc); 57 | lib->AddObject("a.dll", impadd); 58 | lib->AddObject("a.dll", impsub); 59 | lib->AddObject("a.dll", NullThunk); 60 | 61 | lib->FillOffsets(); 62 | 63 | SaveRawData(TEXT("as.lib"), lib); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /CoffGen/testmain.cpp: -------------------------------------------------------------------------------- 1 | #include "coffinterfaces.h" 2 | #include "cofffactory.h" 3 | #include 4 | #include 5 | using namespace Sora; 6 | 7 | #define OFFSET(stru, memb) ((DWORD)&((stru*)0)->memb) 8 | 9 | int main() 10 | { 11 | ICoffFactory* fac = GetX86CoffFactory(); 12 | ICoffBuilder* coff = fac->CreateCoffBuilder(); 13 | ISectionBuilder* id2 = fac->CreateSectionBuilder(); 14 | coff->AppendSection(id2); 15 | 16 | id2->SetName(".idata$2"); 17 | id2->SetCharacteristics(SECH_READ | SECH_WRITE | SECH_ALIGN4); 18 | 19 | IMAGE_IMPORT_DESCRIPTOR iid; 20 | ZeroMemory(&iid, sizeof(iid)); 21 | 22 | IRelocatableVar* relVar[3]; 23 | relVar[0] = fac->CreateRelocatableVar(); 24 | relVar[0]->Set("dllName", id2, OFFSET(IMAGE_IMPORT_DESCRIPTOR, Name), 0, RVARelocate); 25 | relVar[1] = fac->CreateRelocatableVar(); 26 | relVar[1]->Set("FirstThunk", id2, OFFSET(IMAGE_IMPORT_DESCRIPTOR, FirstThunk), 4, RVARelocate); 27 | relVar[2] = fac->CreateRelocatableVar(); 28 | relVar[2]->Set("OriginalFirstThunk", id2, OFFSET(IMAGE_IMPORT_DESCRIPTOR, OriginalFirstThunk), 4, RVARelocate); 29 | id2->AppendData((PBYTE)&iid, sizeof(iid), relVar, 3); 30 | 31 | ISectionBuilder* id5 = fac->CreateSectionBuilder(); 32 | id5->SetName(".idata$5"); 33 | id5->SetCharacteristics(SECH_READ | SECH_WRITE | SECH_ALIGN4); 34 | coff->AppendSection(id5); 35 | DWORD iatval = 0; 36 | coff->GetSymbolTableBuilder()->AddSymbol(id5, 0, "FirstThunk", SYST_STATIC, 0); 37 | relVar[0] = fac->CreateRelocatableVar(); 38 | relVar[0]->Set("LookUp_add", id5, 0, 0, RVARelocate); 39 | id5->AppendData((PBYTE)&iatval, sizeof(DWORD), relVar, 1); 40 | id5->AppendData((PBYTE)&iatval, sizeof(DWORD), 0, 0); 41 | coff->GetSymbolTableBuilder()->AddSymbol(id5, 0, "__imp__add@8", SYST_EXTERN, 0); 42 | 43 | ISectionBuilder* id4 = fac->CreateSectionBuilder(); 44 | id4->SetName(".idata$4"); 45 | id4->SetCharacteristics(SECH_READ | SECH_WRITE | SECH_ALIGN4); 46 | coff->AppendSection(id4); 47 | relVar[0] = fac->CreateRelocatableVar(); 48 | relVar[0]->Set("LookUp_add", id5, 0, 0, RVARelocate); 49 | id4->AppendData((PBYTE)&iatval, sizeof(DWORD), relVar, 1); 50 | id4->AppendData((PBYTE)&iatval, sizeof(DWORD), 0, 0); 51 | coff->GetSymbolTableBuilder()->AddSymbol(id4, 0, "OriginalFirstThunk", SYST_STATIC, 0); 52 | 53 | char dln[] = "a.dll"; 54 | ISectionBuilder* id6 = fac->CreateSectionBuilder(); 55 | id6->SetName(".idata$6"); 56 | id6->SetCharacteristics(SECH_READ | SECH_WRITE | SECH_ALIGN2); 57 | coff->AppendSection(id6); 58 | id6->AppendData((PBYTE)dln, sizeof(dln), 0, 0); 59 | coff->GetSymbolTableBuilder()->AddSymbol(id6, 0, "dllName", SYST_STATIC, 0); 60 | 61 | char fn[] = "add"; 62 | WORD hint = 0; 63 | ISectionBuilder* id7 = fac->CreateSectionBuilder(); 64 | id7->SetName(".idata"); 65 | id7->SetCharacteristics(SECH_READ | SECH_WRITE | SECH_ALIGN2); 66 | coff->AppendSection(id7); 67 | id7->AppendData((PBYTE)&hint, sizeof(hint), 0, 0); 68 | id7->AppendData((PBYTE)fn, sizeof(fn), 0, 0); 69 | coff->GetSymbolTableBuilder()->AddSymbol(id7, 0, "LookUp_add", SYST_STATIC, 0); 70 | 71 | coff->PushRelocs(); 72 | 73 | int l = coff->GetDataLength(); 74 | BYTE* p = new BYTE[l]; 75 | coff->GetRawData(p); 76 | 77 | coff->Dispose(); 78 | 79 | std::fstream f("im.obj", std::ios::binary | std::ios::out); 80 | f.write((char*)p, l); 81 | f.close(); 82 | 83 | delete[] p; 84 | } 85 | -------------------------------------------------------------------------------- /LibGenHelper/LibGenHelperImpl.cpp: -------------------------------------------------------------------------------- 1 | #include "LibGenHelperInterfaces.h" 2 | #include "LibGenHelperFactory.h" 3 | 4 | #include "LibInterfaces.h" 5 | #include "LibFactory.h" 6 | 7 | #include "ImpInterfaces.h" 8 | #include "ImpFactory.h" 9 | 10 | #include 11 | #include 12 | 13 | namespace Sora 14 | { 15 | struct ArchX86 {}; 16 | struct ArchX64 {}; 17 | 18 | template 19 | struct ArchTraits; 20 | 21 | template<> 22 | struct ArchTraits 23 | { 24 | static IImpSectionBuilder* GetImpSectionBuilder(); 25 | }; 26 | 27 | IImpSectionBuilder* ArchTraits::GetImpSectionBuilder() 28 | { 29 | return GetX86ImpSectionBuilder(); 30 | } 31 | 32 | template<> 33 | struct ArchTraits 34 | { 35 | static IImpSectionBuilder* GetImpSectionBuilder(); 36 | }; 37 | 38 | IImpSectionBuilder* ArchTraits::GetImpSectionBuilder() 39 | { 40 | return GetX64ImpSectionBuilder(); 41 | } 42 | 43 | template 44 | class CImportLibraryBuilder : public IImportLibraryBuilder 45 | { 46 | IImpSectionBuilder* m_secBuilder; 47 | ILibraryBuilder* m_libBuilder; 48 | std::string m_dllName; 49 | std::string m_memName; 50 | 51 | std::vector m_todispose; 52 | 53 | ICoffBuilder* CreateObject() 54 | { 55 | ICoffBuilder* r = m_secBuilder->GetCoffFactory()->CreateCoffBuilder(); 56 | m_todispose.push_back(r); 57 | return r; 58 | } 59 | public: 60 | CImportLibraryBuilder(LPCSTR szDllName, LPCSTR szMemName) 61 | { 62 | m_dllName = szDllName; 63 | m_memName = szMemName; 64 | m_libBuilder = CreateLibraryBuilder(); 65 | m_secBuilder = ArchTraits::GetImpSectionBuilder(); 66 | 67 | ICoffBuilder* impdesc = CreateObject(); 68 | m_secBuilder->BuildImportDescriptor(szDllName, impdesc); 69 | m_libBuilder->AddObject(szMemName, impdesc); 70 | 71 | ICoffBuilder* nuldesc = CreateObject(); 72 | m_secBuilder->BuildNullDescriptor(nuldesc); 73 | m_libBuilder->AddObject(szMemName, nuldesc); 74 | } 75 | 76 | void WINAPI Dispose() 77 | { 78 | std::vector::iterator i, iend; 79 | i = m_todispose.begin(); 80 | iend = m_todispose.end(); 81 | for(; i != iend; ++i) 82 | (*i)->Dispose(); 83 | delete this; 84 | } 85 | 86 | void WINAPI AddImportFunctionByName(LPCSTR szImpName, LPCSTR szFuncName, LPCSTR szDllExpName) 87 | { 88 | ICoffBuilder* impMember = CreateObject(); 89 | m_secBuilder->BuildImportByNameThunk(m_dllName.c_str(), szImpName, szFuncName, szDllExpName, impMember); 90 | m_libBuilder->AddObject(m_memName.c_str(), impMember); 91 | } 92 | 93 | void WINAPI AddImportFunctionByOrdinal(LPCSTR szImpName, LPCSTR szFuncName, int nOrdinal) 94 | { 95 | ICoffBuilder* impMember = CreateObject(); 96 | m_secBuilder->BuildImportByOrdinalThunk(m_dllName.c_str(), szImpName, szFuncName, nOrdinal, impMember); 97 | m_libBuilder->AddObject(m_memName.c_str(), impMember); 98 | } 99 | 100 | void WINAPI AddImportFunctionByNameWithHint(LPCSTR szImpName, LPCSTR szFuncName, LPCSTR szImportName, int nOrdinal) 101 | { 102 | ICoffBuilder* impMember = CreateObject(); 103 | m_secBuilder->BuildImportThunk(m_dllName.c_str(), szImpName, szFuncName, szImportName, nOrdinal, impMember); 104 | m_libBuilder->AddObject(m_memName.c_str(), impMember); 105 | } 106 | 107 | void WINAPI Build() 108 | { 109 | ICoffBuilder* nullThunk = CreateObject(); 110 | m_secBuilder->BuildNullThunk(m_dllName.c_str(), nullThunk); 111 | m_libBuilder->AddObject(m_memName.c_str(), nullThunk); 112 | 113 | m_libBuilder->FillOffsets(); 114 | } 115 | 116 | void WINAPI GetRawData(PBYTE buf) 117 | { 118 | m_libBuilder->GetRawData(buf); 119 | } 120 | 121 | int WINAPI GetDataLength() 122 | { 123 | return m_libBuilder->GetDataLength(); 124 | } 125 | }; 126 | 127 | extern "C" IImportLibraryBuilder* WINAPI CreateX86ImpLibBuilder(LPCSTR szDllName, LPCSTR szMemberName) 128 | { 129 | return new CImportLibraryBuilder(szDllName, szMemberName); 130 | } 131 | 132 | extern "C" IImportLibraryBuilder* WINAPI CreateX64ImpLibBuilder(LPCSTR szDllName, LPCSTR szMemberName) 133 | { 134 | return new CImportLibraryBuilder(szDllName, szMemberName); 135 | } 136 | }; 137 | -------------------------------------------------------------------------------- /ImpLibFix/ImpLibFix.cpp: -------------------------------------------------------------------------------- 1 | #include "ImpLibFix.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace Sora { 9 | class ImpLibRenameImpl { 10 | PBYTE m_pData; 11 | PBYTE m_pDataEnd; 12 | 13 | PIMAGE_ARCHIVE_MEMBER_HEADER GetMemberHeader() 14 | { 15 | return (PIMAGE_ARCHIVE_MEMBER_HEADER)m_pData; 16 | } 17 | 18 | bool GetNumberValue(PBYTE pStart, int nLen, DWORD* val) 19 | { 20 | int r = 0; 21 | PBYTE pEnd = pStart + nLen; 22 | for(;;) { 23 | if (pStart >= pEnd) 24 | break; 25 | if (*pStart == ' ') 26 | break; 27 | 28 | int n = *pStart - '0'; 29 | if (n <= 9 && n >= 0) { 30 | r = r * 10 + n; 31 | } else 32 | return false; 33 | 34 | ++pStart; 35 | } 36 | *val = r; 37 | return true; 38 | } 39 | 40 | bool CheckLeftDataLen(int len) 41 | { 42 | if (m_pData + len < m_pDataEnd) 43 | return true; 44 | else 45 | return false; 46 | } 47 | 48 | bool Step1_CheckSign() 49 | { 50 | if (!CheckLeftDataLen(IMAGE_ARCHIVE_START_SIZE)) 51 | return false; 52 | if (!std::equal(m_pData, m_pData + IMAGE_ARCHIVE_START_SIZE, IMAGE_ARCHIVE_START)) 53 | return false; 54 | 55 | m_pData += IMAGE_ARCHIVE_START_SIZE; 56 | return true; 57 | } 58 | 59 | bool Step2_GetMemberName(std::string& mn) 60 | { 61 | if(!CheckLeftDataLen(sizeof(IMAGE_ARCHIVE_MEMBER_HEADER))) 62 | return false; 63 | PIMAGE_ARCHIVE_MEMBER_HEADER pHeader = GetMemberHeader(); 64 | mn = std::string(pHeader->Name, pHeader->Name + sizeof(pHeader->Name)); 65 | 66 | return true; 67 | } 68 | 69 | bool Step3_CheckIfReservedName(std::string& mn) 70 | { 71 | if (!mn.empty() && mn[0] != '/') 72 | return false; 73 | 74 | return true; 75 | } 76 | 77 | bool Step4_Rename(LPCSTR szNewName) 78 | { 79 | PIMAGE_ARCHIVE_MEMBER_HEADER pHeader = GetMemberHeader(); 80 | std::fill(pHeader->Name, pHeader->Name + sizeof(pHeader->Name), ' '); 81 | int nNewNameLen = lstrlenA(szNewName); 82 | if (nNewNameLen > sizeof(pHeader->Name)) 83 | std::copy(szNewName, szNewName + sizeof(pHeader->Name), pHeader->Name); 84 | else 85 | std::copy(szNewName, szNewName + nNewNameLen, pHeader->Name); 86 | 87 | return true; 88 | } 89 | 90 | bool Step5_MoveNext() 91 | { 92 | PIMAGE_ARCHIVE_MEMBER_HEADER pHeader = GetMemberHeader(); 93 | m_pData += sizeof(IMAGE_ARCHIVE_MEMBER_HEADER); 94 | 95 | DWORD nSize; 96 | if (!GetNumberValue(pHeader->Size, sizeof(pHeader->Size), &nSize)) 97 | return false; 98 | 99 | if (!CheckLeftDataLen(nSize)) 100 | return false; 101 | 102 | m_pData += nSize; 103 | 104 | //pad to 2B align 105 | if (nSize % 2 == 1) 106 | ++m_pData; 107 | 108 | return true; 109 | } 110 | 111 | bool Step6_IsEof() 112 | { 113 | if (CheckLeftDataLen(sizeof(IMAGE_ARCHIVE_MEMBER_HEADER))) 114 | return false; 115 | else 116 | return true; 117 | } 118 | 119 | public: 120 | ImpLibRenameImpl(PBYTE pData, int len) 121 | { 122 | m_pData = pData; 123 | m_pDataEnd = pData + len; 124 | } 125 | 126 | int DoWork(LPCSTR szNewName) 127 | { 128 | int cnt = 0; 129 | 130 | if(!Step1_CheckSign()) 131 | return -1; 132 | 133 | doNext: 134 | std::string mn; 135 | 136 | if(!Step2_GetMemberName(mn)) 137 | return -1; 138 | 139 | if( Step3_CheckIfReservedName(mn) == false ) 140 | { 141 | Step4_Rename(szNewName); 142 | ++cnt; 143 | } 144 | 145 | if (Step5_MoveNext() == false) 146 | return -1; 147 | 148 | if (Step6_IsEof() == false) 149 | goto doNext; 150 | 151 | return cnt; 152 | } 153 | }; 154 | 155 | int WINAPI RenameImpLibObjects(LPCSTR szNewName, PBYTE pData, int nDataLen) 156 | { 157 | ImpLibRenameImpl impl(pData, nDataLen); 158 | return impl.DoWork(szNewName); 159 | } 160 | 161 | int WINAPI GetMaxNameLength() 162 | { 163 | return sizeof(((PIMAGE_ARCHIVE_MEMBER_HEADER)0)->Name); 164 | } 165 | }; 166 | -------------------------------------------------------------------------------- /MakeImpLib/MakeImpLib.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release_Static 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B} 25 | Win32Proj 26 | MakeImpLib 27 | 28 | 29 | 30 | Application 31 | true 32 | v120_xp 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v120_xp 39 | false 40 | Unicode 41 | 42 | 43 | Application 44 | false 45 | v120_xp 46 | false 47 | Unicode 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | true 64 | $(OutDir);C:\WDK\7600.16385.1\lib\ATL\i386;$(LibraryPath) 65 | ../CoffGen;../LibGen;../ImpGen;C:\WDK\7600.16385.1\inc\atl71;$(IncludePath) 66 | 67 | 68 | false 69 | $(OutDir);C:\WDK\7600.16385.1\lib\ATL\i386;$(LibraryPath) 70 | ../CoffGen;../LibGen;../ImpGen;C:\WDK\7600.16385.1\inc\atl71;$(IncludePath) 71 | 72 | 73 | false 74 | $(OutDir);C:\WDK\7600.16385.1\lib\ATL\i386;$(LibraryPath) 75 | ../CoffGen;../LibGen;../ImpGen;C:\WDK\7600.16385.1\inc\atl71;$(IncludePath) 76 | 77 | 78 | 79 | 80 | 81 | Level3 82 | Disabled 83 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 84 | 85 | 86 | Console 87 | true 88 | LibGenHelper.lib;%(AdditionalDependencies) 89 | 90 | 91 | 92 | 93 | Level3 94 | 95 | 96 | MaxSpeed 97 | true 98 | true 99 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 100 | MultiThreaded 101 | 102 | 103 | Console 104 | false 105 | true 106 | true 107 | LibGenHelper.lib;%(AdditionalDependencies) 108 | 109 | 110 | 111 | 112 | Level3 113 | 114 | 115 | MaxSpeed 116 | true 117 | true 118 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 119 | MultiThreaded 120 | 121 | 122 | Console 123 | false 124 | true 125 | true 126 | LibGenHelper.lib;LibGen.lib;ImpGen.lib;CoffGen.lib;%(AdditionalDependencies) 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /implib.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2013 for Windows Desktop 4 | VisualStudioVersion = 12.0.30110.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoffGen", "CoffGen\CoffGen.vcxproj", "{A3F71BEF-1263-4682-8A22-A2966B4BA075}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImpGen", "ImpGen\ImpGen.vcxproj", "{5E0B0EF6-C023-44B1-820A-F8EA26D5297D}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {A3F71BEF-1263-4682-8A22-A2966B4BA075} = {A3F71BEF-1263-4682-8A22-A2966B4BA075} 11 | EndProjectSection 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImpLibFix", "ImpLibFix\ImpLibFix.vcxproj", "{D2693F3C-593D-41A7-B936-4D962095DFD4}" 14 | EndProject 15 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibGen", "LibGen\LibGen.vcxproj", "{79742C1B-1D28-4DF4-B5AA-D161599491C3}" 16 | ProjectSection(ProjectDependencies) = postProject 17 | {A3F71BEF-1263-4682-8A22-A2966B4BA075} = {A3F71BEF-1263-4682-8A22-A2966B4BA075} 18 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D} = {5E0B0EF6-C023-44B1-820A-F8EA26D5297D} 19 | EndProjectSection 20 | EndProject 21 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibGenHelper", "LibGenHelper\LibGenHelper.vcxproj", "{EA713B3F-F9E0-4283-8632-250077CE0768}" 22 | ProjectSection(ProjectDependencies) = postProject 23 | {79742C1B-1D28-4DF4-B5AA-D161599491C3} = {79742C1B-1D28-4DF4-B5AA-D161599491C3} 24 | {A3F71BEF-1263-4682-8A22-A2966B4BA075} = {A3F71BEF-1263-4682-8A22-A2966B4BA075} 25 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D} = {5E0B0EF6-C023-44B1-820A-F8EA26D5297D} 26 | EndProjectSection 27 | EndProject 28 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MakeImpLib", "MakeImpLib\MakeImpLib.vcxproj", "{6E63662B-403E-4DBD-A27F-3038B3BC6D2B}" 29 | ProjectSection(ProjectDependencies) = postProject 30 | {EA713B3F-F9E0-4283-8632-250077CE0768} = {EA713B3F-F9E0-4283-8632-250077CE0768} 31 | EndProjectSection 32 | EndProject 33 | Global 34 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 35 | Debug|Win32 = Debug|Win32 36 | Release_Static|Win32 = Release_Static|Win32 37 | Release|Win32 = Release|Win32 38 | TestCoffGen|Win32 = TestCoffGen|Win32 39 | TestImpGen|Win32 = TestImpGen|Win32 40 | TestLibGen|Win32 = TestLibGen|Win32 41 | EndGlobalSection 42 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 43 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.Debug|Win32.ActiveCfg = Debug|Win32 44 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.Debug|Win32.Build.0 = Debug|Win32 45 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 46 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.Release_Static|Win32.Build.0 = Release_Static|Win32 47 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.Release|Win32.ActiveCfg = Release|Win32 48 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.Release|Win32.Build.0 = Release|Win32 49 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.TestCoffGen|Win32.ActiveCfg = TestCoffGen|Win32 50 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.TestCoffGen|Win32.Build.0 = TestCoffGen|Win32 51 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.TestImpGen|Win32.ActiveCfg = TestImpGen|Win32 52 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.TestImpGen|Win32.Build.0 = TestImpGen|Win32 53 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.TestLibGen|Win32.ActiveCfg = TestLibGen|Win32 54 | {A3F71BEF-1263-4682-8A22-A2966B4BA075}.TestLibGen|Win32.Build.0 = TestLibGen|Win32 55 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.Debug|Win32.ActiveCfg = Debug|Win32 56 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.Debug|Win32.Build.0 = Debug|Win32 57 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 58 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.Release_Static|Win32.Build.0 = Release_Static|Win32 59 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.Release|Win32.ActiveCfg = Release|Win32 60 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.Release|Win32.Build.0 = Release|Win32 61 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.TestCoffGen|Win32.ActiveCfg = TestCoffGen|Win32 62 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.TestImpGen|Win32.ActiveCfg = TestImpGen|Win32 63 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.TestImpGen|Win32.Build.0 = TestImpGen|Win32 64 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.TestLibGen|Win32.ActiveCfg = TestLibGen|Win32 65 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D}.TestLibGen|Win32.Build.0 = TestLibGen|Win32 66 | {D2693F3C-593D-41A7-B936-4D962095DFD4}.Debug|Win32.ActiveCfg = Debug|Win32 67 | {D2693F3C-593D-41A7-B936-4D962095DFD4}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 68 | {D2693F3C-593D-41A7-B936-4D962095DFD4}.Release|Win32.ActiveCfg = Release|Win32 69 | {D2693F3C-593D-41A7-B936-4D962095DFD4}.TestCoffGen|Win32.ActiveCfg = TestCoffGen|Win32 70 | {D2693F3C-593D-41A7-B936-4D962095DFD4}.TestImpGen|Win32.ActiveCfg = TestImpGen|Win32 71 | {D2693F3C-593D-41A7-B936-4D962095DFD4}.TestLibGen|Win32.ActiveCfg = TestLibGen|Win32 72 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.Debug|Win32.ActiveCfg = Debug|Win32 73 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.Debug|Win32.Build.0 = Debug|Win32 74 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 75 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.Release_Static|Win32.Build.0 = Release_Static|Win32 76 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.Release|Win32.ActiveCfg = Release|Win32 77 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.Release|Win32.Build.0 = Release|Win32 78 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.TestCoffGen|Win32.ActiveCfg = TestCoffGen|Win32 79 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.TestImpGen|Win32.ActiveCfg = TestImpGen|Win32 80 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.TestLibGen|Win32.ActiveCfg = TestLibGen|Win32 81 | {79742C1B-1D28-4DF4-B5AA-D161599491C3}.TestLibGen|Win32.Build.0 = TestLibGen|Win32 82 | {EA713B3F-F9E0-4283-8632-250077CE0768}.Debug|Win32.ActiveCfg = Debug|Win32 83 | {EA713B3F-F9E0-4283-8632-250077CE0768}.Debug|Win32.Build.0 = Debug|Win32 84 | {EA713B3F-F9E0-4283-8632-250077CE0768}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 85 | {EA713B3F-F9E0-4283-8632-250077CE0768}.Release_Static|Win32.Build.0 = Release_Static|Win32 86 | {EA713B3F-F9E0-4283-8632-250077CE0768}.Release|Win32.ActiveCfg = Release|Win32 87 | {EA713B3F-F9E0-4283-8632-250077CE0768}.Release|Win32.Build.0 = Release|Win32 88 | {EA713B3F-F9E0-4283-8632-250077CE0768}.TestCoffGen|Win32.ActiveCfg = Release|Win32 89 | {EA713B3F-F9E0-4283-8632-250077CE0768}.TestImpGen|Win32.ActiveCfg = Release|Win32 90 | {EA713B3F-F9E0-4283-8632-250077CE0768}.TestLibGen|Win32.ActiveCfg = Release|Win32 91 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.Debug|Win32.ActiveCfg = Debug|Win32 92 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.Debug|Win32.Build.0 = Debug|Win32 93 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 94 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.Release_Static|Win32.Build.0 = Release_Static|Win32 95 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.Release|Win32.ActiveCfg = Release|Win32 96 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.Release|Win32.Build.0 = Release|Win32 97 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.TestCoffGen|Win32.ActiveCfg = Release|Win32 98 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.TestImpGen|Win32.ActiveCfg = Release|Win32 99 | {6E63662B-403E-4DBD-A27F-3038B3BC6D2B}.TestLibGen|Win32.ActiveCfg = Release|Win32 100 | EndGlobalSection 101 | GlobalSection(SolutionProperties) = preSolution 102 | HideSolutionNode = FALSE 103 | EndGlobalSection 104 | EndGlobal 105 | -------------------------------------------------------------------------------- /LibGenHelper/LibGenHelper.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release_Static 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | 18 | {EA713B3F-F9E0-4283-8632-250077CE0768} 19 | LibGenHelper 20 | 21 | 22 | 23 | DynamicLibrary 24 | true 25 | v120_xp 26 | Unicode 27 | 28 | 29 | DynamicLibrary 30 | false 31 | v120_xp 32 | false 33 | Unicode 34 | 35 | 36 | StaticLibrary 37 | false 38 | v120_xp 39 | false 40 | Unicode 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | $(OutDir);$(LibraryPath) 57 | ../CoffGen;../LibGen;../ImpGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 58 | 59 | 60 | $(OutDir);$(LibraryPath) 61 | ../CoffGen;../LibGen;../ImpGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 62 | 63 | 64 | $(OutDir);$(LibraryPath) 65 | ../CoffGen;../LibGen;../ImpGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 66 | 67 | 68 | 69 | Level3 70 | Disabled 71 | true 72 | 73 | 74 | true 75 | Windows 76 | LibGen.lib;ImpGen.lib;%(AdditionalDependencies) 77 | LibGenHelper.def 78 | 79 | 80 | 81 | 82 | Level3 83 | MaxSpeed 84 | true 85 | true 86 | true 87 | MultiThreaded 88 | _USING_V110_SDK71_;%(PreprocessorDefinitions) 89 | 90 | 91 | false 92 | true 93 | true 94 | Windows 95 | LibGen.lib;ImpGen.lib;%(AdditionalDependencies) 96 | LibGenHelper.def 97 | 98 | 99 | _USING_V110_SDK71_;BUILD_DLL;%(PreprocessorDefinitions) 100 | 101 | 102 | 103 | 104 | Level3 105 | MaxSpeed 106 | true 107 | true 108 | false 109 | MultiThreaded 110 | 111 | 112 | true 113 | true 114 | true 115 | Windows 116 | LibGen.lib;ImpGen.lib;%(AdditionalDependencies) 117 | 118 | 119 | 120 | 121 | MachineX86 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /CoffGen/coffInterfaces.h: -------------------------------------------------------------------------------- 1 | #ifndef COFFINTERFACES_H 2 | #define COFFINTERFACES_H 3 | 4 | #include 5 | 6 | namespace Sora { 7 | //indicate that the object offers method to free 8 | class IDispose 9 | { 10 | public: 11 | virtual void WINAPI Dispose() = 0; 12 | }; 13 | 14 | //indicate that the object can output binary datas 15 | class IHasRawData 16 | { 17 | public: 18 | virtual int WINAPI GetDataLength() = 0; 19 | 20 | //the memory should be allocated by the caller 21 | virtual void WINAPI GetRawData(PBYTE) = 0; 22 | }; 23 | 24 | class ICoffBuilder; //for building coff object file 25 | class ISectionBuilder; //for building section of coff object file 26 | class IStringTableBuilder; //for building string table of coff object file 27 | class ISymbolStrings; //for enum each symbol string in symbol table 28 | class ISymbolTableBuilder; //for building symbol table of coff object file 29 | class ISectionAuxSymbol; //present a aux symbol in symbol table 30 | class IRelocatableVar; //present a relocation item in relocation table 31 | class IRelocationTableBuilder; //for building relocation table of coff object file 32 | 33 | class ICoffFactory 34 | { 35 | public: 36 | virtual ICoffBuilder* WINAPI CreateCoffBuilder() = 0; 37 | virtual ISectionBuilder* WINAPI CreateSectionBuilder() = 0; 38 | 39 | //generally this function is not called by user. 40 | virtual ISymbolTableBuilder* WINAPI CreateSymbolTableBuilder() = 0; 41 | 42 | //generally this function is not called by user. 43 | virtual IStringTableBuilder* WINAPI CreateStringTableBuilder() = 0; 44 | 45 | virtual IRelocatableVar* WINAPI CreateRelocatableVar() = 0; 46 | 47 | //generally this function is not called by user. 48 | virtual IRelocationTableBuilder* WINAPI CreateRelocationTableBuilder() = 0; 49 | }; 50 | 51 | class ICoffBuilder : public IDispose, public IHasRawData 52 | { 53 | public: 54 | //return: index in secions, 1-based. this function will set the section index 55 | //the ownership of object is transferred 56 | virtual int WINAPI AppendSection(ISectionBuilder*) = 0; 57 | 58 | virtual IStringTableBuilder* WINAPI GetStringTableBuilder() = 0; 59 | virtual ISymbolTableBuilder* WINAPI GetSymbolTableBuilder() = 0; 60 | 61 | //call turns: add symbol -> PushRelocs. the function will reference relocs to previous added symbols 62 | virtual void WINAPI PushRelocs() = 0; 63 | }; 64 | 65 | enum SectionCharacteristic 66 | { 67 | SECH_READ = 1, 68 | SECH_WRITE = 2, 69 | SECH_EXEC = 4, 70 | SECH_CODE = 8, 71 | SECH_ALIGN1 = 16, 72 | SECH_ALIGN2 = 32, 73 | SECH_ALIGN4 = 64, 74 | SECH_ALIGN8 = 128, 75 | SECH_ALIGN16 = 256, 76 | SECH_ALIGN32 = 512, 77 | SECH_ALIGN64 = 1024, 78 | SECH_UNINIT = 2048, 79 | SECH_COMDAT = 4096 80 | }; 81 | 82 | enum SectionComdat 83 | { 84 | SECO_NODUPLICATE = 1, 85 | SECO_SELECTANY, 86 | SECO_SELECTSAMESIZE, 87 | SECO_SELECTSAME, 88 | SECO_ASSOCIATIVE, 89 | SECO_SELECTLARGEST 90 | }; 91 | 92 | class ISectionBuilder : public IDispose 93 | { 94 | public: 95 | //ownership of relocationItems will transfer to this object 96 | //the offset in relocatableVar is relative to the beginning of pData 97 | virtual void WINAPI AppendData(LPCBYTE pData, int len, IRelocatableVar*[], int relocCount) = 0; 98 | 99 | virtual void WINAPI SetCharacteristics(DWORD) = 0; 100 | virtual void WINAPI SetName(LPCSTR) = 0; //set section name, max length: 8 chars 101 | 102 | virtual int WINAPI GetHeaderLength() = 0; 103 | 104 | //param 2: offset (base) of the section in the data part 105 | virtual void WINAPI GetRawHeader(PBYTE, DWORD rawOffset) = 0; 106 | 107 | virtual int WINAPI GetDataLength() = 0; //not include the header 108 | virtual void WINAPI GetRawData(PBYTE) = 0; //not include the header either 109 | 110 | //please don't call setsectionindex by hand unless you know what you are doing. 111 | //it's called by the coff builder 112 | virtual void WINAPI SetSectionIndex(int) = 0; 113 | 114 | virtual int WINAPI GetSectionIndex() = 0; //1-based 115 | 116 | //please don't call pushrelocs by hand unless you know what you are doing. 117 | //this will be called by coff builder's pushrelocs 118 | virtual void WINAPI PushRelocs(ISymbolTableBuilder*) = 0; 119 | 120 | //input: SectionCharacteristic output: raw characteristic 121 | virtual DWORD WINAPI GetRawCharacteristic(DWORD) = 0; //object independent 122 | 123 | //return the raw characteristic of this object 124 | virtual DWORD WINAPI GetRawCharacteristic() = 0; 125 | 126 | //no crc is generated in aux symbol 127 | //associated section can be null 128 | virtual ISectionAuxSymbol* WINAPI CreateAuxSymbol(ISectionBuilder* associatedSection, SectionComdat selection) = 0; 129 | }; 130 | 131 | class IStringTableBuilder : public IDispose, public IHasRawData 132 | { 133 | public: 134 | //return the offset of appended string 135 | virtual int WINAPI AppendString(LPCSTR) = 0; 136 | 137 | //don't free the returned value, it's inside the string table 138 | virtual LPCSTR WINAPI GetString(int offset) = 0; 139 | }; 140 | 141 | enum StorageType 142 | { 143 | SYST_EXTERN = 1, 144 | SYST_STATIC, 145 | SYST_SECTION, 146 | SYST_FUNCTION, 147 | SYST_STATICFUNCTION 148 | }; 149 | 150 | class ISymbolStrings : public IDispose 151 | { 152 | public: 153 | virtual int WINAPI GetCount() = 0; 154 | virtual LPCSTR WINAPI GetString(int nIndex) = 0; 155 | }; 156 | 157 | class ISymbolTableBuilder : public IDispose, public IHasRawData 158 | { 159 | public: 160 | //return the index of added item, 0-based 161 | //value: often the offset. 162 | //value could be size when add extern reference though often 0 here. 163 | virtual int WINAPI AddSymbol(ISectionBuilder* section, int value, LPCSTR name, StorageType, int auxCnt) = 0; 164 | 165 | //data is copied. after the function returned the parameter can be freed 166 | //often ISectionAuxSymbol* 167 | //ownership is not transfered, don't forget to free it 168 | virtual int WINAPI AddAuxData(IHasRawData*) = 0; 169 | 170 | virtual int WINAPI GetSymbolCount() = 0; 171 | 172 | //please don't call setsectionindex by hand. 173 | virtual void WINAPI SetStringTable(IStringTableBuilder*) = 0; 174 | 175 | //the caller has responsibility to free the returned object 176 | virtual ISymbolStrings* GetPublicSymbolNames() = 0; 177 | }; 178 | 179 | enum RelocateType { 180 | VARelocate32 = 1, 181 | VARelocate64, 182 | RVARelocate 183 | }; 184 | 185 | class IRelocatableVar : public IDispose 186 | { 187 | public: 188 | //change the inside offset value of this object by add the parameter value 189 | virtual void WINAPI Offset(int offset) = 0; 190 | 191 | //section and offset point to the mem that should be rewrite during linking 192 | virtual void WINAPI Set(LPCSTR symbol, ISectionBuilder* section, DWORD offset, int size, DWORD relocType) = 0; 193 | 194 | virtual void WINAPI Get(LPCSTR* symbol, ISectionBuilder** section, DWORD* offset, int* size, DWORD* relocType) = 0; 195 | }; 196 | 197 | class IRelocationTableBuilder : public IDispose, public IHasRawData 198 | { 199 | public: 200 | //get the bytes of a pointer. 4 for x86 and 8 for x64 201 | virtual int WINAPI GetPtrLength() = 0; 202 | 203 | //it's used during build section header 204 | //generally you don't need call this method unless you know what you are doing 205 | virtual int WINAPI GetCount() = 0; 206 | 207 | //ownership is transfered 208 | virtual void WINAPI AppendRelocationItem(IRelocatableVar*) = 0; 209 | 210 | //this will be called by section builder's pushrelocs 211 | virtual void WINAPI PushToSymbolTable(ISymbolTableBuilder*) = 0; 212 | }; 213 | 214 | class ISectionAuxSymbol : public IHasRawData, public IDispose 215 | { 216 | }; 217 | }; 218 | 219 | #endif 220 | -------------------------------------------------------------------------------- /MakeImpLib/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../LibGenHelper/LibGenHelperInterfaces.h" 10 | #include "../LibGenHelper/LibGenHelperFactory.h" 11 | 12 | struct MyMsgException 13 | { 14 | CString fmt; 15 | CString msg; 16 | MyMsgException(LPCTSTR p) : msg(p), fmt("%s") {} 17 | MyMsgException(LPCTSTR p1, LPCTSTR p2) : fmt(p1), msg(p2) {} 18 | }; 19 | 20 | int _tmain(int argc, TCHAR* argv[]) 21 | { 22 | CoInitializeEx(NULL, COINIT_MULTITHREADED); 23 | 24 | try 25 | { 26 | if (argv[1] != 0 && argv[2] != 0 && argv[3] == 0) { 27 | CComPtr xdoc; 28 | if (xdoc.CoCreateInstance(L"Msxml2.DOMDocument.6.0") != S_OK) 29 | throw MyMsgException(TEXT("Fail to create XML parser object!")); 30 | 31 | CComVariant strFileName; 32 | strFileName = SysAllocString( CT2CW(argv[1]) ); 33 | VARIANT_BOOL bIsSucc; 34 | xdoc->load(strFileName, &bIsSucc); 35 | if (bIsSucc != VARIANT_TRUE) 36 | throw MyMsgException(TEXT("Fail to load input file %s!"), argv[1]); 37 | 38 | CComPtr xDllNameNode; 39 | CComBSTR strXPath; 40 | strXPath = L"/ImportLibrary/DllName"; 41 | xdoc->selectSingleNode(strXPath, &xDllNameNode); 42 | if (xDllNameNode == NULL) 43 | throw MyMsgException(TEXT("No DllName node!")); 44 | 45 | Sora::IImportLibraryBuilder* impBuilder; 46 | CComBSTR strDllName; 47 | xDllNameNode->get_text(&strDllName); 48 | CW2AEX<> cvtstrDllName(strDllName, CP_ACP); 49 | 50 | CComPtr xAmd64Node; 51 | strXPath = L"/ImportLibrary/ArchAMD64"; 52 | xdoc->selectSingleNode(strXPath, &xAmd64Node); 53 | if (xAmd64Node == NULL) 54 | impBuilder = Sora::CreateX86ImpLibBuilder(cvtstrDllName, cvtstrDllName); 55 | else 56 | impBuilder = Sora::CreateX64ImpLibBuilder(cvtstrDllName, cvtstrDllName); 57 | 58 | strXPath = L"/ImportLibrary/Import"; 59 | CComPtr xImportNodes; 60 | if (xdoc->selectNodes(strXPath, &xImportNodes) != S_OK) 61 | throw MyMsgException(TEXT("No Import nodes found!")); 62 | 63 | for(;;) { 64 | CComPtr xImportNode; 65 | if (xImportNodes->nextNode(&xImportNode) != S_OK) 66 | break; 67 | 68 | CComPtr xLinkNameNode, xStubNameNode, xImportNameNode, xImportOrdinalNode; 69 | CComBSTR strLinkName, strStubName, strImportName, strImportOrdinal; 70 | 71 | strXPath = L"./LinkName"; 72 | if (xImportNode->selectSingleNode(strXPath, &xLinkNameNode) != S_OK) 73 | throw MyMsgException(TEXT("No LinkName Node!")); 74 | 75 | strXPath = L"./StubName"; 76 | xImportNode->selectSingleNode(strXPath, &xStubNameNode); 77 | //if no stubname node found, will not generate callstub 78 | 79 | xLinkNameNode->get_text(&strLinkName); 80 | if (xStubNameNode != NULL) xStubNameNode->get_text(&strStubName); 81 | 82 | HRESULT selectImportName; 83 | HRESULT selectOrdinal; 84 | strXPath = L"./ImportName"; 85 | selectImportName = xImportNode->selectSingleNode(strXPath, &xImportNameNode); 86 | strXPath = L"./Ordinal"; 87 | selectOrdinal = xImportNode->selectSingleNode(strXPath, &xImportOrdinalNode); 88 | int nOrdinal = 0; 89 | 90 | if (selectImportName == S_OK || selectOrdinal == S_OK) { 91 | if (selectImportName == S_OK) 92 | xImportNameNode->get_text(&strImportName); 93 | 94 | if (selectOrdinal == S_OK) { 95 | xImportOrdinalNode->get_text(&strImportOrdinal); 96 | LPCWSTR pszImportOrdinal = strImportOrdinal; 97 | 98 | while(*pszImportOrdinal != 0) { 99 | nOrdinal *= 10; 100 | nOrdinal += *pszImportOrdinal - L'0'; 101 | ++pszImportOrdinal; 102 | } 103 | } 104 | 105 | if (selectImportName == S_OK && selectOrdinal == S_OK) { 106 | impBuilder->AddImportFunctionByNameWithHint( 107 | CW2AEX<>(strLinkName, CP_UTF8), 108 | CW2AEX<>(strStubName, CP_UTF8), 109 | CW2AEX<>(strImportName, CP_UTF8), 110 | nOrdinal 111 | ); 112 | } else if (selectImportName == S_OK) { 113 | impBuilder->AddImportFunctionByName( 114 | CW2AEX<>(strLinkName, CP_UTF8), 115 | CW2AEX<>(strStubName, CP_UTF8), 116 | CW2AEX<>(strImportName, CP_UTF8) 117 | ); 118 | } else if (selectOrdinal == S_OK) { 119 | impBuilder->AddImportFunctionByOrdinal( 120 | CW2AEX<>(strLinkName, CP_UTF8), 121 | CW2AEX<>(strStubName, CP_UTF8), 122 | nOrdinal 123 | ); 124 | } 125 | } else { 126 | throw MyMsgException(TEXT("No ImportName or Ordinal Node!")); 127 | } 128 | } 129 | 130 | //save file 131 | impBuilder->Build(); 132 | 133 | int nFileSize = impBuilder->GetDataLength(); 134 | CHandle hFile( CreateFile(argv[2], GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, NULL) ); 135 | if ( (HANDLE)hFile == INVALID_HANDLE_VALUE ) 136 | throw MyMsgException(TEXT("Fail to create library File %s!"), argv[2]); 137 | 138 | if (SetFilePointer(hFile, nFileSize, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) 139 | if (GetLastError() != 0) 140 | throw MyMsgException(TEXT("Can't allocate disk space for output file!")); 141 | 142 | if (SetEndOfFile(hFile) == FALSE) 143 | throw MyMsgException(TEXT("Can't allocate disk space for output file!")); 144 | 145 | CHandle hFileMap( CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, nFileSize, 0) ); 146 | if ((HANDLE)hFileMap == NULL) 147 | throw MyMsgException(TEXT("Can't map output file for writing!")); 148 | 149 | LPVOID pFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0); 150 | if (pFile == 0) 151 | throw MyMsgException(TEXT("Can't map output file for writing!")); 152 | 153 | impBuilder->GetRawData((PBYTE)pFile); 154 | impBuilder->Dispose(); 155 | UnmapViewOfFile(pFile); 156 | } else { 157 | fprintf(stdout, "%s", 158 | "Make import library from XML\n" 159 | "using: MakeImpLib \n" 160 | "\n" 161 | "XML Sample\n" 162 | "\n" 163 | " \n" 164 | " \n" 165 | " Kernel32.dll\n" 166 | " \n" 167 | " __imp__SleepEx@8\n" 168 | " \n" 169 | " _SleepEx@8\n" 170 | " \n" 171 | " \n" 172 | " \n" 173 | " \n" 174 | " 1208\n" 175 | " SleepEx\n" 176 | " \n" 177 | " \n" 178 | " __imp__WaitForSingleObject@8\n" 179 | " WaitForSingleObject\n" 180 | " \n" 181 | "\n" 182 | "\n" 183 | " is needed " 184 | "for filename or function other than English letters.\n" 185 | ); 186 | } 187 | } 188 | catch (MyMsgException e) 189 | { 190 | fprintf(stderr, CT2CA(e.fmt), CT2CA(e.msg)); 191 | } 192 | 193 | CoUninitialize(); 194 | } 195 | -------------------------------------------------------------------------------- /ImpLibFix/ImpLibFix.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release_Static 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | TestCoffGen 18 | Win32 19 | 20 | 21 | TestImpGen 22 | Win32 23 | 24 | 25 | TestImpLibFix 26 | Win32 27 | 28 | 29 | TestLibGen 30 | Win32 31 | 32 | 33 | 34 | {D2693F3C-593D-41A7-B936-4D962095DFD4} 35 | ImpLibFix 36 | 37 | 38 | 39 | DynamicLibrary 40 | true 41 | v120 42 | Unicode 43 | 44 | 45 | DynamicLibrary 46 | true 47 | v120 48 | Unicode 49 | 50 | 51 | DynamicLibrary 52 | true 53 | v120 54 | Unicode 55 | 56 | 57 | DynamicLibrary 58 | true 59 | v120 60 | Unicode 61 | 62 | 63 | Application 64 | true 65 | v120 66 | Unicode 67 | 68 | 69 | DynamicLibrary 70 | false 71 | v120 72 | true 73 | Unicode 74 | 75 | 76 | DynamicLibrary 77 | false 78 | v120 79 | true 80 | Unicode 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | Level3 111 | Disabled 112 | false 113 | 114 | 115 | true 116 | ImpLibFix.def 117 | 118 | 119 | 120 | 121 | Level3 122 | Disabled 123 | false 124 | 125 | 126 | true 127 | ImpLibFix.def 128 | 129 | 130 | 131 | 132 | Level3 133 | Disabled 134 | false 135 | 136 | 137 | true 138 | ImpLibFix.def 139 | 140 | 141 | 142 | 143 | Level3 144 | Disabled 145 | false 146 | 147 | 148 | true 149 | ImpLibFix.def 150 | 151 | 152 | 153 | 154 | Level3 155 | Disabled 156 | false 157 | 158 | 159 | true 160 | 161 | 162 | 163 | 164 | Level3 165 | MaxSpeed 166 | true 167 | true 168 | false 169 | MultiThreaded 170 | 171 | 172 | true 173 | true 174 | true 175 | ImpLibFix.def 176 | 177 | 178 | 179 | 180 | Level3 181 | MaxSpeed 182 | true 183 | true 184 | false 185 | MultiThreaded 186 | 187 | 188 | true 189 | true 190 | true 191 | ImpLibFix.def 192 | 193 | 194 | 195 | 196 | 197 | true 198 | true 199 | true 200 | true 201 | true 202 | true 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /LibGen/LibGen.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release_Static 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | TestCoffGen 18 | Win32 19 | 20 | 21 | TestImpGen 22 | Win32 23 | 24 | 25 | TestLibGen 26 | Win32 27 | 28 | 29 | 30 | {79742C1B-1D28-4DF4-B5AA-D161599491C3} 31 | LibGen 32 | 33 | 34 | 35 | DynamicLibrary 36 | true 37 | v120_xp 38 | Unicode 39 | 40 | 41 | Application 42 | true 43 | v120_xp 44 | Unicode 45 | 46 | 47 | Application 48 | true 49 | v120_xp 50 | Unicode 51 | 52 | 53 | Application 54 | true 55 | v120_xp 56 | Unicode 57 | 58 | 59 | DynamicLibrary 60 | false 61 | v120_xp 62 | false 63 | Unicode 64 | 65 | 66 | StaticLibrary 67 | false 68 | v120_xp 69 | false 70 | Unicode 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | $(OutDir);$(LibraryPath) 96 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 97 | 98 | 99 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 100 | 101 | 102 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 103 | 104 | 105 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 106 | 107 | 108 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 109 | 110 | 111 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 112 | 113 | 114 | 115 | Level3 116 | Disabled 117 | false 118 | 119 | 120 | true 121 | Windows 122 | LibGen.def 123 | 124 | 125 | 126 | 127 | Level3 128 | Disabled 129 | true 130 | 131 | 132 | true 133 | Windows 134 | 135 | 136 | 137 | 138 | Level3 139 | Disabled 140 | true 141 | 142 | 143 | true 144 | Windows 145 | 146 | 147 | 148 | 149 | Level3 150 | Disabled 151 | false 152 | 153 | 154 | true 155 | coffgen.lib;impgen.lib;%(AdditionalDependencies) 156 | Console 157 | 158 | 159 | 160 | 161 | Level3 162 | MaxSpeed 163 | true 164 | true 165 | true 166 | MultiThreaded 167 | _USING_V110_SDK71_;%(PreprocessorDefinitions) 168 | 169 | 170 | false 171 | true 172 | true 173 | LibGen.def 174 | Windows 175 | 176 | 177 | _USING_V110_SDK71_;BUILD_DLL;%(PreprocessorDefinitions) 178 | 179 | 180 | 181 | 182 | Level3 183 | MaxSpeed 184 | true 185 | true 186 | false 187 | MultiThreaded 188 | 189 | 190 | true 191 | true 192 | true 193 | 194 | 195 | Windows 196 | 197 | 198 | MachineX86 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | true 209 | true 210 | true 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /CoffGen/CoffGen.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release_Static 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | TestImpGen 18 | Win32 19 | 20 | 21 | TestCoffGen 22 | Win32 23 | 24 | 25 | TestImpLibFix 26 | Win32 27 | 28 | 29 | TestLibGen 30 | Win32 31 | 32 | 33 | 34 | {A3F71BEF-1263-4682-8A22-A2966B4BA075} 35 | impobj 36 | CoffGen 37 | 38 | 39 | 40 | DynamicLibrary 41 | true 42 | v120_xp 43 | MultiByte 44 | 45 | 46 | DynamicLibrary 47 | true 48 | v120_xp 49 | MultiByte 50 | 51 | 52 | DynamicLibrary 53 | true 54 | v120_xp 55 | MultiByte 56 | 57 | 58 | Application 59 | true 60 | v120_xp 61 | MultiByte 62 | 63 | 64 | DynamicLibrary 65 | true 66 | v120_xp 67 | MultiByte 68 | 69 | 70 | DynamicLibrary 71 | false 72 | v120_xp 73 | false 74 | MultiByte 75 | 76 | 77 | StaticLibrary 78 | false 79 | v120_xp 80 | false 81 | MultiByte 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | Level3 112 | Disabled 113 | false 114 | 115 | 116 | true 117 | Console 118 | Enabled 119 | coffGen.def 120 | 121 | 122 | 123 | 124 | Level3 125 | Disabled 126 | false 127 | 128 | 129 | true 130 | Console 131 | Enabled 132 | coffGen.def 133 | 134 | 135 | 136 | 137 | Level3 138 | Disabled 139 | false 140 | 141 | 142 | true 143 | Console 144 | Enabled 145 | coffGen.def 146 | 147 | 148 | 149 | 150 | Level3 151 | Disabled 152 | false 153 | 154 | 155 | true 156 | Console 157 | Enabled 158 | 159 | 160 | 161 | 162 | 163 | 164 | Level3 165 | Disabled 166 | false 167 | 168 | 169 | true 170 | Console 171 | Enabled 172 | CoffGen.def 173 | 174 | 175 | 176 | 177 | Level3 178 | MaxSpeed 179 | true 180 | true 181 | false 182 | MultiThreaded 183 | _USING_V110_SDK71_;%(PreprocessorDefinitions) 184 | 185 | 186 | false 187 | true 188 | true 189 | Windows 190 | Enabled 191 | coffGen.def 192 | 193 | 194 | _USING_V110_SDK71_;BUILD_DLL;%(PreprocessorDefinitions) 195 | 196 | 197 | 198 | 199 | Level3 200 | MaxSpeed 201 | true 202 | true 203 | false 204 | MultiThreaded 205 | false 206 | 207 | 208 | true 209 | true 210 | true 211 | Windows 212 | Enabled 213 | 214 | 215 | 216 | 217 | MachineX86 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | true 228 | true 229 | true 230 | false 231 | false 232 | true 233 | true 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /ImpGen/ImpGen.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release_Static 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | TestImpGen 18 | Win32 19 | 20 | 21 | TestCoffGen 22 | Win32 23 | 24 | 25 | TestImpLibFix 26 | Win32 27 | 28 | 29 | TestLibGen 30 | Win32 31 | 32 | 33 | 34 | {5E0B0EF6-C023-44B1-820A-F8EA26D5297D} 35 | Win32Proj 36 | ImpGen 37 | 38 | 39 | 40 | DynamicLibrary 41 | true 42 | v120_xp 43 | Unicode 44 | 45 | 46 | DynamicLibrary 47 | true 48 | v120_xp 49 | Unicode 50 | 51 | 52 | DynamicLibrary 53 | true 54 | v120_xp 55 | Unicode 56 | 57 | 58 | DynamicLibrary 59 | false 60 | v120_xp 61 | false 62 | Unicode 63 | 64 | 65 | StaticLibrary 66 | false 67 | v120_xp 68 | false 69 | Unicode 70 | 71 | 72 | v120_xp 73 | Utility 74 | 75 | 76 | v120_xp 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | true 99 | $(OutDir);$(LibraryPath) 100 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 101 | 102 | 103 | true 104 | $(OutDir);$(LibraryPath) 105 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 106 | 107 | 108 | true 109 | $(OutDir);$(LibraryPath) 110 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 111 | 112 | 113 | false 114 | $(OutDir);$(LibraryPath) 115 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 116 | 117 | 118 | false 119 | $(OutDir);$(LibraryPath) 120 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 121 | 122 | 123 | $(OutDir);$(LibraryPath) 124 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 125 | 126 | 127 | $(OutDir);$(LibraryPath) 128 | ../CoffGen;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);$(IncludePath) 129 | 130 | 131 | 132 | 133 | 134 | Level3 135 | Disabled 136 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 137 | false 138 | 139 | 140 | Windows 141 | true 142 | coffgen.lib;%(AdditionalDependencies) 143 | ImpGen.def 144 | 145 | 146 | 147 | 148 | 149 | 150 | Level3 151 | Disabled 152 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 153 | false 154 | 155 | 156 | Windows 157 | true 158 | coffgen.lib;%(AdditionalDependencies) 159 | ImpGen.def 160 | 161 | 162 | 163 | 164 | 165 | 166 | Level3 167 | Disabled 168 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 169 | false 170 | 171 | 172 | Windows 173 | true 174 | coffgen.lib;%(AdditionalDependencies) 175 | ImpGen.def 176 | 177 | 178 | 179 | 180 | Level3 181 | 182 | 183 | MaxSpeed 184 | true 185 | true 186 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 187 | false 188 | MultiThreaded 189 | 190 | 191 | Windows 192 | false 193 | true 194 | true 195 | coffgen.lib;%(AdditionalDependencies) 196 | ImpGen.def 197 | 198 | 199 | _USING_V110_SDK71_;BUILD_DLL;%(PreprocessorDefinitions) 200 | 201 | 202 | 203 | 204 | Level3 205 | 206 | 207 | MaxSpeed 208 | true 209 | true 210 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 211 | false 212 | MultiThreaded 213 | 214 | 215 | Windows 216 | true 217 | true 218 | true 219 | coffgen.lib;%(AdditionalDependencies) 220 | 221 | 222 | 223 | 224 | MachineX86 225 | 226 | 227 | 228 | 229 | coffgen.lib;%(AdditionalDependencies) 230 | Windows 231 | 232 | 233 | 234 | 235 | coffgen.lib;%(AdditionalDependencies) 236 | Console 237 | true 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | true 248 | true 249 | true 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | -------------------------------------------------------------------------------- /LibGen/LibImpl.cpp: -------------------------------------------------------------------------------- 1 | #include "LibInterfaces.h" 2 | #include "LibFactory.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Sora 12 | { 13 | //return: is limit enough 14 | static bool StrCpyNoZero(LPSTR to, LPCSTR from, int limit) 15 | { 16 | bool r = true; 17 | int nFromLen = lstrlenA(from); 18 | if (nFromLen > limit) { 19 | nFromLen = limit; 20 | r = false; 21 | } 22 | std::copy(from, from + nFromLen, to); 23 | return r; 24 | } 25 | 26 | static void BuildMemberHeader(PIMAGE_ARCHIVE_MEMBER_HEADER h, LPCSTR szName, int nSize) 27 | { 28 | char tmpBuffer[32]; 29 | 30 | std::fill((char*)h, (char*)(h + 1), ' '); 31 | 32 | std::string strName(szName); 33 | if (strName.size() >= sizeof(h->Name)) 34 | strName[sizeof(h->Name) - 1] = '/'; 35 | else 36 | strName += '/'; 37 | 38 | StrCpyNoZero((LPSTR)h->Name, strName.c_str(), sizeof(h->Name)); 39 | h->Date[0] = '0'; 40 | h->Mode[0] = '0'; 41 | StrCpyNoZero((LPSTR)h->EndHeader, IMAGE_ARCHIVE_END, sizeof(h->EndHeader)); 42 | 43 | wsprintfA(tmpBuffer, "%d", nSize); 44 | StrCpyNoZero((LPSTR)h->Size, tmpBuffer, sizeof(h->Size)); 45 | } 46 | 47 | static DWORD32 GetBigEndian(DWORD32 val) 48 | { 49 | std::reverse((PBYTE)&val, ((PBYTE)&val) + sizeof(val)); 50 | return val; 51 | } 52 | 53 | class CBaseLinkMemberBuilder : public IHasRawData 54 | { 55 | public: 56 | struct StringLesser 57 | { 58 | bool operator()(const std::string& lhs, const std::string& rhs) 59 | { 60 | return strcmp(lhs.c_str(), rhs.c_str()) < 0; 61 | } 62 | }; 63 | protected: 64 | //slm: Second link Member 65 | typedef std::map OffsetCollection; 66 | OffsetCollection m_offsets; 67 | typedef std::map SymbolCollection; 68 | SymbolCollection m_symbols; 69 | 70 | template 71 | int GetIterIndex(Iterator x, Iterator begin) 72 | { 73 | int r = 0; 74 | while( x != begin ) { 75 | ++begin; 76 | ++r; 77 | } 78 | return r; 79 | } 80 | public: 81 | bool WINAPI SetMemberOffset(ICoffBuilder* member, int offset) 82 | { 83 | OffsetCollection::iterator x = m_offsets.find(member); 84 | if (x != m_offsets.end()) { 85 | x->second = offset; 86 | return true; 87 | } else 88 | return false; 89 | } 90 | 91 | void WINAPI AppendMember(ICoffBuilder* member) 92 | { 93 | m_offsets.insert( std::make_pair(member, 0) ); 94 | 95 | ISymbolStrings* sns = member->GetSymbolTableBuilder()->GetPublicSymbolNames(); 96 | int cnt = sns->GetCount(); 97 | int i; 98 | for(i = 0; i < cnt; ++i) 99 | m_symbols.insert( std::make_pair(std::string(sns->GetString(i)), member) ); 100 | 101 | sns->Dispose(); 102 | } 103 | }; 104 | 105 | class CFirstLinkMemberBuilder : virtual public CBaseLinkMemberBuilder 106 | { 107 | static bool SortOffsetLesser(const std::pair& a, const std::pair& b) 108 | { 109 | if (a.first < b.first) 110 | return true; 111 | else 112 | return false; 113 | } 114 | 115 | public: 116 | void WINAPI GetRawData(PBYTE buf) 117 | { 118 | PIMAGE_ARCHIVE_MEMBER_HEADER pHeader; 119 | *(LPVOID*)&pHeader = buf; 120 | BuildMemberHeader(pHeader, "", CFirstLinkMemberBuilder::GetDataLength() - sizeof(*pHeader)); 121 | ++pHeader; 122 | 123 | PDWORD32 pSymbolCnt = (PDWORD32) pHeader; 124 | *pSymbolCnt = GetBigEndian(m_symbols.size()); 125 | ++pSymbolCnt; 126 | 127 | // (offset, symbol) pairs 128 | std::vector< std::pair > tmp; 129 | 130 | { 131 | SymbolCollection::iterator i, iend; 132 | i = m_symbols.begin(); 133 | iend = m_symbols.end(); 134 | for(; i != iend; ++i) { 135 | OffsetCollection::iterator x; 136 | x = m_offsets.find(i->second); 137 | tmp.push_back( std::make_pair(x->second, i->first) ); 138 | } 139 | 140 | std::sort(tmp.begin(), tmp.end(), &CFirstLinkMemberBuilder::SortOffsetLesser); 141 | } 142 | 143 | PDWORD32 pOffsets = pSymbolCnt; 144 | { 145 | std::vector< std::pair >::iterator i, iend; 146 | i = tmp.begin(); 147 | iend = tmp.end(); 148 | for(; i != iend; ++i) { 149 | *pOffsets = GetBigEndian(i->first); 150 | ++pOffsets; 151 | } 152 | } 153 | 154 | char* pStringTable = (char*)pOffsets; 155 | { 156 | std::vector< std::pair >::iterator i = tmp.begin(), iend = tmp.end(); 157 | for(; i != iend; ++i) { 158 | int sl = i->second.size(); 159 | 160 | i->second.copy(pStringTable, sl); 161 | pStringTable += sl; 162 | *pStringTable = 0; 163 | ++pStringTable; 164 | } 165 | } 166 | } 167 | 168 | int WINAPI GetDataLength() 169 | { 170 | int r = 0; 171 | r += sizeof(IMAGE_ARCHIVE_MEMBER_HEADER); 172 | r += 4; //number of symbols 173 | r += 4 * m_symbols.size(); //array of offsets, one offset for one symbol 174 | 175 | //string table 176 | SymbolCollection::iterator i = m_symbols.begin(), iend = m_symbols.end(); 177 | for(; i != iend; ++i) 178 | r += i->first.size() + 1; //null terminated 179 | 180 | return r; 181 | } 182 | }; 183 | 184 | class CSecondLinkMemberBuilder : virtual public CBaseLinkMemberBuilder 185 | { 186 | public: 187 | void WINAPI GetRawData(PBYTE buf) 188 | { 189 | PIMAGE_ARCHIVE_MEMBER_HEADER mh; 190 | *(LPVOID*)&mh = buf; 191 | BuildMemberHeader(mh, "", CSecondLinkMemberBuilder::GetDataLength() - sizeof(*mh)); //not include header 192 | ++mh; 193 | 194 | PDWORD32 pMemberCnt = (PDWORD32) mh; 195 | *pMemberCnt = m_offsets.size(); 196 | ++pMemberCnt; 197 | 198 | PDWORD32 arrMemberOffset = pMemberCnt; 199 | std::set tmpOffsets; 200 | { 201 | OffsetCollection::iterator i = m_offsets.begin(), iend = m_offsets.end(); 202 | for(; i != iend; ++i) 203 | tmpOffsets.insert(i->second); 204 | 205 | std::copy(tmpOffsets.begin(), tmpOffsets.end(), arrMemberOffset); 206 | arrMemberOffset += tmpOffsets.size(); 207 | } 208 | 209 | PDWORD32 pSymbolCnt = arrMemberOffset; 210 | *pSymbolCnt = m_symbols.size(); 211 | ++pSymbolCnt; 212 | 213 | PWORD pSymbolBelongOffset = (PWORD) pSymbolCnt; 214 | { 215 | SymbolCollection::iterator i = m_symbols.begin(), iend = m_symbols.end(); 216 | for(; i != iend; ++i) { 217 | ICoffBuilder* c = i->second; 218 | OffsetCollection::iterator x = m_offsets.find(c); 219 | std::set::iterator y = tmpOffsets.find(x->second); 220 | *pSymbolBelongOffset = GetIterIndex(y, tmpOffsets.begin()) + 1; //1-based index 221 | ++pSymbolBelongOffset; 222 | } 223 | } 224 | 225 | char* pStringTable = (char*)pSymbolBelongOffset; 226 | { 227 | SymbolCollection::iterator i = m_symbols.begin(), iend = m_symbols.end(); 228 | for(; i != iend; ++i) { 229 | int sl = i->first.size(); 230 | 231 | i->first.copy(pStringTable, sl); 232 | pStringTable += sl; 233 | *pStringTable = 0; 234 | ++pStringTable; 235 | } 236 | } 237 | } 238 | 239 | int WINAPI GetDataLength() 240 | { 241 | int r = 0; 242 | r += sizeof(IMAGE_ARCHIVE_MEMBER_HEADER); 243 | r += 4; //number of members; 244 | r += 4 * m_offsets.size(); //offset array 245 | r += 4; //number of symbols 246 | r += 2 * m_symbols.size(); //symbol name index array 247 | 248 | //string table 249 | SymbolCollection::iterator i = m_symbols.begin(), iend = m_symbols.end(); 250 | for(; i != iend; ++i) 251 | r += i->first.size() + 1; //null terminated 252 | 253 | return r; 254 | } 255 | }; 256 | 257 | class CDoubleLinkMemberBuilder : public CFirstLinkMemberBuilder, public CSecondLinkMemberBuilder 258 | { 259 | int WINAPI GetDataLength() 260 | { 261 | throw std::logic_error("Not clear which to call"); 262 | } 263 | 264 | void WINAPI GetRawData(PBYTE buf) 265 | { 266 | throw std::logic_error("Not clear which to call"); 267 | } 268 | }; 269 | 270 | class CLibraryBuilder : public ILibraryBuilder 271 | { 272 | typedef std::pair ArchiveMember; 273 | std::vector m_members; 274 | CDoubleLinkMemberBuilder m_linkMember; 275 | 276 | ~CLibraryBuilder() 277 | { 278 | } 279 | 280 | bool DoPad(int& size) 281 | { 282 | if (size % 2 == 1) { 283 | ++size; 284 | return true; 285 | } else 286 | return false; 287 | } 288 | 289 | void DoPad(PBYTE& buf, int size) 290 | { 291 | if (size % 2 == 1) { 292 | *buf = *IMAGE_ARCHIVE_PAD; 293 | ++buf; 294 | } 295 | } 296 | public: 297 | void WINAPI Dispose() 298 | { 299 | delete this; 300 | } 301 | 302 | void WINAPI GetRawData(PBYTE buf) 303 | { 304 | PBYTE pBufBegin = buf; 305 | 306 | //sign 307 | std::copy(IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START + IMAGE_ARCHIVE_START_SIZE, buf); 308 | buf += IMAGE_ARCHIVE_START_SIZE; 309 | 310 | //first link member 311 | m_linkMember.CFirstLinkMemberBuilder::GetRawData(buf); 312 | buf += m_linkMember.CFirstLinkMemberBuilder::GetDataLength(); 313 | DoPad(buf, buf - pBufBegin); 314 | 315 | //second link member 316 | m_linkMember.CSecondLinkMemberBuilder::GetRawData(buf); 317 | buf += m_linkMember.CSecondLinkMemberBuilder::GetDataLength(); 318 | DoPad(buf, buf - pBufBegin); 319 | 320 | std::vector::iterator i, iend; 321 | i = m_members.begin(); 322 | iend = m_members.end(); 323 | for(; i != iend; ++i) { 324 | IMAGE_ARCHIVE_MEMBER_HEADER h; 325 | BuildMemberHeader(&h, i->first.c_str(), i->second->GetDataLength()); 326 | *(PIMAGE_ARCHIVE_MEMBER_HEADER)buf = h; 327 | buf += sizeof(h); 328 | i->second->GetRawData(buf); 329 | buf += i->second->GetDataLength(); 330 | DoPad(buf, buf - pBufBegin); 331 | } 332 | } 333 | 334 | int WINAPI GetDataLength() 335 | { 336 | return CalcSizeOrFillOffsets(false); 337 | } 338 | 339 | void WINAPI AddObject(LPCSTR szName, ICoffBuilder* cb) 340 | { 341 | cb->PushRelocs(); 342 | m_members.push_back( std::make_pair(std::string(szName), cb) ); 343 | m_linkMember.AppendMember(cb); 344 | } 345 | 346 | void WINAPI FillOffsets() 347 | { 348 | CalcSizeOrFillOffsets(true); 349 | } 350 | 351 | int WINAPI CalcSizeOrFillOffsets(bool bFillOffset) 352 | { 353 | int curPos = 0; 354 | 355 | //sign 356 | curPos += IMAGE_ARCHIVE_START_SIZE; 357 | 358 | //first link member 359 | curPos += m_linkMember.CFirstLinkMemberBuilder::GetDataLength(); 360 | DoPad(curPos); 361 | 362 | //second link member 363 | curPos += m_linkMember.CSecondLinkMemberBuilder::GetDataLength(); 364 | DoPad(curPos); 365 | 366 | std::vector::iterator i, iend; 367 | i = m_members.begin(); 368 | iend = m_members.end(); 369 | for(; i != iend; ++i) { 370 | if (bFillOffset) 371 | m_linkMember.SetMemberOffset(i->second, curPos); 372 | 373 | curPos += sizeof(IMAGE_ARCHIVE_MEMBER_HEADER); 374 | curPos += i->second->GetDataLength(); 375 | DoPad(curPos); 376 | } 377 | 378 | return curPos; 379 | } 380 | }; 381 | 382 | extern "C" ILibraryBuilder* WINAPI CreateLibraryBuilder() 383 | { 384 | return new CLibraryBuilder; 385 | } 386 | }; 387 | -------------------------------------------------------------------------------- /ImpGen/impImpl.cpp: -------------------------------------------------------------------------------- 1 | #include "ImpInterfaces.h" 2 | #include "ImpFactory.h" 3 | 4 | #include "cofffactory.h" 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #define OFFSET(stru, memb) ((DWORD)&((stru*)0)->memb) 12 | 13 | namespace Sora 14 | { 15 | typedef struct {} ArchX86; 16 | typedef struct {} ArchX64; 17 | typedef struct {} ArchIA64; 18 | 19 | template 20 | struct ArchTraits; 21 | 22 | template<> 23 | struct ArchTraits 24 | { 25 | enum { JmpMemInstLen = 2, 26 | ImpDescSectionChara = SECH_READ | SECH_WRITE | SECH_ALIGN4, 27 | ImpThunkSectionChara = SECH_READ | SECH_WRITE | SECH_ALIGN4, 28 | ImpLookupSectionChara = SECH_READ | SECH_WRITE | SECH_ALIGN2, 29 | ImpDllNameSectionChara = SECH_READ | SECH_WRITE | SECH_ALIGN2, 30 | ImpCallStubSectionChara = SECH_READ | SECH_CODE | SECH_EXEC | SECH_ALIGN2 31 | }; 32 | typedef DWORD32 UIntPtr; 33 | 34 | static UIntPtr OrdinalFlag; 35 | static BYTE JmpMemInst[2]; 36 | 37 | enum { PtrReloc = VARelocate32, 38 | RvaReloc = RVARelocate 39 | }; 40 | 41 | static ICoffFactory* GetCoffFactory() { 42 | return GetX86CoffFactory(); 43 | } 44 | }; 45 | BYTE ArchTraits::JmpMemInst[2] = {0xff, 0x25}; 46 | ArchTraits::UIntPtr ArchTraits::OrdinalFlag = IMAGE_ORDINAL_FLAG32; 47 | 48 | template<> 49 | struct ArchTraits 50 | { 51 | enum { JmpMemInstLen = 2, 52 | ImpDescSectionChara = SECH_READ | SECH_WRITE, 53 | ImpThunkSectionChara = SECH_READ | SECH_WRITE, 54 | ImpLookupSectionChara = SECH_READ | SECH_WRITE, 55 | ImpDllNameSectionChara = SECH_READ | SECH_WRITE, 56 | ImpCallStubSectionChara = SECH_READ | SECH_CODE | SECH_EXEC 57 | }; 58 | typedef DWORD64 UIntPtr; 59 | 60 | static UIntPtr OrdinalFlag; 61 | static BYTE JmpMemInst[2]; 62 | 63 | enum { PtrReloc = VARelocate64, 64 | RvaReloc = RVARelocate 65 | }; 66 | 67 | static ICoffFactory* GetCoffFactory() { 68 | return GetX64CoffFactory(); 69 | } 70 | }; 71 | BYTE ArchTraits::JmpMemInst[2] = {0xff, 0x25}; 72 | ArchTraits::UIntPtr ArchTraits::OrdinalFlag = IMAGE_ORDINAL_FLAG64; 73 | 74 | template 75 | class CImpSectionBuilder : public IImpSectionBuilder { 76 | ICoffFactory* cf; 77 | 78 | CImpSectionBuilder() { 79 | cf = ArchTraits::GetCoffFactory(); 80 | } 81 | 82 | class TmpStr { 83 | LPSTR m_str; 84 | public: 85 | TmpStr() { 86 | m_str = 0; 87 | } 88 | TmpStr(TmpStr& s) { 89 | m_str = 0; 90 | *this = s; 91 | } 92 | TmpStr(LPCSTR s) { 93 | m_str = 0; 94 | *this = s; 95 | } 96 | void Clear() { 97 | if (m_str != 0) 98 | delete[] m_str; 99 | m_str = 0; 100 | } 101 | ~TmpStr() { 102 | Clear(); 103 | } 104 | TmpStr& operator = (TmpStr& s) { 105 | if (this == &s) return *this; 106 | Clear(); 107 | m_str = s.m_str; 108 | s.m_str = 0; 109 | return *this; 110 | } 111 | TmpStr& operator = (LPCSTR s) { 112 | Clear(); 113 | int len = lstrlenA(s); 114 | m_str = new char[len + 1]; 115 | std::copy(s, s + len + 1, m_str); 116 | return *this; 117 | } 118 | operator LPCSTR () const { 119 | return m_str; 120 | } 121 | }; 122 | 123 | TmpStr BuildImpDescSymbolName(LPCSTR szDllName) 124 | { 125 | std::string r; 126 | r += "__IMPORT_DESCRITPOR_"; 127 | r += szDllName; 128 | return TmpStr(r.c_str()); 129 | } 130 | 131 | TmpStr BuildNullThunkName(LPCSTR szDllName) 132 | { 133 | std::string r; 134 | r += '\x7f'; 135 | r += szDllName; 136 | r += "_NULL_THUNK_DATA"; 137 | return TmpStr(r.c_str()); 138 | } 139 | public: 140 | ICoffFactory* GetCoffFactory() 141 | { 142 | return cf; 143 | } 144 | 145 | int GetPtrSize() 146 | { 147 | return sizeof(ArchTraits::UIntPtr); 148 | } 149 | 150 | void WINAPI BuildImportDescriptor(LPCSTR szDllName, ICoffBuilder* cb) 151 | { 152 | IMAGE_IMPORT_DESCRIPTOR iid; 153 | ZeroMemory(&iid, sizeof(iid)); 154 | 155 | ISectionBuilder* idSection = cf->CreateSectionBuilder(); 156 | cb->AppendSection(idSection); 157 | 158 | idSection->SetName(".idata$2"); 159 | idSection->SetCharacteristics( ArchTraits::ImpDescSectionChara ); 160 | 161 | IRelocatableVar* relVar[3]; 162 | int i; 163 | for(i = 0; i < 3; ++i) 164 | relVar[i] = cf->CreateRelocatableVar(); 165 | relVar[0]->Set(".idata$4", idSection, OFFSET(IMAGE_IMPORT_DESCRIPTOR, OriginalFirstThunk), GetPtrSize(), ArchTraits::RvaReloc); 166 | relVar[1]->Set(".idata$6", idSection, OFFSET(IMAGE_IMPORT_DESCRIPTOR, Name), 0, ArchTraits::RvaReloc); 167 | relVar[2]->Set(".idata$5", idSection, OFFSET(IMAGE_IMPORT_DESCRIPTOR, FirstThunk), GetPtrSize(), ArchTraits::RvaReloc); 168 | 169 | idSection->AppendData((LPBYTE)&iid, sizeof(iid), relVar, 3); 170 | 171 | ISectionBuilder* dllnameSection = cf->CreateSectionBuilder(); 172 | cb->AppendSection(dllnameSection); 173 | 174 | dllnameSection->SetName(".idata$6"); 175 | dllnameSection->SetCharacteristics( ArchTraits::ImpLookupSectionChara ); 176 | 177 | int dllnameLen = lstrlenA(szDllName) + 1; 178 | dllnameSection->AppendData((PBYTE)szDllName, dllnameLen, 0, 0); 179 | 180 | DWORD schara = idSection->GetRawCharacteristic(SECH_READ | SECH_WRITE); 181 | 182 | cb->GetSymbolTableBuilder()->AddSymbol(idSection, 0, BuildImpDescSymbolName(szDllName), SYST_EXTERN, 0); 183 | cb->GetSymbolTableBuilder()->AddSymbol(idSection, schara, ".idata$2", SYST_SECTION, 0); 184 | cb->GetSymbolTableBuilder()->AddSymbol(dllnameSection, 0, ".idata$6", SYST_STATIC, 0); 185 | cb->GetSymbolTableBuilder()->AddSymbol(0, schara, ".idata$4", SYST_SECTION, 0); 186 | cb->GetSymbolTableBuilder()->AddSymbol(0, schara, ".idata$5", SYST_SECTION, 0); 187 | cb->GetSymbolTableBuilder()->AddSymbol(0, 0, "__NULL_IMPORT_DESCRIPTOR", SYST_EXTERN, 0); 188 | cb->GetSymbolTableBuilder()->AddSymbol(0, 0, BuildNullThunkName(szDllName), SYST_EXTERN, 0); 189 | } 190 | 191 | void WINAPI BuildImportThunk(LPCSTR szDllName, LPCSTR szImpName, LPCSTR szFuncName, LPCSTR szDllExpName, WORD nDllExpOrdinal, ICoffBuilder* cb) 192 | { 193 | std::string lookupSymbol; 194 | 195 | //---------------------------------------------- 196 | //call stub 197 | if (szFuncName) { 198 | ISectionBuilder* callstubSec = cf->CreateSectionBuilder(); 199 | cb->AppendSection(callstubSec); 200 | callstubSec->SetName(".text"); 201 | callstubSec->SetCharacteristics( ArchTraits::ImpCallStubSectionChara | SECH_COMDAT ); 202 | 203 | callstubSec->AppendData(ArchTraits::JmpMemInst, sizeof(ArchTraits::JmpMemInst), 0, 0); 204 | 205 | ArchTraits::UIntPtr zeroptr = 0; 206 | IRelocatableVar* funcptr = cf->CreateRelocatableVar(); 207 | funcptr->Set(szImpName, callstubSec, 0, sizeof(zeroptr), ArchTraits::PtrReloc); 208 | callstubSec->AppendData((PBYTE)&zeroptr, sizeof(zeroptr), &funcptr, 1); 209 | 210 | cb->GetSymbolTableBuilder()->AddSymbol(callstubSec, 0, ".text", SYST_STATIC, 1); 211 | ISectionAuxSymbol* auxsym = callstubSec->CreateAuxSymbol(0, SECO_NODUPLICATE); 212 | cb->GetSymbolTableBuilder()->AddAuxData(auxsym); 213 | auxsym->Dispose(); 214 | 215 | cb->GetSymbolTableBuilder()->AddSymbol(callstubSec, 0, szFuncName, SYST_FUNCTION, 0); 216 | } 217 | 218 | //---------------------------------------------- 219 | //thunk, original thunk 220 | static LPCSTR secName[] = {".idata$5", ".idata$4"}; 221 | 222 | //thunk and original thunk, filled with lookup or ordinal 223 | int i; 224 | ISectionBuilder *id5, *id4; 225 | for(i = 0; i < 2; ++i) { //0 = OriginalThunk, 1 = Thunk 226 | ISectionBuilder* thunkSection = cf->CreateSectionBuilder(); 227 | if (i == 0) 228 | id5 = thunkSection; 229 | else 230 | id4 = thunkSection; 231 | 232 | cb->AppendSection(thunkSection); 233 | thunkSection->SetName(secName[i]); 234 | thunkSection->SetCharacteristics( ArchTraits::ImpThunkSectionChara | SECH_COMDAT ); 235 | 236 | typename ArchTraits::UIntPtr val; 237 | if (szDllExpName != 0) { 238 | //by name 239 | val = 0; 240 | IRelocatableVar* rel = cf->CreateRelocatableVar(); 241 | rel->Set(".idata$6", thunkSection, 0, 0, ArchTraits::RvaReloc); 242 | thunkSection->AppendData((PBYTE)&val, sizeof(val), &rel, 1); 243 | } else { 244 | //by ordinal 245 | val = ArchTraits::OrdinalFlag | nDllExpOrdinal; 246 | thunkSection->AppendData((PBYTE)&val, sizeof(val), 0, 0); 247 | } 248 | 249 | if (i == 0) { // .idata$5, thunk 250 | cb->GetSymbolTableBuilder()->AddSymbol(thunkSection, 0, secName[i], SYST_STATIC, 1); 251 | ISectionAuxSymbol* secauxsym = thunkSection->CreateAuxSymbol(0, SECO_NODUPLICATE); 252 | cb->GetSymbolTableBuilder()->AddAuxData(secauxsym); 253 | secauxsym->Dispose(); 254 | cb->GetSymbolTableBuilder()->AddSymbol(thunkSection, 0, szImpName, SYST_EXTERN, 0); 255 | } else { //.idata$4 256 | cb->GetSymbolTableBuilder()->AddSymbol(thunkSection, 0, secName[i], SYST_STATIC, 1); 257 | ISectionAuxSymbol* secauxsym = thunkSection->CreateAuxSymbol(id5, SECO_ASSOCIATIVE); 258 | cb->GetSymbolTableBuilder()->AddAuxData(secauxsym); 259 | secauxsym->Dispose(); 260 | } 261 | } 262 | 263 | //---------------------------------------------- 264 | //import by name 265 | if (szDllExpName != 0) { 266 | ISectionBuilder* impSection = cf->CreateSectionBuilder(); 267 | cb->AppendSection(impSection); 268 | 269 | impSection->SetName(".idata$6"); 270 | impSection->SetCharacteristics( ArchTraits::ImpLookupSectionChara | SECH_COMDAT ); 271 | 272 | WORD hint = nDllExpOrdinal; 273 | impSection->AppendData((LPBYTE)&hint, sizeof(hint), 0, 0); 274 | 275 | int nameLen = lstrlenA(szDllExpName) + 1; 276 | impSection->AppendData((LPBYTE)szDllExpName, nameLen, 0, 0); 277 | 278 | cb->GetSymbolTableBuilder()->AddSymbol(impSection, 0, ".idata$6", SYST_STATIC, 1); 279 | ISectionAuxSymbol* auxsym = impSection->CreateAuxSymbol(id5, SECO_ASSOCIATIVE); 280 | cb->GetSymbolTableBuilder()->AddAuxData(auxsym); 281 | auxsym->Dispose(); 282 | } 283 | 284 | //cb->GetSymbolTableBuilder()->AddSymbol(0, sizeof(ArchTraits::UIntPtr), "NullThunk", SYST_EXTERN, 0); 285 | //cb->GetSymbolTableBuilder()->AddSymbol(0, sizeof(ArchTraits::UIntPtr), "NullOriginalThunk", SYST_EXTERN, 0); 286 | cb->GetSymbolTableBuilder()->AddSymbol(0, 0, BuildImpDescSymbolName(szDllName), SYST_EXTERN, 0); 287 | } 288 | 289 | void WINAPI BuildImportByNameThunk(LPCSTR szDllName, LPCSTR szImpName, LPCSTR szFuncName, LPCSTR szDllExpName, ICoffBuilder* cb) 290 | { 291 | BuildImportThunk(szDllName, szImpName, szFuncName, szDllExpName, 0, cb); 292 | } 293 | 294 | void WINAPI BuildImportByOrdinalThunk(LPCSTR szDllName, LPCSTR szImpName, LPCSTR szFuncName, WORD nDllExpOrdinal, ICoffBuilder* cb) 295 | { 296 | BuildImportThunk(szDllName, szImpName, szFuncName, 0, nDllExpOrdinal, cb); 297 | } 298 | 299 | void WINAPI BuildNullThunk(LPCSTR szDllName, ICoffBuilder* cb) 300 | { 301 | ISectionBuilder* ft = cf->CreateSectionBuilder(); 302 | ISectionBuilder* oft = cf->CreateSectionBuilder(); 303 | cb->AppendSection(ft); 304 | cb->AppendSection(oft); 305 | 306 | ft->SetName(".idata$5"); 307 | ft->SetCharacteristics( ArchTraits::ImpThunkSectionChara ); 308 | oft->SetName(".idata$4"); 309 | oft->SetCharacteristics( ArchTraits::ImpThunkSectionChara ); 310 | 311 | typename ArchTraits::UIntPtr zeroptr = 0; 312 | 313 | ft->AppendData((PBYTE)&zeroptr, sizeof(zeroptr), 0, 0); 314 | oft->AppendData((PBYTE)&zeroptr, sizeof(zeroptr), 0, 0); 315 | 316 | cb->GetSymbolTableBuilder()->AddSymbol(ft, 0, BuildNullThunkName(szDllName), SYST_EXTERN, 0); 317 | //cb->GetSymbolTableBuilder()->AddSymbol(oft, 0, "NullOriginalThunk", SYST_EXTERN, 0); 318 | } 319 | 320 | void WINAPI BuildNullDescriptor(ICoffBuilder* cb) 321 | { 322 | IMAGE_IMPORT_DESCRIPTOR iid; 323 | ZeroMemory(&iid, sizeof(iid)); 324 | 325 | ISectionBuilder* nullDesc = cf->CreateSectionBuilder(); 326 | cb->AppendSection(nullDesc); 327 | nullDesc->SetName(".idata$3"); 328 | nullDesc->SetCharacteristics( ArchTraits::ImpDescSectionChara ); 329 | nullDesc->AppendData((PBYTE)&iid, sizeof(iid), 0, 0); 330 | 331 | cb->GetSymbolTableBuilder()->AddSymbol(nullDesc, 0, "__NULL_IMPORT_DESCRIPTOR", SYST_EXTERN, 0); 332 | } 333 | 334 | static CImpSectionBuilder Instance; 335 | }; 336 | 337 | template 338 | CImpSectionBuilder CImpSectionBuilder::Instance; 339 | 340 | extern "C" { 341 | IImpSectionBuilder* WINAPI GetX86ImpSectionBuilder() { return &CImpSectionBuilder::Instance; } 342 | IImpSectionBuilder* WINAPI GetX64ImpSectionBuilder() { return &CImpSectionBuilder::Instance; } 343 | } 344 | }; 345 | -------------------------------------------------------------------------------- /CoffGen/coffImpl.cpp: -------------------------------------------------------------------------------- 1 | #include "coffinterfaces.h" 2 | #include "cofffactory.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Sora 9 | { 10 | 11 | typedef struct {} ArchX86; 12 | typedef struct {} ArchX64; 13 | typedef struct {} ArchIA64; 14 | 15 | template 16 | struct ArchTraits; 17 | 18 | template<> 19 | struct ArchTraits 20 | { 21 | typedef DWORD32 UIntPtr; 22 | enum { 23 | ArchSign = IMAGE_FILE_MACHINE_I386, 24 | RelRVA = IMAGE_REL_I386_DIR32NB, 25 | RelVA = IMAGE_REL_I386_DIR32, 26 | RelVA64 = 0 27 | }; 28 | static BYTE PadInst; 29 | static BYTE PadData; 30 | }; 31 | BYTE ArchTraits::PadInst = 0x90; 32 | BYTE ArchTraits::PadData = 0; 33 | 34 | template<> 35 | struct ArchTraits 36 | { 37 | typedef DWORD64 UIntPtr; 38 | enum { 39 | ArchSign = IMAGE_FILE_MACHINE_AMD64, 40 | RelRVA = IMAGE_REL_AMD64_ADDR32NB, 41 | RelVA = IMAGE_REL_AMD64_ADDR32, 42 | RelVA64 = IMAGE_REL_AMD64_ADDR64 43 | }; 44 | static BYTE PadInst; 45 | static BYTE PadData; 46 | }; 47 | BYTE ArchTraits::PadInst = 0x90; 48 | BYTE ArchTraits::PadData = 0x90; 49 | 50 | template<> 51 | struct ArchTraits 52 | { 53 | typedef DWORD64 UIntPtr; 54 | enum { 55 | ArchSign = IMAGE_FILE_MACHINE_IA64, 56 | RelRVA = IMAGE_REL_IA64_DIR32NB, 57 | RelVA = IMAGE_REL_IA64_DIR32, 58 | RelVA64 = IMAGE_REL_IA64_DIR64 59 | }; 60 | static BYTE PadInst; 61 | static BYTE PadData; 62 | }; 63 | BYTE ArchTraits::PadInst = 0x00; 64 | BYTE ArchTraits::PadData = 0x00; 65 | 66 | template 67 | class CDispose : public T { 68 | protected: 69 | virtual ~CDispose() = 0 { } 70 | public: 71 | void WINAPI Dispose() { 72 | delete this; 73 | } 74 | }; 75 | 76 | template 77 | class CCoffFactory : public ICoffFactory 78 | { 79 | public: 80 | ICoffBuilder* WINAPI CreateCoffBuilder() { return new CCoffBuilder(); } 81 | ISectionBuilder* WINAPI CreateSectionBuilder() { return new CSectionBuilder(); } 82 | ISymbolTableBuilder* WINAPI CreateSymbolTableBuilder() { return new CSymbolTableBuilder(); } 83 | IStringTableBuilder* WINAPI CreateStringTableBuilder() { return new CStringTableBuilder(); } 84 | IRelocatableVar* WINAPI CreateRelocatableVar() { return new CRelocatableVar(); } 85 | IRelocationTableBuilder* WINAPI CreateRelocationTableBuilder() { return new CRelocationTableBuilder(); } 86 | 87 | static CCoffFactory Instance; 88 | }; 89 | 90 | 91 | template CCoffFactory CCoffFactory::Instance; 92 | 93 | extern "C" { 94 | ICoffFactory* WINAPI GetX86CoffFactory() { return &CCoffFactory::Instance; } 95 | ICoffFactory* WINAPI GetX64CoffFactory() { return &CCoffFactory::Instance; } 96 | ICoffFactory* WINAPI GetIA64CoffFactory() { return &CCoffFactory::Instance; } 97 | }; 98 | 99 | template 100 | class CCoffBuilder : public CDispose 101 | { 102 | typedef std::vector Sections; 103 | Sections m_sections; 104 | 105 | ISymbolTableBuilder* m_symbolTable; 106 | IStringTableBuilder* m_stringTable; 107 | public: 108 | int WINAPI AppendSection(ISectionBuilder* p) 109 | { 110 | m_sections.push_back(p); 111 | p->SetSectionIndex(m_sections.size()); //1-based 112 | 113 | return m_sections.size(); 114 | } 115 | 116 | CCoffBuilder() 117 | { 118 | m_stringTable = CCoffFactory::Instance.CreateStringTableBuilder(); 119 | m_symbolTable = CCoffFactory::Instance.CreateSymbolTableBuilder(); 120 | m_symbolTable->SetStringTable(m_stringTable); 121 | } 122 | 123 | WINAPI ~CCoffBuilder() 124 | { 125 | Sections::iterator i, iend; 126 | for(i = m_sections.begin(), iend = m_sections.end(); 127 | i != iend; ++i) 128 | { 129 | (*i)->Dispose(); 130 | } 131 | 132 | m_symbolTable->Dispose(); 133 | m_stringTable->Dispose(); 134 | } 135 | 136 | IStringTableBuilder* WINAPI GetStringTableBuilder() 137 | { 138 | return m_stringTable; 139 | } 140 | 141 | ISymbolTableBuilder* WINAPI GetSymbolTableBuilder() 142 | { 143 | return m_symbolTable; 144 | } 145 | 146 | void WINAPI PushRelocs() 147 | { 148 | Sections::iterator i, iend; 149 | for(i = m_sections.begin(), iend = m_sections.end(); 150 | i != iend; ++i) 151 | { 152 | (*i)->PushRelocs(m_symbolTable); 153 | } 154 | } 155 | 156 | int WINAPI GetDataLength() 157 | { 158 | Sections::iterator i, iend; 159 | int len = 0; 160 | 161 | //header 162 | len += sizeof(IMAGE_FILE_HEADER); 163 | 164 | //sections 165 | for(i = m_sections.begin(), iend = m_sections.end(); 166 | i != iend; ++i) 167 | { 168 | len += (*i)->GetHeaderLength(); 169 | len += (*i)->GetDataLength(); 170 | } 171 | 172 | //symbols 173 | len += m_symbolTable->GetDataLength(); 174 | 175 | //string table 176 | len += m_stringTable->GetDataLength(); 177 | 178 | return len; 179 | } 180 | 181 | void WINAPI GetRawData(PBYTE p) 182 | { 183 | PBYTE sp = p; 184 | 185 | int len = 0; 186 | 187 | //header 188 | IMAGE_FILE_HEADER* coffHeader = (IMAGE_FILE_HEADER*) p; 189 | ZeroMemory(coffHeader, sizeof(*coffHeader)); 190 | coffHeader->Machine = ArchTraits::ArchSign; 191 | coffHeader->NumberOfSections = m_sections.size(); 192 | coffHeader->PointerToSymbolTable = 0; //will assign value just before write symbol table 193 | coffHeader->NumberOfSymbols = m_symbolTable->GetSymbolCount(); 194 | coffHeader->SizeOfOptionalHeader = 0; 195 | coffHeader->Characteristics = 0; 196 | p += sizeof(*coffHeader); 197 | 198 | //sections 199 | Sections::iterator i, iend; 200 | 201 | int secDataBase = p - sp; //current section's offset in file 202 | //skip section headers 203 | for(i = m_sections.begin(), iend = m_sections.end(); 204 | i != iend; ++i) 205 | { 206 | secDataBase += (*i)->GetHeaderLength(); 207 | } 208 | 209 | for(i = m_sections.begin(), iend = m_sections.end(); 210 | i != iend; ++i) 211 | { 212 | (*i)->GetRawHeader(p, secDataBase); 213 | p += (*i)->GetHeaderLength(); 214 | 215 | secDataBase += (*i)->GetDataLength(); 216 | } 217 | 218 | for(i = m_sections.begin(), iend = m_sections.end(); 219 | i != iend; ++i) 220 | { 221 | (*i)->GetRawData(p); 222 | p += (*i)->GetDataLength(); 223 | } 224 | 225 | coffHeader->PointerToSymbolTable = (p - sp); 226 | 227 | //symbols 228 | m_symbolTable->GetRawData(p); 229 | p += m_symbolTable->GetDataLength(); 230 | 231 | //string table 232 | m_stringTable->GetRawData(p); 233 | p += m_stringTable->GetDataLength(); 234 | } 235 | }; 236 | 237 | template 238 | class CSectionBuilder : public CDispose 239 | { 240 | DWORD m_chara; 241 | IRelocationTableBuilder* m_relocTable; 242 | 243 | int m_secIndex; 244 | 245 | std::vector m_buf; 246 | CHAR m_name[IMAGE_SIZEOF_SHORT_NAME]; 247 | 248 | DWORD _outArg; 249 | 250 | int AdjustAlign(DWORD* adjustedSize, DWORD* padSize) 251 | { 252 | int as, ps, ras, align; 253 | ras = m_buf.size(); 254 | 255 | if (m_chara & SECH_ALIGN1) align = 1; 256 | else if (m_chara & SECH_ALIGN2) align = 2; 257 | else if (m_chara & SECH_ALIGN4) align = 4; 258 | else if (m_chara & SECH_ALIGN8) align = 8; 259 | else if (m_chara & SECH_ALIGN16) align = 16; 260 | else if (m_chara & SECH_ALIGN32) align = 32; 261 | else if (m_chara & SECH_ALIGN64) align = 64; 262 | else align = 1; 263 | 264 | if (ras % align == 0) as = ras; 265 | else as = (ras / align + 1) * align; 266 | 267 | ps = as - ras; 268 | 269 | if (adjustedSize == &_outArg) return as; 270 | if (padSize == &_outArg) return ps; 271 | 272 | *adjustedSize = as; 273 | *padSize = ps; 274 | 275 | return 0; 276 | } 277 | 278 | public: 279 | CSectionBuilder() 280 | { 281 | m_relocTable = CCoffFactory::Instance.CreateRelocationTableBuilder(); 282 | } 283 | 284 | WINAPI ~CSectionBuilder() 285 | { 286 | m_relocTable->Dispose(); 287 | } 288 | 289 | void WINAPI SetName(LPCSTR p) 290 | { 291 | int pl = lstrlenA(p); 292 | if (pl >= IMAGE_SIZEOF_SHORT_NAME) //no long name support 293 | std::copy(p, p + IMAGE_SIZEOF_SHORT_NAME, m_name); 294 | else 295 | lstrcpyA(m_name, p); 296 | } 297 | 298 | void WINAPI SetSectionIndex(int secIndex) 299 | { 300 | m_secIndex = secIndex; 301 | } 302 | 303 | int WINAPI GetSectionIndex() 304 | { 305 | return m_secIndex; 306 | } 307 | 308 | void WINAPI AppendData(LPCBYTE pBuf, int len, IRelocatableVar* aReloc[], int relocCount) 309 | { 310 | int beginPos = m_buf.size(); 311 | m_buf.insert(m_buf.end(), pBuf, pBuf + len); 312 | for(int i = 0; i < relocCount; ++i) { 313 | aReloc[i]->Offset(beginPos); 314 | m_relocTable->AppendRelocationItem(aReloc[i]); 315 | } 316 | } 317 | 318 | void WINAPI SetCharacteristics(DWORD p) 319 | { 320 | m_chara = p; 321 | } 322 | 323 | int WINAPI GetHeaderLength() 324 | { 325 | return sizeof(IMAGE_SECTION_HEADER); 326 | } 327 | 328 | DWORD WINAPI GetRawCharacteristic(DWORD c) 329 | { 330 | return 331 | (c & SECH_CODE ? IMAGE_SCN_CNT_CODE : 0) 332 | | (c & SECH_READ ? IMAGE_SCN_MEM_READ : 0) 333 | | (c & SECH_WRITE ? IMAGE_SCN_MEM_WRITE : 0) 334 | | (c & SECH_EXEC ? IMAGE_SCN_MEM_EXECUTE : 0) 335 | | (c & SECH_UNINIT ? IMAGE_SCN_CNT_UNINITIALIZED_DATA : (c & SECH_CODE ? 0 : IMAGE_SCN_CNT_INITIALIZED_DATA)) 336 | | (c & SECH_ALIGN1 ? IMAGE_SCN_ALIGN_1BYTES : 0) 337 | | (c & SECH_ALIGN2 ? IMAGE_SCN_ALIGN_2BYTES : 0) 338 | | (c & SECH_ALIGN4 ? IMAGE_SCN_ALIGN_4BYTES : 0) 339 | | (c & SECH_ALIGN8 ? IMAGE_SCN_ALIGN_8BYTES : 0) 340 | | (c & SECH_ALIGN16 ? IMAGE_SCN_ALIGN_16BYTES : 0) 341 | | (c & SECH_ALIGN32 ? IMAGE_SCN_ALIGN_32BYTES : 0) 342 | | (c & SECH_ALIGN64 ? IMAGE_SCN_ALIGN_64BYTES : 0) 343 | | (c & SECH_COMDAT ? IMAGE_SCN_LNK_COMDAT : 0); 344 | } 345 | 346 | DWORD WINAPI GetRawCharacteristic() 347 | { 348 | return GetRawCharacteristic(m_chara); 349 | } 350 | 351 | void WINAPI GetRawHeader(PBYTE p, DWORD rawOffset) 352 | { 353 | IMAGE_SECTION_HEADER* pHeader = (IMAGE_SECTION_HEADER*) p; 354 | ZeroMemory(pHeader, sizeof(*pHeader)); 355 | std::copy(m_name, m_name+IMAGE_SIZEOF_SHORT_NAME, (LPSTR)pHeader->Name); 356 | pHeader->Misc.VirtualSize = 0; //must be 0 for obj 357 | pHeader->VirtualAddress = 0; 358 | pHeader->SizeOfRawData = AdjustAlign(&_outArg, 0); 359 | pHeader->PointerToRawData = rawOffset; 360 | if (m_relocTable->GetCount() == 0) 361 | pHeader->PointerToRelocations = 0; 362 | else 363 | pHeader->PointerToRelocations = rawOffset + AdjustAlign(&_outArg, 0); 364 | pHeader->NumberOfRelocations = m_relocTable->GetCount(); 365 | pHeader->NumberOfLinenumbers = 0; //must be 0 366 | pHeader->Characteristics = GetRawCharacteristic(m_chara); 367 | } 368 | 369 | int WINAPI GetDataLength() 370 | { 371 | int r = m_buf.size() + m_relocTable->GetDataLength(); 372 | r += AdjustAlign(0, &_outArg); 373 | return r; 374 | } 375 | 376 | void WINAPI GetRawData(PBYTE p) 377 | { 378 | std::copy(m_buf.begin(), m_buf.end(), p); 379 | p += m_buf.size(); 380 | 381 | BYTE padbyte = 0; 382 | if (m_chara & SECH_CODE) 383 | padbyte = ArchTraits::PadInst; 384 | else 385 | padbyte = ArchTraits::PadData; 386 | 387 | int padsize = AdjustAlign(0, &_outArg); 388 | while(padsize --> 0) { 389 | *p = padbyte; 390 | ++p; 391 | } 392 | 393 | m_relocTable->GetRawData(p); 394 | } 395 | 396 | void WINAPI PushRelocs(ISymbolTableBuilder* table) 397 | { 398 | //std::string tname(m_name, m_name + 8); 399 | //table->AddSymbol(this, 0, tname.c_str(), SYST_STATIC, 0); 400 | m_relocTable->PushToSymbolTable(table); 401 | } 402 | 403 | class SecAuxSym : public ISectionAuxSymbol 404 | { 405 | public: 406 | IMAGE_AUX_SYMBOL u; 407 | 408 | SecAuxSym() 409 | { 410 | ZeroMemory(&u, sizeof(u)); 411 | } 412 | 413 | int WINAPI GetDataLength() 414 | { 415 | return sizeof(u); 416 | } 417 | 418 | void WINAPI GetRawData(PBYTE p) 419 | { 420 | *(PIMAGE_AUX_SYMBOL)p = u; 421 | } 422 | 423 | void WINAPI Dispose() 424 | { 425 | delete this; 426 | } 427 | }; 428 | 429 | ISectionAuxSymbol* WINAPI CreateAuxSymbol(ISectionBuilder* associatedSection, SectionComdat selection) 430 | { 431 | SecAuxSym* r = new SecAuxSym(); 432 | r->u.Section.Length = GetDataLength(); 433 | r->u.Section.NumberOfRelocations = m_relocTable->GetCount(); 434 | r->u.Section.NumberOfLinenumbers = 0; 435 | r->u.Section.CheckSum = 0; 436 | r->u.Section.Number = associatedSection == 0 ? 0 : associatedSection->GetSectionIndex(); 437 | 438 | BYTE& val = r->u.Section.Selection; 439 | switch(selection) { 440 | case SECO_NODUPLICATE: 441 | val = IMAGE_COMDAT_SELECT_NODUPLICATES; 442 | break; 443 | case SECO_ASSOCIATIVE: 444 | val = IMAGE_COMDAT_SELECT_ASSOCIATIVE; 445 | break; 446 | case SECO_SELECTANY: 447 | val = IMAGE_COMDAT_SELECT_ANY; 448 | break; 449 | case SECO_SELECTLARGEST: 450 | val = IMAGE_COMDAT_SELECT_LARGEST; 451 | break; 452 | case SECO_SELECTSAME: 453 | val = IMAGE_COMDAT_SELECT_EXACT_MATCH; 454 | break; 455 | case SECO_SELECTSAMESIZE: 456 | val = IMAGE_COMDAT_SELECT_SAME_SIZE; 457 | break; 458 | } 459 | 460 | return r; 461 | } 462 | }; 463 | 464 | template 465 | class CStringTableBuilder : public CDispose 466 | { 467 | std::vector m_buf; 468 | public: 469 | int WINAPI AppendString(LPCSTR p) 470 | { 471 | int sl = lstrlenA(p); 472 | int r = m_buf.size() + sizeof(DWORD); 473 | m_buf.insert(m_buf.end(), p, p + sl + 1); 474 | return r; 475 | } 476 | 477 | LPCSTR WINAPI GetString(int offset) 478 | { 479 | return &m_buf[offset - sizeof(DWORD)]; 480 | } 481 | 482 | int WINAPI GetDataLength() 483 | { 484 | return m_buf.size() + sizeof(DWORD); 485 | } 486 | 487 | void WINAPI GetRawData(PBYTE p) 488 | { 489 | DWORD* pLen = (DWORD*) p; 490 | *pLen = GetDataLength(); 491 | p += sizeof(*pLen); 492 | 493 | std::copy(m_buf.begin(), m_buf.end(), p); 494 | } 495 | }; 496 | 497 | template 498 | class CSymbolTableBuilder : public CDispose 499 | { 500 | std::vector m_buf; 501 | IStringTableBuilder* m_strTable; 502 | public: 503 | void WINAPI SetStringTable(IStringTableBuilder* t) 504 | { 505 | m_strTable = t; 506 | } 507 | 508 | int WINAPI FindSymbol(LPCSTR name) 509 | { 510 | int cnt = m_buf.size(); 511 | int i; 512 | for(i = 0; i < cnt; ++i) { 513 | IMAGE_SYMBOL& x = m_buf[i]; 514 | LPCSTR cn = m_strTable->GetString(x.N.Name.Long); 515 | if (lstrcmpA(cn, name) == 0) 516 | return i; 517 | 518 | i += x.NumberOfAuxSymbols; 519 | } 520 | return -1; 521 | } 522 | 523 | int WINAPI AddSymbol(ISectionBuilder* section, int offset, LPCSTR name, StorageType stype, int auxCnt) 524 | { 525 | int ind = FindSymbol(name); 526 | if (ind != -1) 527 | return ind; 528 | 529 | IMAGE_SYMBOL s; 530 | ZeroMemory(&s, sizeof(s)); 531 | s.N.Name.Short = 0; 532 | s.N.Name.Long = m_strTable->AppendString(name); 533 | s.Value = offset; 534 | s.SectionNumber = section != 0 ? section->GetSectionIndex() : 0; 535 | s.Type = ((stype == SYST_FUNCTION || stype == SYST_STATICFUNCTION) ? (IMAGE_SYM_DTYPE_FUNCTION << 4) | 0 : 0); 536 | 537 | switch(stype) { 538 | case SYST_STATIC: s.StorageClass = IMAGE_SYM_CLASS_STATIC; break; 539 | case SYST_EXTERN: s.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; break; 540 | case SYST_FUNCTION: s.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; break; 541 | case SYST_STATICFUNCTION: s.StorageClass = IMAGE_SYM_CLASS_STATIC; break; 542 | case SYST_SECTION: s.StorageClass = IMAGE_SYM_CLASS_SECTION; break; 543 | } 544 | 545 | s.NumberOfAuxSymbols = auxCnt; //currently not supported 546 | 547 | m_buf.push_back(s); 548 | 549 | return m_buf.size() - 1; 550 | } 551 | 552 | int WINAPI AddAuxData(IHasRawData* d) 553 | { 554 | IMAGE_SYMBOL s; 555 | if (d->GetDataLength() == sizeof(s)) { 556 | d->GetRawData((PBYTE)&s); 557 | m_buf.push_back(s); 558 | return m_buf.size() - 1; 559 | } else 560 | return -1; 561 | } 562 | 563 | int WINAPI GetSymbolCount() 564 | { 565 | return m_buf.size(); 566 | } 567 | 568 | int WINAPI GetDataLength() 569 | { 570 | return sizeof(IMAGE_SYMBOL) * GetSymbolCount(); 571 | } 572 | 573 | void WINAPI GetRawData(PBYTE p) 574 | { 575 | IMAGE_SYMBOL* pData = (IMAGE_SYMBOL*) p; 576 | std::copy(m_buf.begin(), m_buf.end(), pData); 577 | } 578 | 579 | class CSymbolStrings : public ISymbolStrings 580 | { 581 | public: 582 | int m_cnt; 583 | LPCSTR* m_str; 584 | 585 | ~CSymbolStrings() 586 | { 587 | if (m_str != 0) 588 | delete[] m_str; 589 | } 590 | 591 | void WINAPI Dispose() 592 | { 593 | delete this; 594 | } 595 | 596 | int WINAPI GetCount() 597 | { 598 | return m_cnt; 599 | } 600 | 601 | LPCSTR WINAPI GetString(int nIndex) 602 | { 603 | return m_str[nIndex]; 604 | } 605 | }; 606 | 607 | ISymbolStrings* GetPublicSymbolNames() 608 | { 609 | std::vector tmp; 610 | CSymbolStrings* r = new CSymbolStrings; 611 | 612 | int cnt = m_buf.size(); 613 | int i; 614 | for(i = 0; i < cnt; ++i) { 615 | IMAGE_SYMBOL& x = m_buf[i]; 616 | if (x.StorageClass == IMAGE_SYM_CLASS_EXTERNAL && x.SectionNumber > 0) { 617 | LPCSTR cn = m_strTable->GetString(x.N.Name.Long); 618 | tmp.push_back(cn); 619 | } 620 | 621 | i += x.NumberOfAuxSymbols; 622 | } 623 | 624 | r->m_cnt = tmp.size(); 625 | r->m_str = new LPCSTR[r->m_cnt]; 626 | std::copy(tmp.begin(), tmp.end(), r->m_str); 627 | return r; 628 | } 629 | }; 630 | 631 | template 632 | class CRelocatableVar : public CDispose 633 | { 634 | int m_val; 635 | std::string m_symbol; 636 | DWORD m_relocType; 637 | ISectionBuilder* m_section; 638 | int m_size; 639 | public: 640 | void WINAPI Offset(int offset) 641 | { 642 | m_val += offset; 643 | } 644 | 645 | void WINAPI Set(LPCSTR symbol, ISectionBuilder* section, DWORD val, int size, DWORD reloctype) 646 | { 647 | m_symbol = symbol; 648 | m_val = val; 649 | m_size = size; 650 | m_relocType = reloctype; 651 | m_section = section; 652 | } 653 | 654 | void WINAPI Get(LPCSTR* symbol, ISectionBuilder** section, DWORD* val, int* size, DWORD* reloctype) 655 | { 656 | *symbol = m_symbol.c_str(); 657 | *val = m_val; 658 | *size = m_size; 659 | *reloctype = m_relocType; 660 | *section = m_section; 661 | } 662 | }; 663 | 664 | template 665 | class CRelocationTableBuilder : public CDispose 666 | { 667 | typedef std::vector Relocs; 668 | Relocs m_relocs; 669 | std::vector m_buf; 670 | 671 | public: 672 | WINAPI ~CRelocationTableBuilder() 673 | { 674 | Relocs::iterator i, iend; 675 | for(i = m_relocs.begin(), iend = m_relocs.end(); 676 | i != iend; ++i) 677 | { 678 | (*i)->Dispose(); 679 | } 680 | } 681 | 682 | int WINAPI GetPtrLength() 683 | { 684 | return sizeof( ArchTraits::UIntPtr ); 685 | } 686 | 687 | int WINAPI GetCount() 688 | { 689 | return m_relocs.size(); 690 | } 691 | 692 | void WINAPI AppendRelocationItem(IRelocatableVar* p) 693 | { 694 | m_relocs.push_back(p); 695 | } 696 | 697 | void WINAPI PushToSymbolTable(ISymbolTableBuilder* table) 698 | { 699 | Relocs::iterator i, iend; 700 | for(i = m_relocs.begin(), iend = m_relocs.end(); 701 | i != iend; ++i) 702 | { 703 | ISectionBuilder* section; 704 | DWORD relocType; 705 | LPCSTR symbolName; 706 | DWORD val; 707 | int symbolValSize; 708 | 709 | (*i)->Get(&symbolName, §ion, &val, &symbolValSize, &relocType); 710 | 711 | IMAGE_RELOCATION r; 712 | ZeroMemory(&r, sizeof(r)); 713 | r.VirtualAddress = val; 714 | r.SymbolTableIndex = table->AddSymbol(0, symbolValSize, symbolName, SYST_EXTERN, 0); 715 | 716 | r.Type = 717 | (relocType == VARelocate32 ? ArchTraits::RelVA : 0) 718 | | (relocType == VARelocate64 ? ArchTraits::RelVA64 : 0) 719 | | (relocType == RVARelocate ? ArchTraits::RelRVA : 0); 720 | m_buf.push_back(r); 721 | } 722 | 723 | for (i = m_relocs.begin(), iend = m_relocs.end(); 724 | i != iend; ++i) 725 | { 726 | (*i)->Dispose(); 727 | } 728 | m_relocs.clear(); 729 | } 730 | 731 | int WINAPI GetDataLength() 732 | { 733 | return m_buf.size() * sizeof(IMAGE_RELOCATION); 734 | } 735 | 736 | void WINAPI GetRawData(PBYTE p) 737 | { 738 | IMAGE_RELOCATION* pData = (IMAGE_RELOCATION*) p; 739 | std::copy(m_buf.begin(), m_buf.end(), pData); 740 | } 741 | }; 742 | }; 743 | --------------------------------------------------------------------------------