├── .gitattributes ├── .gitignore ├── PELoader.sln ├── PELoader ├── PELoader.vcxproj ├── PELoader.vcxproj.filters ├── PELoader │ ├── PELoader.cpp │ └── PELoader.h └── main.cpp ├── README.md ├── Screenshot ├── 1.jpg ├── 2.jpg ├── 3.jpg └── 4.jpg └── TestDLL ├── ReadMe.txt ├── TestDLL.cpp ├── TestDLL.vcxproj ├── TestDLL.vcxproj.filters ├── dllmain.cpp ├── stdafx.cpp ├── stdafx.h └── targetver.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /PELoader.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.7 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PELoader", "PELoader\PELoader.vcxproj", "{02DB1BFF-93A4-4420-87D1-412FB902183E}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestDLL", "TestDLL\TestDLL.vcxproj", "{3D5AF455-8361-4BA9-AF90-BF59CEED51FB}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {02DB1BFF-93A4-4420-87D1-412FB902183E}.Debug|x64.ActiveCfg = Debug|x64 19 | {02DB1BFF-93A4-4420-87D1-412FB902183E}.Debug|x64.Build.0 = Debug|x64 20 | {02DB1BFF-93A4-4420-87D1-412FB902183E}.Debug|x86.ActiveCfg = Debug|Win32 21 | {02DB1BFF-93A4-4420-87D1-412FB902183E}.Debug|x86.Build.0 = Debug|Win32 22 | {02DB1BFF-93A4-4420-87D1-412FB902183E}.Release|x64.ActiveCfg = Release|x64 23 | {02DB1BFF-93A4-4420-87D1-412FB902183E}.Release|x64.Build.0 = Release|x64 24 | {02DB1BFF-93A4-4420-87D1-412FB902183E}.Release|x86.ActiveCfg = Release|Win32 25 | {02DB1BFF-93A4-4420-87D1-412FB902183E}.Release|x86.Build.0 = Release|Win32 26 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB}.Debug|x64.ActiveCfg = Debug|x64 27 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB}.Debug|x64.Build.0 = Debug|x64 28 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB}.Debug|x86.ActiveCfg = Debug|Win32 29 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB}.Debug|x86.Build.0 = Debug|Win32 30 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB}.Release|x64.ActiveCfg = Release|x64 31 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB}.Release|x64.Build.0 = Release|x64 32 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB}.Release|x86.ActiveCfg = Release|Win32 33 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /PELoader/PELoader.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {02DB1BFF-93A4-4420-87D1-412FB902183E} 24 | Win32Proj 25 | PELoader 26 | 10.0.15063.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | ..\..\MyTools;$(IncludePath) 76 | 77 | 78 | true 79 | ..\..\MyTools;$(IncludePath) 80 | 81 | 82 | false 83 | 84 | 85 | false 86 | 87 | 88 | 89 | 90 | 91 | Level4 92 | Disabled 93 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 94 | 95 | 96 | Console 97 | 98 | 99 | 100 | 101 | 102 | 103 | Level3 104 | Disabled 105 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 106 | 107 | 108 | Console 109 | 110 | 111 | 112 | 113 | Level3 114 | 115 | 116 | MaxSpeed 117 | true 118 | true 119 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 120 | 121 | 122 | Console 123 | true 124 | true 125 | 126 | 127 | 128 | 129 | Level3 130 | 131 | 132 | MaxSpeed 133 | true 134 | true 135 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 136 | 137 | 138 | Console 139 | true 140 | true 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /PELoader/PELoader.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 | {e61cf4fe-65f0-4323-94cb-a3aa132708e3} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | MyTools 26 | 27 | 28 | MyTools 29 | 30 | 31 | MyTools 32 | 33 | 34 | MyTools 35 | 36 | 37 | MyTools 38 | 39 | 40 | MyTools 41 | 42 | 43 | MyTools 44 | 45 | 46 | MyTools 47 | 48 | 49 | MyTools 50 | 51 | 52 | MyTools 53 | 54 | 55 | MyTools 56 | 57 | 58 | MyTools 59 | 60 | 61 | MyTools 62 | 63 | 64 | MyTools 65 | 66 | 67 | MyTools 68 | 69 | 70 | Source Files 71 | 72 | 73 | 74 | 75 | MyTools 76 | 77 | 78 | MyTools 79 | 80 | 81 | MyTools 82 | 83 | 84 | MyTools 85 | 86 | 87 | MyTools 88 | 89 | 90 | MyTools 91 | 92 | 93 | MyTools 94 | 95 | 96 | MyTools 97 | 98 | 99 | MyTools 100 | 101 | 102 | MyTools 103 | 104 | 105 | MyTools 106 | 107 | 108 | MyTools 109 | 110 | 111 | MyTools 112 | 113 | 114 | MyTools 115 | 116 | 117 | MyTools 118 | 119 | 120 | MyTools 121 | 122 | 123 | MyTools 124 | 125 | 126 | Header Files 127 | 128 | 129 | -------------------------------------------------------------------------------- /PELoader/PELoader/PELoader.cpp: -------------------------------------------------------------------------------- 1 | #include "PELoader.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #pragma comment(lib,"DbgHelp.lib") 9 | 10 | CPELoader::~CPELoader() 11 | { 12 | if (_bAlloc) 13 | { 14 | ::VirtualFree(_pvFileContent, 0, MEM_RELEASE); 15 | } 16 | } 17 | 18 | BOOL CPELoader::SetContent(_In_ CONST std::wstring& wsFilePath) 19 | { 20 | if (!MyTools::CLFile::ReadFileContent(wsFilePath, _pvFileContent, _uFileSize)) 21 | { 22 | _SetErrMsg(L"UnExist File:%s", wsFilePath.c_str()); 23 | return FALSE; 24 | } 25 | 26 | _bAlloc = TRUE; 27 | return TRUE; 28 | } 29 | 30 | VOID CPELoader::SetContent(_In_ LPVOID pvCode, _In_ UINT uSize) 31 | { 32 | _pvFileContent = pvCode; 33 | _uFileSize = uSize; 34 | _bAlloc = FALSE; 35 | } 36 | 37 | BOOL CPELoader::IsPEFile() CONST 38 | { 39 | auto pDosHeader = GetDosHeader(); 40 | if (pDosHeader == nullptr) 41 | { 42 | _SetErrMsg(L"pDosHeader = nullptr"); 43 | return FALSE; 44 | } 45 | 46 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 47 | { 48 | _SetErrMsg(L"pDosHeader->e_magic[%04X] != MZ", pDosHeader->e_magic); 49 | return FALSE; 50 | } 51 | 52 | auto pNtHeader = GetNtHeader(); 53 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) 54 | { 55 | _SetErrMsg(L"pNtHeader->Signature[%04X] != PE00", pDosHeader->e_magic); 56 | return FALSE; 57 | } 58 | #ifdef _WIN64 59 | else if(pNtHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) 60 | { 61 | _SetErrMsg(L"Current Machine = x86, Target Machine = x64"); 62 | return FALSE; 63 | } 64 | #else 65 | else if (pNtHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) 66 | { 67 | _SetErrMsg(L"Current Machine = x64, Target Machine = x86"); 68 | return FALSE; 69 | } 70 | #endif // _WIN64 71 | else if (pNtHeader->OptionalHeader.SectionAlignment & 1) 72 | { 73 | _SetErrMsg(L"Invalid SectionAlignment[%d]", pNtHeader->OptionalHeader.SectionAlignment); 74 | return FALSE; 75 | } 76 | 77 | return TRUE; 78 | } 79 | 80 | BOOL CPELoader::GetVecImportTable(_Out_ std::vector& Vec) CONST 81 | { 82 | CONST auto pImportDescriptor = reinterpret_cast(GetDataDirectory(IMAGE_DIRECTORY_ENTRY_IMPORT)); 83 | if (pImportDescriptor == nullptr) 84 | { 85 | _SetErrMsg(L"pImportDescriptor = nullptr"); 86 | return FALSE; 87 | } 88 | 89 | for (auto pImportDesc = pImportDescriptor; pImportDesc->FirstThunk != 0; ++pImportDesc) 90 | { 91 | ImportTable ImportTable_; 92 | 93 | CONST CHAR* szName = reinterpret_cast(RVAToPtr(pImportDesc->Name)); 94 | if (szName == nullptr) 95 | { 96 | _SetErrMsg(L"szName = nullptr"); 97 | continue; 98 | } 99 | 100 | ImportTable_.wsDLLName = MyTools::CCharacter::ASCIIToUnicode(std::string(szName)); 101 | DWORD* pdwThunk = reinterpret_cast(RVAToPtr(pImportDesc->OriginalFirstThunk != NULL ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk)); 102 | 103 | DWORD dwThunkValue = NULL; 104 | while ((dwThunkValue = MyTools::CCharacter::ReadDWORD(reinterpret_cast(pdwThunk))) != NULL) 105 | { 106 | ImportDLLTable DLLTable; 107 | 108 | if (dwThunkValue & IMAGE_ORDINAL_FLAG32) 109 | DLLTable.wsAPIName = L"--"; 110 | else 111 | { 112 | PIMAGE_IMPORT_BY_NAME pImportName = reinterpret_cast(RVAToPtr(dwThunkValue)); 113 | DLLTable.wsAPIName = pImportName == nullptr ? L"--" : MyTools::CCharacter::ASCIIToUnicode(std::string(pImportName->Name)); 114 | } 115 | 116 | 117 | pdwThunk += 1; 118 | ImportTable_.VecTable.push_back(std::move(DLLTable)); 119 | } 120 | 121 | 122 | Vec.push_back(std::move(ImportTable_)); 123 | } 124 | 125 | return TRUE; 126 | } 127 | 128 | BOOL CPELoader::GetMapExportTable(_Out_ std::map& MapExportTable) CONST 129 | { 130 | CONST auto pExportDirectory = reinterpret_cast(GetDataDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT)); 131 | if (pExportDirectory == nullptr) 132 | { 133 | _SetErrMsg(L"pExportDirectory = nullptr"); 134 | return FALSE; 135 | } 136 | 137 | auto dwNameRva = reinterpret_cast(RVAToPtr(pExportDirectory->AddressOfNames)); 138 | for (DWORD i = 0;i < pExportDirectory->NumberOfFunctions; ++i) 139 | { 140 | ExportTable ExportTable_; 141 | ExportTable_.dwOrdinal = pExportDirectory->Base + i; 142 | 143 | auto dwValue = reinterpret_cast(RVAToPtr(pExportDirectory->AddressOfFunctions + i * 4)); 144 | ExportTable_.dwMethodPtr = MyTools::CCharacter::ReadDWORD(dwValue); 145 | MapExportTable.insert(std::make_pair(ExportTable_.dwOrdinal, std::move(ExportTable_))); 146 | } 147 | 148 | for (DWORD i = 0;i < pExportDirectory->NumberOfNames; ++i) 149 | { 150 | DWORD dwRva = MyTools::CCharacter::ReadDWORD(dwNameRva + i * 4); // dwRva = (DWORD*)(dwNameRva)[i]; 151 | if (dwRva == NULL) 152 | { 153 | _SetErrMsg(L"i = %d, dwRvaValue = NULL, dwNameRva = %X", i, dwNameRva); 154 | continue; 155 | } 156 | 157 | CONST CHAR* szNamePtr = reinterpret_cast(RVAToPtr(dwRva)); 158 | if (szNamePtr == nullptr) 159 | { 160 | _SetErrMsg(L"i = %d, szNamePtr = NULL, dwRva = %X", i, dwRva); 161 | continue; 162 | } 163 | 164 | auto dwOrdinals = reinterpret_cast(RVAToPtr(pExportDirectory->AddressOfNameOrdinals + i * sizeof(WORD))); 165 | dwOrdinals = static_cast(MyTools::CCharacter::ReadWORD(dwOrdinals)) + pExportDirectory->Base; 166 | 167 | auto itr = MapExportTable.find(dwOrdinals); 168 | if (itr != MapExportTable.end()) 169 | { 170 | itr->second.wsFunName = MyTools::CCharacter::ASCIIToUnicode(std::string(szNamePtr)); 171 | } 172 | } 173 | 174 | return TRUE; 175 | } 176 | 177 | LPVOID CPELoader::GetDLLAddress(_In_ UINT_PTR hModule, _In_ LPCSTR pszFunName) 178 | { 179 | PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast(hModule); 180 | if (pDosHeader == nullptr) 181 | { 182 | _SetErrMsg(L"pDosHeader = nullptr"); 183 | return nullptr; 184 | } 185 | 186 | PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast(pDosHeader->e_lfanew + hModule); 187 | if (pNtHeader == nullptr) 188 | { 189 | _SetErrMsg(L"pNtHeader = nullptr"); 190 | return nullptr; 191 | } 192 | 193 | PIMAGE_EXPORT_DIRECTORY pExportDirectory = reinterpret_cast(pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + hModule); 194 | 195 | // By Ordinals? 196 | if ((reinterpret_cast(pszFunName) & 0xFFFF0000) == 0) 197 | { 198 | auto dwOrdinals = reinterpret_cast(pszFunName); 199 | if (dwOrdinals >= hModule) 200 | { 201 | _SetErrMsg(L"dwOrdinals[%X] > hModule[%X]", dwOrdinals, hModule); 202 | return nullptr; 203 | } 204 | else if (dwOrdinals > pExportDirectory->Base + pExportDirectory->NumberOfFunctions - 1/*RAV to Max Ordinals VA*/) 205 | { 206 | _SetErrMsg(L"dwOrdinals[%X] > Max Ordinals[%X]", dwOrdinals, pExportDirectory->Base + pExportDirectory->NumberOfFunctions - 1); 207 | return nullptr; 208 | } 209 | 210 | // to VA 211 | UINT_PTR dwMethodPtr = pExportDirectory->AddressOfFunctions + hModule; 212 | 213 | // VA Function[Ordinal] 214 | return reinterpret_cast(MyTools::CCharacter::ReadDWORD(pExportDirectory->Base - dwMethodPtr) + hModule); 215 | } 216 | 217 | // By Name! 218 | for (DWORD i = 0; i < pExportDirectory->NumberOfNames; ++i) 219 | { 220 | // Name RVA 221 | DWORD dwRva = MyTools::CCharacter::ReadDWORD(pExportDirectory->AddressOfNames + hModule + i * 4); 222 | if (dwRva == NULL) 223 | continue; 224 | 225 | // Name VA 226 | CONST CHAR* szName = reinterpret_cast(dwRva + hModule); 227 | if (szName == nullptr) 228 | continue; 229 | 230 | if (strcmp(szName, pszFunName) == 0x0) 231 | { 232 | DWORD dwOrdinals = MyTools::CCharacter::ReadWORD(pExportDirectory->AddressOfNameOrdinals + hModule + i * 2); 233 | if (dwOrdinals >= pExportDirectory->NumberOfFunctions + pExportDirectory->Base - 1) 234 | { 235 | _SetErrMsg(L"dwOrdinals[%X] > Max Ordinals[%X]", dwOrdinals, pExportDirectory->Base + pExportDirectory->NumberOfFunctions - 1); 236 | return nullptr; 237 | } 238 | 239 | DWORD dwFunAddr = MyTools::CCharacter::ReadDWORD(static_cast(pExportDirectory->AddressOfFunctions + dwOrdinals * 4 + hModule)); 240 | if (dwFunAddr == NULL) 241 | { 242 | _SetErrMsg(L"dwOrdinals[%X] = NULL", dwOrdinals); 243 | return nullptr; 244 | } 245 | 246 | return reinterpret_cast(hModule + dwFunAddr); 247 | } 248 | } 249 | return nullptr; 250 | } 251 | 252 | 253 | BOOL CPELoader::_LoadLibrary() 254 | { 255 | auto pNtHeader = GetNtHeader(); 256 | if ((pNtHeader->FileHeader.Characteristics & IMAGE_FILE_DLL) == 0) 257 | { 258 | _SetErrMsg(L"this File wasn't DLL!"); 259 | return FALSE; 260 | } 261 | 262 | // 263 | auto pCode = AllocAlignedCodeContent(); 264 | if (pCode == nullptr) 265 | return FALSE; 266 | 267 | // 268 | auto pNewDosHeader = AllocAndCopyPeHeader(pCode); 269 | if (pNewDosHeader == nullptr) 270 | return FALSE; 271 | 272 | // 273 | if (!CopySection(reinterpret_cast(pCode), pNewDosHeader)) 274 | return FALSE; 275 | 276 | // 277 | DWORD64 dwLocationDelta = static_cast(GetNtHeader(pNewDosHeader)->OptionalHeader.ImageBase - pNtHeader->OptionalHeader.ImageBase); 278 | if (dwLocationDelta != NULL && !Relocation(dwLocationDelta, reinterpret_cast(pCode), pNewDosHeader)) // Relocation 279 | return FALSE; 280 | 281 | // 282 | if (!ReBuileImportTable(reinterpret_cast(pCode), pNewDosHeader)) 283 | return FALSE; 284 | 285 | // UnUseful 286 | //if (!ReBuileExportTable(reinterpret_cast(pCode), pNewDosHeader)) 287 | // return FALSE; 288 | //ReBuileSection(pNewDosHeader); 289 | InvokeTLS(reinterpret_cast(pCode)); 290 | return ExcuteEntryPoint(reinterpret_cast(pCode)); 291 | } 292 | 293 | DWORD CPELoader::GetAlignedImageSize() CONST 294 | { 295 | // 296 | SYSTEM_INFO SysInfo; 297 | ::GetNativeSystemInfo(&SysInfo); 298 | 299 | // 300 | DWORD dwAlignedImageSize = GetNtHeader()->OptionalHeader.SizeOfImage + SysInfo.dwPageSize - 1; 301 | dwAlignedImageSize &= ~(SysInfo.dwPageSize - 1); 302 | 303 | DWORD dwSectionAlignedImageSize = GetSectionEndRva() + SysInfo.dwPageSize - 1; 304 | dwSectionAlignedImageSize &= ~(SysInfo.dwPageSize - 1); 305 | if (dwSectionAlignedImageSize != dwAlignedImageSize) 306 | { 307 | _SetErrMsg(L"dwSectionAlignedImageSize[%X] != dwAlignedImageSize[%X]", dwSectionAlignedImageSize, dwAlignedImageSize); 308 | return 0; 309 | } 310 | 311 | return dwAlignedImageSize; 312 | } 313 | 314 | DWORD CPELoader::GetSectionEndRva() CONST 315 | { 316 | auto pNtHeader = GetNtHeader(); 317 | auto pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader); 318 | 319 | DWORD dwSectionEnd = NULL; 320 | for (decltype(IMAGE_FILE_HEADER::NumberOfSections) i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i,++pSectionHeader) 321 | { 322 | DWORD dwValue = NULL; 323 | if (pSectionHeader->SizeOfRawData == 0) 324 | dwValue = pSectionHeader->VirtualAddress + pNtHeader->OptionalHeader.SectionAlignment; 325 | else 326 | dwValue = pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData; 327 | 328 | dwSectionEnd = dwValue > dwSectionEnd ? dwValue : dwSectionEnd; 329 | } 330 | return dwSectionEnd; 331 | } 332 | 333 | LPVOID CPELoader::AllocAlignedCodeContent() CONST 334 | { 335 | // if DLL Size = 10KB, but AlignedImageSize may = 16KB, make ImageSize Aligned to System.PageSize 336 | DWORD dwAlignedImageSize = GetAlignedImageSize(); 337 | if (dwAlignedImageSize == NULL) 338 | return nullptr; 339 | 340 | 341 | // Try to Alloc Contiguous Memory begin of ImageBase 342 | auto pCode = ::VirtualAlloc(NULL/*reinterpret_cast(GetNtHeader()->OptionalHeader.ImageBase)*/, dwAlignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 343 | if (pCode == nullptr) 344 | { 345 | // whatever 346 | pCode = ::VirtualAlloc(NULL, dwAlignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 347 | if (pCode == nullptr) 348 | { 349 | _SetErrMsg(L"Alloc Memory [%d] Size Faild", dwAlignedImageSize); 350 | return nullptr; 351 | } 352 | } 353 | 354 | return pCode; 355 | } 356 | 357 | PIMAGE_DOS_HEADER CPELoader::AllocAndCopyPeHeader(LPVOID pCode) CONST 358 | { 359 | auto pNtHeader = GetNtHeader(); 360 | 361 | // 362 | auto pNewDosHeader = reinterpret_cast(::VirtualAlloc(pCode, pNtHeader->OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_EXECUTE_READWRITE)); 363 | if (pNewDosHeader == nullptr) 364 | { 365 | _SetErrMsg(L"Alloc pHeader = nullptr!"); 366 | return nullptr; 367 | } 368 | 369 | // Copy Memory 370 | memcpy(pNewDosHeader, GetDosHeader(), pNtHeader->OptionalHeader.SizeOfHeaders); 371 | 372 | // Set New ImageBase 373 | auto pNewNtHeader = GetNtHeader(pNewDosHeader); 374 | #ifdef _WIN64 375 | pNewNtHeader->OptionalHeader.ImageBase = reinterpret_cast(pCode); 376 | #else 377 | pNewNtHeader->OptionalHeader.ImageBase = reinterpret_cast(pCode); 378 | #endif // _WIN64 379 | return pNewDosHeader; 380 | } 381 | 382 | BOOL CPELoader::CopySection(_In_ UCHAR* pCode, _In_ PIMAGE_DOS_HEADER pDosHeader) CONST 383 | { 384 | auto pNtHeader = GetNtHeader(pDosHeader); 385 | auto pSectionheader = IMAGE_FIRST_SECTION(pNtHeader); 386 | 387 | for (decltype(IMAGE_FILE_HEADER::NumberOfSections) i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i, ++pSectionheader) 388 | { 389 | // Empty Section 390 | if (pSectionheader->SizeOfRawData == NULL) 391 | { 392 | if (pNtHeader->OptionalHeader.SectionAlignment > 0) 393 | { 394 | auto pSectionBase = ::VirtualAlloc(pCode + pSectionheader->VirtualAddress, pNtHeader->OptionalHeader.SectionAlignment, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 395 | if (pSectionBase == nullptr) 396 | { 397 | _SetErrMsg(L"VirtualAlloc Section Base Faild! Size[%d], Addr[%X]", pNtHeader->OptionalHeader.SectionAlignment, pCode + pSectionheader->VirtualAddress); 398 | return FALSE; 399 | } 400 | 401 | pSectionBase = pCode + pSectionheader->VirtualAddress; 402 | pSectionheader->Misc.PhysicalAddress = static_cast(reinterpret_cast(pSectionBase)); 403 | ZeroMemory(pSectionBase, pNtHeader->OptionalHeader.SectionAlignment); 404 | } 405 | 406 | // pass Empty Section 407 | continue; 408 | } 409 | 410 | // Copy Section Content 411 | auto pSectionBase = ::VirtualAlloc(pCode + pSectionheader->VirtualAddress, pSectionheader->SizeOfRawData, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 412 | if (pSectionBase == nullptr) 413 | { 414 | _SetErrMsg(L"VirtualAlloc Section Content Faild! Size[%d], Addr[%X]", pSectionheader->SizeOfRawData, pCode + pSectionheader->VirtualAddress); 415 | return FALSE; 416 | } 417 | 418 | pSectionBase = pCode + pSectionheader->VirtualAddress; 419 | memcpy(pSectionBase, reinterpret_cast(_pvFileContent) + pSectionheader->PointerToRawData, pSectionheader->SizeOfRawData); 420 | pSectionheader->Misc.PhysicalAddress = static_cast(reinterpret_cast(pSectionBase)); 421 | } 422 | 423 | return TRUE; 424 | } 425 | 426 | BOOL CPELoader::Relocation(_In_ LONGLONG LocationDelta, _In_ UCHAR* pCode, _In_ PIMAGE_DOS_HEADER pDosHeader) CONST 427 | { 428 | auto pNtHeader = GetNtHeader(pDosHeader); 429 | auto pDirectoryBaseReloc = &pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; 430 | if (pDirectoryBaseReloc->Size == NULL) 431 | { 432 | _SetErrMsg(L"pDirectoryBaseReloc->Size = 0"); 433 | return FALSE; 434 | } 435 | 436 | auto pBaseRelocation = reinterpret_cast(pCode + pDirectoryBaseReloc->VirtualAddress); 437 | while (pBaseRelocation->VirtualAddress != 0) 438 | { 439 | auto dwRelocationBase = reinterpret_cast(pCode) + pBaseRelocation->VirtualAddress; 440 | USHORT* pRelocationInfo = reinterpret_cast(reinterpret_cast(pBaseRelocation) + sizeof(IMAGE_BASE_RELOCATION)); 441 | 442 | int nMaxSize = (pBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2; // >> 1 443 | for (int i = 0;i < nMaxSize; ++i, ++pRelocationInfo) 444 | { 445 | DWORD dwOffset = *pRelocationInfo & 0xFFF; 446 | 447 | switch (*pRelocationInfo >> 12) 448 | { 449 | case IMAGE_REL_BASED_ABSOLUTE: 450 | break; 451 | case IMAGE_REL_BASED_HIGHLOW: // x86 452 | *reinterpret_cast(dwRelocationBase + dwOffset) += static_cast(LocationDelta); 453 | break; 454 | #ifdef _WIN64 455 | case IMAGE_REL_BASED_DIR64: // x64 456 | *reinterpret_cast(dwRelocationBase + dwOffset) += LocationDelta; 457 | break; 458 | #endif // _WIN64 459 | 460 | default: 461 | break; 462 | } 463 | } 464 | 465 | pBaseRelocation = reinterpret_cast(reinterpret_cast(pBaseRelocation) + pBaseRelocation->SizeOfBlock); 466 | } 467 | 468 | return TRUE; 469 | } 470 | 471 | BOOL CPELoader::ReBuileImportTable(_In_ UINT_PTR pCode, _In_ PIMAGE_DOS_HEADER pDosHeader) CONST 472 | { 473 | auto pNtHeader = GetNtHeader(pDosHeader); 474 | auto pImortDescipor = reinterpret_cast(pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + pCode); 475 | if (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0) 476 | return TRUE; 477 | 478 | for (; pImortDescipor->FirstThunk != NULL; pImortDescipor++) 479 | { 480 | // repalace to _LoadLibrary? 481 | CONST CHAR* pszDLLName = reinterpret_cast(pCode + pImortDescipor->Name); 482 | HMODULE hmDLL = ::LoadLibraryA(pszDLLName); 483 | if (hmDLL == NULL) 484 | { 485 | _SetErrMsg(L"Load ImportTable DLL[%s] Faild!!!", MyTools::CCharacter::ASCIIToUnicode(std::string(pszDLLName)).c_str()); 486 | return FALSE; 487 | } 488 | 489 | UINT_PTR* pdwThunk = nullptr; 490 | UINT_PTR* pdwFunc = nullptr; 491 | 492 | // OriginalFirstThunk -> INT Table 493 | // FirstThunk -> IAT Table 494 | if (pImortDescipor->OriginalFirstThunk) 495 | { 496 | pdwThunk = reinterpret_cast(pCode + pImortDescipor->OriginalFirstThunk); 497 | pdwFunc = reinterpret_cast(pCode + pImortDescipor->FirstThunk); 498 | } 499 | else 500 | { 501 | pdwFunc = pdwThunk = reinterpret_cast(pCode + pImortDescipor->FirstThunk); 502 | } 503 | 504 | for (; *pdwThunk != NULL;pdwFunc++, pdwThunk++) 505 | { 506 | if (*pdwThunk & IMAGE_ORDINAL_FLAG32) 507 | { 508 | // For Original 509 | auto dwOriginal = *pdwThunk & 0xFFFF; 510 | *pdwFunc = reinterpret_cast(::GetProcAddress(hmDLL, reinterpret_cast(dwOriginal))); 511 | if (*pdwFunc == NULL) 512 | { 513 | _SetErrMsg(L"DLL[%s] Proc Address By Original[%X] Load Faild!", 514 | MyTools::CCharacter::ASCIIToUnicode(std::string(pszDLLName)).c_str(), dwOriginal); 515 | return FALSE; 516 | } 517 | } 518 | else 519 | { 520 | // For Name 521 | PIMAGE_IMPORT_BY_NAME pImportName = reinterpret_cast(pCode + *pdwThunk/*RVA*/); 522 | *pdwFunc = reinterpret_cast(::GetProcAddress(hmDLL, pImportName->Name)); 523 | if (*pdwFunc == NULL) 524 | { 525 | _SetErrMsg(L"DLL[%s] Proc Address By Name[%X] Load Faild!", 526 | MyTools::CCharacter::ASCIIToUnicode(std::string(pszDLLName)).c_str(), 527 | MyTools::CCharacter::ASCIIToUnicode(std::string(pImportName->Name)).c_str()); 528 | return FALSE; 529 | } 530 | } 531 | } 532 | } 533 | 534 | return TRUE; 535 | } 536 | 537 | BOOL CPELoader::ReBuileExportTable(_In_ UINT_PTR, _In_ PIMAGE_DOS_HEADER ) CONST 538 | { 539 | return TRUE; 540 | } 541 | 542 | BOOL CPELoader::ReBuileSection(_In_ PIMAGE_DOS_HEADER pDosHeader) CONST 543 | { 544 | auto pNtHeader = GetNtHeader(pDosHeader); 545 | auto pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader); 546 | 547 | SYSTEM_INFO SysInfo; 548 | ::GetNativeSystemInfo(&SysInfo); 549 | 550 | // Convert DLL Attribute to Memory Attribute 551 | SectionAttribute&& SectionAttribute_ = FillSectionAttribute(pNtHeader, nullptr, SysInfo.dwPageSize, pSectionHeader++); 552 | FinalizeSection(SysInfo.dwPageSize, pNtHeader, std::move(SectionAttribute_), FALSE); 553 | for (DWORD i = 1; i < pNtHeader->FileHeader.NumberOfSections ;++i, ++pSectionHeader) 554 | { 555 | // how to Force Discard Last Section ? 556 | SectionAttribute_ = FillSectionAttribute(pNtHeader, &SectionAttribute_, SysInfo.dwPageSize, pSectionHeader); 557 | FinalizeSection(SysInfo.dwPageSize, pNtHeader, std::move(SectionAttribute_), FALSE); 558 | } 559 | 560 | return TRUE; 561 | } 562 | 563 | CPELoader::SectionAttribute&& CPELoader::FillSectionAttribute(_In_ PIMAGE_NT_HEADERS pNtHeader, _In_ CONST SectionAttribute* pSectionAttribute, _In_ DWORD dwPageSize, _In_ PIMAGE_SECTION_HEADER pSectionHeader) CONST 564 | { 565 | #ifdef _WIN64 566 | UINT ImageOffset = static_cast(pNtHeader->OptionalHeader.ImageBase & 0xffffffff00000000); 567 | #else 568 | UINT ImageOffset = 0; 569 | #endif // _WIN64 570 | 571 | SectionAttribute SectionAttribute_; 572 | // Convert File RVA to Memory RVA 573 | SectionAttribute_.dwSectionRVA = pSectionHeader->Misc.PhysicalAddress | ImageOffset; 574 | // Set Section Aligned = System Page Aligned 575 | SectionAttribute_.dwSectionAligned = static_cast(SectionAttribute_.dwSectionRVA) & ~(dwPageSize - 1); 576 | 577 | DWORD dwSectionSize = 0; 578 | if (pSectionHeader->SizeOfRawData != 0) 579 | dwSectionSize = pSectionHeader->SizeOfRawData; 580 | else 581 | { 582 | if (pSectionHeader->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) // include Initialized Data in Secion 583 | dwSectionSize = pNtHeader->OptionalHeader.SizeOfInitializedData; 584 | else if (pSectionHeader->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) // include UnInitialized Data in Secion 585 | dwSectionSize = pNtHeader->OptionalHeader.SizeOfUninitializedData; 586 | } 587 | 588 | if (pSectionAttribute == nullptr) 589 | { 590 | SectionAttribute_.dwCharacteristics = pSectionHeader->Characteristics; 591 | SectionAttribute_.dwSectionSize = dwSectionSize; 592 | } 593 | else 594 | { 595 | if (SectionAttribute_.dwSectionRVA == pSectionAttribute->dwSectionRVA || (pSectionAttribute->dwSectionRVA + pSectionAttribute->dwSectionSize > SectionAttribute_.dwSectionRVA)) 596 | { 597 | if (!(pSectionHeader->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) || !(pSectionAttribute->dwCharacteristics & IMAGE_SCN_MEM_DISCARDABLE)) 598 | SectionAttribute_.dwCharacteristics = (pSectionAttribute->dwCharacteristics | pSectionHeader->Characteristics) & ~IMAGE_SCN_MEM_DISCARDABLE; 599 | else 600 | SectionAttribute_.dwCharacteristics |= pSectionHeader->Characteristics; 601 | } 602 | 603 | SectionAttribute_.dwSectionSize = static_cast(SectionAttribute_.dwSectionRVA) + dwSectionSize - static_cast(pSectionAttribute->dwSectionRVA); 604 | } 605 | 606 | return std::move(SectionAttribute_); 607 | } 608 | 609 | VOID CPELoader::FinalizeSection(_In_ DWORD dwPageSize, _In_ PIMAGE_NT_HEADERS pNtHeader, _In_ SectionAttribute&& SectionAttribute_, _In_ BOOL bForceDiscard) CONST 610 | { 611 | if (SectionAttribute_.dwSectionSize == 0) 612 | return; 613 | else if (SectionAttribute_.dwCharacteristics & IMAGE_SCN_MEM_DISCARDABLE) 614 | { 615 | /*if (SectionAttribute_.dwSectionRVA != SectionAttribute_.dwSectionAligned) 616 | return; 617 | 618 | if (bForceDiscard || pNtHeader->OptionalHeader.SectionAlignment == dwPageSize || (SectionAttribute_.dwSectionSize % dwPageSize) == 0) 619 | { 620 | ::VirtualFree(reinterpret_cast(SectionAttribute_.dwSectionRVA), SectionAttribute_.dwSectionSize, MEM_DECOMMIT); 621 | }*/ 622 | 623 | return; 624 | } 625 | 626 | 627 | //DWORD dwProtect = SectionAttribute_.dwCharacteristics & IMAGE_SCN_MEM_EXECUTE ? PAGE_EXECUTE : 0; 628 | //dwProtect |= SectionAttribute_.dwCharacteristics & IMAGE_SCN_MEM_READ ? PAGE_EXECUTE_READ : 0; 629 | //dwProtect |= SectionAttribute_.dwCharacteristics & IMAGE_SCN_MEM_WRITE ? PAGE_EXECUTE_WRITECOPY : 0; 630 | DWORD dwProtect = PAGE_EXECUTE_READWRITE; 631 | if (SectionAttribute_.dwCharacteristics & IMAGE_SCN_MEM_NOT_CACHED) 632 | dwProtect |= PAGE_NOCACHE; 633 | 634 | DWORD dwValue = 0; 635 | ::VirtualProtect(reinterpret_cast(SectionAttribute_.dwSectionRVA), SectionAttribute_.dwSectionSize, dwProtect, &dwValue); 636 | } 637 | 638 | VOID CPELoader::InvokeTLS(_In_ UINT_PTR pCode) CONST 639 | { 640 | auto pNtHeader = GetNtHeader(reinterpret_cast(pCode)); 641 | if (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress == NULL) 642 | return; 643 | 644 | 645 | auto pTlsDirectory = reinterpret_cast(pCode + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); 646 | auto pTlsCallBack = reinterpret_cast(pTlsDirectory->AddressOfCallBacks); 647 | while (pTlsCallBack && *pTlsCallBack) 648 | { 649 | (*pTlsCallBack)(reinterpret_cast(pCode), DLL_PROCESS_ATTACH, NULL); 650 | ++pTlsCallBack; 651 | } 652 | } 653 | 654 | BOOL CPELoader::ExcuteEntryPoint(_In_ UCHAR* pCode) CONST 655 | { 656 | auto pNtHeader = GetNtHeader(reinterpret_cast(pCode)); 657 | if (pNtHeader->OptionalHeader.AddressOfEntryPoint == NULL) 658 | { 659 | _SetErrMsg(L"AddressOfEntryPoint = 0!"); 660 | ::VirtualFree(pCode, 0, MEM_RELEASE); 661 | return FALSE; 662 | } 663 | 664 | using DLLEntryProc = BOOL(APIENTRY *)(HMODULE hModule, DWORD dwReason, LPVOID lpReserved); 665 | DLLEntryProc DLLEntry = reinterpret_cast(pCode + pNtHeader->OptionalHeader.AddressOfEntryPoint); 666 | 667 | __try 668 | { 669 | DLLEntry(reinterpret_cast(pCode), DLL_PROCESS_ATTACH, NULL); 670 | } 671 | __except (EXCEPTION_EXECUTE_HANDLER) 672 | { 673 | ::MessageBoxW(NULL, L"aaa", L"", NULL); 674 | } 675 | 676 | return TRUE; 677 | } 678 | 679 | CONST PIMAGE_DOS_HEADER CPELoader::GetDosHeader() CONST 680 | { 681 | return reinterpret_cast(_pvFileContent); 682 | } 683 | 684 | CONST PIMAGE_NT_HEADERS CPELoader::GetNtHeader() CONST 685 | { 686 | CONST auto pDosHeader = GetDosHeader(); 687 | if (pDosHeader == nullptr) 688 | { 689 | _SetErrMsg(L"pDosHeader = nullptr"); 690 | return nullptr; 691 | } 692 | 693 | return GetNtHeader(pDosHeader); 694 | } 695 | 696 | CONST PIMAGE_NT_HEADERS CPELoader::GetNtHeader(_In_ CONST PIMAGE_DOS_HEADER pDosHeader) CONST 697 | { 698 | auto lgOffset = pDosHeader->e_lfanew + reinterpret_cast(pDosHeader); 699 | return reinterpret_cast(lgOffset); 700 | } 701 | 702 | CONST PIMAGE_FILE_HEADER CPELoader::GetFileHeader() CONST 703 | { 704 | CONST auto pNtHeader = GetNtHeader(); 705 | if (pNtHeader == nullptr) 706 | { 707 | _SetErrMsg(L"pNtHeader = nullptr"); 708 | return nullptr; 709 | } 710 | 711 | return static_cast(&pNtHeader->FileHeader); 712 | } 713 | 714 | CONST PIMAGE_OPTIONAL_HEADER CPELoader::GetOptionalHeader() CONST 715 | { 716 | CONST auto pNtHeader = GetNtHeader(); 717 | if (pNtHeader == nullptr) 718 | { 719 | _SetErrMsg(L"pNtHeader = nullptr"); 720 | return nullptr; 721 | } 722 | 723 | return static_cast(&pNtHeader->OptionalHeader); 724 | } 725 | 726 | CONST PIMAGE_DATA_DIRECTORY CPELoader::GetDataDirectoryArray() CONST 727 | { 728 | CONST auto pOptionalHeader = GetOptionalHeader(); 729 | if (pOptionalHeader == nullptr) 730 | { 731 | _SetErrMsg(L"pOptionalHeader = nullptr"); 732 | return nullptr; 733 | } 734 | 735 | return static_cast(pOptionalHeader->DataDirectory); 736 | } 737 | 738 | 739 | CONST PIMAGE_SECTION_HEADER CPELoader::GetSectionHeader() CONST 740 | { 741 | CONST auto pNtHeader = GetNtHeader(); 742 | if (pNtHeader == nullptr) 743 | { 744 | _SetErrMsg(L"pNtHeader = nullptr"); 745 | return nullptr; 746 | } 747 | 748 | return IMAGE_FIRST_SECTION(pNtHeader); 749 | } 750 | 751 | VOID CPELoader::ForEachSection(_In_ std::function ActionPtr) CONST 752 | { 753 | CONST auto pFileHeader = GetFileHeader(); 754 | if (pFileHeader == nullptr) 755 | { 756 | _SetErrMsg(L"pFileHeader = nullptr"); 757 | return; 758 | } 759 | 760 | auto SectionPtr = GetSectionHeader(); 761 | for (decltype(IMAGE_FILE_HEADER::NumberOfSections) i = 0;i < pFileHeader->NumberOfSections; ++i, ++SectionPtr) 762 | ActionPtr(SectionPtr); 763 | } 764 | 765 | LPVOID CPELoader::RVAToVA(_In_ DWORD dwRva) CONST 766 | { 767 | auto pNtHeader = GetNtHeader(); 768 | if (pNtHeader == nullptr) 769 | { 770 | _SetErrMsg(L"pNtHeader = nullptr"); 771 | return nullptr; 772 | } 773 | 774 | return ::ImageRvaToVa(pNtHeader, _pvFileContent, dwRva, NULL); 775 | } 776 | 777 | LPVOID CPELoader::RVAToPtr(_In_ DWORD dwRva) CONST 778 | { 779 | return RVAToVA(dwRva); 780 | } 781 | 782 | LPVOID CPELoader::GetDataDirectory(_In_ int DirectoryOrder) CONST 783 | { 784 | CONST auto pDataDirectoryArray = GetDataDirectoryArray(); 785 | if (pDataDirectoryArray == nullptr) 786 | { 787 | _SetErrMsg(L"pDataDirectoryArray = nullptr"); 788 | return nullptr; 789 | } 790 | 791 | return GetDataDirectory(pDataDirectoryArray, DirectoryOrder); 792 | } 793 | 794 | LPVOID CPELoader::GetDataDirectory(_In_ PIMAGE_DATA_DIRECTORY pDataDirectoryArray, _In_ int DirectoryOrder) CONST 795 | { 796 | if (DirectoryOrder < 0 || DirectoryOrder >= 16) 797 | { 798 | _SetErrMsg(L"DirectoryOrder = %d", DirectoryOrder); 799 | return nullptr; 800 | } 801 | 802 | CONST auto pDataDirectory = &pDataDirectoryArray[DirectoryOrder]; 803 | if (pDataDirectory == nullptr) 804 | { 805 | _SetErrMsg(L"pDataDirectory = %d", DirectoryOrder); 806 | return nullptr; 807 | } 808 | 809 | return RVAToVA(pDataDirectory->VirtualAddress); 810 | } 811 | -------------------------------------------------------------------------------- /PELoader/PELoader/PELoader.h: -------------------------------------------------------------------------------- 1 | #ifndef __PELOADER_PELOADER_PELOADER_H__ 2 | #define __PELOADER_PELOADER_PELOADER_H__ 3 | 4 | #include 5 | #include 6 | 7 | 8 | class CPELoader 9 | { 10 | public: 11 | struct ExportTable 12 | { 13 | DWORD dwOrdinal = NULL; 14 | DWORD dwMethodPtr = NULL; 15 | std::wstring wsFunName; 16 | }; 17 | 18 | struct ImportDLLTable 19 | { 20 | std::wstring wsAPIName; 21 | DWORD dwFuncRVA; 22 | }; 23 | 24 | struct ImportTable 25 | { 26 | std::wstring wsDLLName; 27 | std::vector VecTable; 28 | }; 29 | public: 30 | CPELoader() = default; 31 | ~CPELoader(); 32 | 33 | // Set Applocation binary Code 34 | BOOL SetContent(_In_ CONST std::wstring& wsFilePath); 35 | VOID SetContent(_In_ LPVOID pvCode, _In_ UINT uSize); 36 | 37 | // Load PE Format 38 | BOOL IsPEFile() CONST; 39 | 40 | // 41 | BOOL GetVecImportTable(_Out_ std::vector& Vec) CONST; 42 | 43 | // 44 | BOOL GetMapExportTable(_Out_ std::map& MapExportTable) CONST; 45 | 46 | // 47 | static LPVOID GetDLLAddress(_In_ UINT_PTR hModule, _In_ LPCSTR pszFunName); 48 | 49 | // 50 | BOOL _LoadLibrary(); 51 | 52 | private: 53 | struct SectionAttribute 54 | { 55 | DWORD dwCharacteristics; 56 | DWORD dwSectionSize; 57 | UINT_PTR dwSectionRVA; 58 | DWORD dwSectionAligned; 59 | }; 60 | 61 | // 62 | DWORD GetAlignedImageSize() CONST; 63 | 64 | // 65 | DWORD GetSectionEndRva() CONST; 66 | 67 | // 68 | LPVOID AllocAlignedCodeContent() CONST; 69 | 70 | // 71 | PIMAGE_DOS_HEADER AllocAndCopyPeHeader(_In_ LPVOID pCode) CONST; 72 | 73 | // Copy DLL Section to Alloc Memory Section 74 | BOOL CopySection(_In_ UCHAR* pCode, _In_ PIMAGE_DOS_HEADER pDosHeader) CONST; 75 | 76 | // Relocation 77 | BOOL Relocation(_In_ LONGLONG LocationDelta, _In_ UCHAR* pCode, _In_ PIMAGE_DOS_HEADER pDosHeader) CONST; 78 | 79 | // 80 | BOOL ReBuileImportTable(_In_ UINT_PTR pCode, _In_ PIMAGE_DOS_HEADER pDosHeader) CONST; 81 | 82 | // 83 | BOOL ReBuileExportTable(_In_ UINT_PTR pCode, _In_ PIMAGE_DOS_HEADER pDosHeader) CONST; 84 | 85 | // 86 | BOOL ReBuileSection(_In_ PIMAGE_DOS_HEADER pDosHeader) CONST; 87 | 88 | // 89 | SectionAttribute&& FillSectionAttribute(_In_ PIMAGE_NT_HEADERS pNtHeader, _In_ CONST SectionAttribute* pSectionAttribute, _In_ DWORD dwPageSize, _In_ PIMAGE_SECTION_HEADER pSectionHeader) CONST; 90 | 91 | // 92 | VOID FinalizeSection(_In_ DWORD dwPageSize, _In_ PIMAGE_NT_HEADERS pNtHeader, _In_ SectionAttribute&& SectionAttribute_, _In_ BOOL bForceDiscard) CONST; 93 | 94 | // 95 | VOID InvokeTLS(_In_ UINT_PTR pCode) CONST; 96 | 97 | // 98 | BOOL ExcuteEntryPoint(_In_ UCHAR* pCode) CONST; 99 | private: 100 | CONST PIMAGE_DOS_HEADER GetDosHeader() CONST; 101 | 102 | CONST PIMAGE_NT_HEADERS GetNtHeader() CONST; 103 | 104 | CONST PIMAGE_NT_HEADERS GetNtHeader(_In_ CONST PIMAGE_DOS_HEADER pDosHeader) CONST; 105 | 106 | CONST PIMAGE_FILE_HEADER GetFileHeader() CONST; 107 | 108 | CONST PIMAGE_OPTIONAL_HEADER GetOptionalHeader() CONST; 109 | 110 | CONST PIMAGE_DATA_DIRECTORY GetDataDirectoryArray() CONST; 111 | 112 | CONST PIMAGE_SECTION_HEADER GetSectionHeader() CONST; 113 | 114 | VOID ForEachSection(_In_ std::function ActionPtr) CONST; 115 | 116 | LPVOID RVAToVA(_In_ DWORD dwRva) CONST; 117 | 118 | LPVOID RVAToPtr(_In_ DWORD dwRva) CONST; 119 | 120 | LPVOID GetDataDirectory(_In_ int DirectoryOrder) CONST; 121 | 122 | LPVOID GetDataDirectory(_In_ PIMAGE_DATA_DIRECTORY pDataDirectoryArray, _In_ int DirectoryOrder) CONST; 123 | private: 124 | BOOL _bAlloc = FALSE; 125 | LPVOID _pvFileContent; 126 | UINT _uFileSize; 127 | }; 128 | 129 | 130 | 131 | 132 | 133 | #endif // !__PELOADER_PELOADER_PELOADER_H__ 134 | -------------------------------------------------------------------------------- /PELoader/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "PELoader/PELoader.h" 7 | 8 | typedef BOOL(WINAPI* DefMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT); 9 | DefMessageBoxW OldMessageBoxW = NULL; 10 | 11 | BOOL WINAPI NewMessageBoxW(_In_ HWND hWnd, _In_ LPCWSTR pwsz, _In_ LPCWSTR pwsz2, UINT u) 12 | { 13 | std::cout << "asd" << std::endl; 14 | return OldMessageBoxW(hWnd, pwsz, pwsz2, u); 15 | } 16 | 17 | BOOL IATHook() 18 | { 19 | DWORD pCode = reinterpret_cast(::GetModuleHandleW(NULL)); 20 | PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast(pCode); 21 | PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast(pDosHeader->e_lfanew + reinterpret_cast(pDosHeader)); 22 | 23 | auto pImportDescriptor = reinterpret_cast(pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + pCode); 24 | 25 | for (auto pImportDesc = pImportDescriptor; pImportDesc->FirstThunk != 0; ++pImportDesc) 26 | { 27 | CONST CHAR* szName = reinterpret_cast(pImportDesc->Name + pCode); 28 | if (szName == nullptr) 29 | { 30 | continue; 31 | } 32 | 33 | //ImportTable_.wsDLLName = MyTools::CCharacter::ASCIIToUnicode(std::string(szName)); 34 | PIMAGE_THUNK_DATA pdwThunk = reinterpret_cast(pCode + pImportDesc->OriginalFirstThunk); 35 | PIMAGE_THUNK_DATA pValueThunk = reinterpret_cast(pCode + pImportDesc->FirstThunk); 36 | 37 | while (pdwThunk->u1.Function != 0) 38 | { 39 | 40 | if (pdwThunk->u1.Function & IMAGE_ORDINAL_FLAG32) 41 | ;//DLLTable.wsAPIName = L"--"; 42 | else 43 | { 44 | PIMAGE_IMPORT_BY_NAME pImportName = reinterpret_cast(pdwThunk->u1.Function + pCode); 45 | if (MyTools::CCharacter::ASCIIToUnicode(std::string(pImportName->Name)) == L"MessageBoxW") 46 | { 47 | OldMessageBoxW = reinterpret_cast(pValueThunk->u1.Function); 48 | 49 | MEMORY_BASIC_INFORMATION mbi; 50 | ::VirtualQuery(pValueThunk, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); 51 | ::VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect); 52 | pValueThunk->u1.Function = (DWORD)NewMessageBoxW; 53 | } 54 | //DLLTable.dwFuncRVA = pImportName->Hint + pCode; 55 | } 56 | 57 | pValueThunk += 1; 58 | pdwThunk += 1; 59 | } 60 | } 61 | 62 | return TRUE; 63 | } 64 | 65 | int main() 66 | { 67 | CPELoader Loader; 68 | 69 | //FARPROC pAddr1 = ::GetProcAddress(::GetModuleHandleW(L"user32.dll"), "MessageBoxA"); 70 | //LPVOID pAddr2 = CPELoader::GetDLLAddress(reinterpret_cast(::GetModuleHandleW(L"user32.dll")), "MessageBoxA"); 71 | IATHook(); 72 | 73 | 74 | ::MessageBoxW(NULL, L"", L"", NULL); 75 | /*if (Loader.SetContent(LR"(D:\TestDLL1.dll)")) 76 | { 77 | std::map Vec; 78 | Loader.GetMapExportTable(Vec); 79 | 80 | std::vector Vec1; 81 | Loader.GetVecImportTable(Vec1); 82 | 83 | ::MessageBoxW(NULL, Loader._LoadLibrary() ? L"Succ" : L"Err", L"", NULL); 84 | }*/ 85 | 86 | 87 | ::Sleep(INFINITE); 88 | return 0; 89 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PELoader 2 | ![image](https://github.com/VideoCardGuy/PELoader/raw/master/Screenshot/1.jpg)
3 | ![image](https://github.com/VideoCardGuy/PELoader/raw/master/Screenshot/2.jpg)
4 | ![image](https://github.com/VideoCardGuy/PELoader/raw/master/Screenshot/3.jpg)
5 | ![image](https://github.com/VideoCardGuy/PELoader/raw/master/Screenshot/4.jpg)
6 | -------------------------------------------------------------------------------- /Screenshot/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyexe/PELoader/a2332e4fc59bafa969ceb988c07fbb78579acb83/Screenshot/1.jpg -------------------------------------------------------------------------------- /Screenshot/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyexe/PELoader/a2332e4fc59bafa969ceb988c07fbb78579acb83/Screenshot/2.jpg -------------------------------------------------------------------------------- /Screenshot/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyexe/PELoader/a2332e4fc59bafa969ceb988c07fbb78579acb83/Screenshot/3.jpg -------------------------------------------------------------------------------- /Screenshot/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyexe/PELoader/a2332e4fc59bafa969ceb988c07fbb78579acb83/Screenshot/4.jpg -------------------------------------------------------------------------------- /TestDLL/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | DYNAMIC LINK LIBRARY : TestDLL Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this TestDLL DLL for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your TestDLL application. 9 | 10 | 11 | TestDLL.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | TestDLL.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | TestDLL.cpp 25 | This is the main DLL source file. 26 | 27 | When created, this DLL does not export any symbols. As a result, it 28 | will not produce a .lib file when it is built. If you wish this project 29 | to be a project dependency of some other project, you will either need to 30 | add code to export some symbols from the DLL so that an export library 31 | will be produced, or you can set the Ignore Input Library property to Yes 32 | on the General propert page of the Linker folder in the project's Property 33 | Pages dialog box. 34 | 35 | ///////////////////////////////////////////////////////////////////////////// 36 | Other standard files: 37 | 38 | StdAfx.h, StdAfx.cpp 39 | These files are used to build a precompiled header (PCH) file 40 | named TestDLL.pch and a precompiled types file named StdAfx.obj. 41 | 42 | ///////////////////////////////////////////////////////////////////////////// 43 | Other notes: 44 | 45 | AppWizard uses "TODO:" comments to indicate parts of the source code you 46 | should add to or customize. 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | -------------------------------------------------------------------------------- /TestDLL/TestDLL.cpp: -------------------------------------------------------------------------------- 1 | // TestDLL.cpp : Defines the exported functions for the DLL application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | 7 | -------------------------------------------------------------------------------- /TestDLL/TestDLL.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {3D5AF455-8361-4BA9-AF90-BF59CEED51FB} 24 | Win32Proj 25 | TestDLL 26 | 10.0.15063.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | 88 | 89 | Level3 90 | Disabled 91 | WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions) 92 | 93 | 94 | Windows 95 | 96 | 97 | 98 | 99 | 100 | 101 | Level3 102 | Disabled 103 | _DEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions) 104 | 105 | 106 | Windows 107 | 108 | 109 | 110 | 111 | Level3 112 | 113 | 114 | MaxSpeed 115 | true 116 | true 117 | WIN32;NDEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions) 118 | 119 | 120 | Windows 121 | true 122 | true 123 | 124 | 125 | 126 | 127 | Level3 128 | 129 | 130 | MaxSpeed 131 | true 132 | true 133 | NDEBUG;_WINDOWS;_USRDLL;TESTDLL_EXPORTS;%(PreprocessorDefinitions) 134 | 135 | 136 | Windows 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | false 151 | 152 | 153 | false 154 | 155 | 156 | false 157 | 158 | 159 | false 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /TestDLL/TestDLL.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 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /TestDLL/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "stdafx.h" 3 | 4 | BOOL APIENTRY DllMain( HMODULE hModule, 5 | DWORD ul_reason_for_call, 6 | LPVOID lpReserved 7 | ) 8 | { 9 | switch (ul_reason_for_call) 10 | { 11 | case DLL_PROCESS_ATTACH: 12 | ::MessageBoxW(NULL, L"I'm TestDLL.dll, You Load Succ!", L"", NULL); 13 | break; 14 | case DLL_THREAD_ATTACH: 15 | case DLL_THREAD_DETACH: 16 | case DLL_PROCESS_DETACH: 17 | break; 18 | } 19 | return TRUE; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /TestDLL/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // TestDLL.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /TestDLL/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | 14 | 15 | 16 | // TODO: reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /TestDLL/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | --------------------------------------------------------------------------------