├── .gitattributes ├── .github ├── FUNDING.yml └── dependabot.yml ├── .gitignore ├── LICENSE ├── PeNet.sln ├── PeNet.sln.DotSettings ├── README.md ├── azure-pipelines.yml ├── docfx ├── .gitignore ├── api │ ├── .gitignore │ └── index.md ├── articles │ ├── filehash.md │ ├── imphash.md │ ├── imports.md │ ├── intro.md │ ├── parseroptions.md │ ├── pdb.md │ ├── sections.md │ ├── toc.yml │ └── typerefhash.md ├── docfx.json ├── index.md └── toc.yml ├── docs └── info.txt ├── flake.lock ├── flake.nix ├── resource ├── facebook_cover_photo_2.png ├── facebook_profile_image.png ├── favicon.png ├── icon.png ├── icon_large.png ├── instagram_profile_image.png ├── linkedin_banner_image_1.png ├── linkedin_banner_image_2.png ├── linkedin_profile_image.png ├── logo.png ├── logo_transparent.png ├── pinterest_board_photo.png ├── pinterest_profile_image.png ├── twitter_header_photo_2.png ├── twitter_profile_image.png └── youtube_profile_image.png ├── src └── PeNet │ ├── Crypto │ ├── Algorithm.cs │ ├── Hash.cs │ ├── Md5.cs │ ├── Pack.cs │ ├── Sha1.cs │ └── Sha256.cs │ ├── Editor │ ├── AdditionalImport.cs │ ├── Import.cs │ └── Section.cs │ ├── ExtensionMethods.cs │ ├── FileParser │ ├── BufferFile.cs │ ├── IRawFile.cs │ ├── MMFile.cs │ └── StreamFile.cs │ ├── Header │ ├── AbstractStructure.cs │ ├── Authenticode │ │ ├── AuthenticodeInfo.cs │ │ ├── CrlUrlList.cs │ │ └── X509AuthentiCodeInfo.cs │ ├── ImpHash │ │ ├── ImportHash.cs │ │ └── OrdinalSymbolMapping.cs │ ├── Net │ │ ├── CodedIndex.cs │ │ ├── HeapSizes.cs │ │ ├── MetaDataHdr.cs │ │ ├── MetaDataStreamGuid.cs │ │ ├── MetaDataStreamHdr.cs │ │ ├── MetaDataStreamString.cs │ │ ├── MetaDataStreamUs.cs │ │ ├── MetaDataTables │ │ │ ├── AbstractTable.cs │ │ │ ├── Assembly.cs │ │ │ ├── AssemblyOS.cs │ │ │ ├── AssemblyProcessor.cs │ │ │ ├── AssemblyRef.cs │ │ │ ├── AssemblyRefOS.cs │ │ │ ├── AssemblyRefProcessor.cs │ │ │ ├── ClassLayout.cs │ │ │ ├── Constant.cs │ │ │ ├── CustomAttribute.cs │ │ │ ├── DeclSecurity.cs │ │ │ ├── Event.cs │ │ │ ├── EventMap.cs │ │ │ ├── ExportedType.cs │ │ │ ├── Field.cs │ │ │ ├── FieldLayout.cs │ │ │ ├── FieldMarshal.cs │ │ │ ├── FieldRVA.cs │ │ │ ├── File.cs │ │ │ ├── GenericParam.cs │ │ │ ├── GenericParamConstraint.cs │ │ │ ├── ImplMap.cs │ │ │ ├── InterfaceImpl.cs │ │ │ ├── ManifestResource.cs │ │ │ ├── MemberRef.cs │ │ │ ├── MethodDef.cs │ │ │ ├── MethodImpl.cs │ │ │ ├── MethodSemantics.cs │ │ │ ├── Module.cs │ │ │ ├── ModuleRef.cs │ │ │ ├── NestedClass.cs │ │ │ ├── Param.cs │ │ │ ├── Property.cs │ │ │ ├── PropertyMap.cs │ │ │ ├── StandAloneSig.cs │ │ │ ├── Tables.cs │ │ │ ├── TypeDef.cs │ │ │ ├── TypeRef.cs │ │ │ └── TypeSpec.cs │ │ ├── MetaDataTablesHdr.cs │ │ ├── NetGuids.cs │ │ └── TypeRefHash.cs │ ├── Pe │ │ ├── Copyright.cs │ │ ├── ExportFunction.cs │ │ ├── ImageBaseRelocation.cs │ │ ├── ImageBoundImportDescriptor.cs │ │ ├── ImageCor20Header.cs │ │ ├── ImageDataDirectory.cs │ │ ├── ImageDebugDirectory.cs │ │ ├── ImageDelayImportDescriptor.cs │ │ ├── ImageDosHeader.cs │ │ ├── ImageExportDirectory.cs │ │ ├── ImageFileHeader.cs │ │ ├── ImageImportByName.cs │ │ ├── ImageImportDescriptor.cs │ │ ├── ImageLoadConfigDirectory.cs │ │ ├── ImageNtHeaders.cs │ │ ├── ImageOptionalHeader.cs │ │ ├── ImageResourceDataEntry.cs │ │ ├── ImageResourceDirStringU.cs │ │ ├── ImageResourceDirectory.cs │ │ ├── ImageResourceDirectoryEntry.cs │ │ ├── ImageSectionHeader.cs │ │ ├── ImageThunkData.cs │ │ ├── ImageTlsCallback.cs │ │ ├── ImageTlsDirectory.cs │ │ ├── ImportFunction.cs │ │ ├── RuntimeFunction.cs │ │ ├── UnwindCode.cs │ │ ├── UnwindInfo.cs │ │ └── WinCertificate.cs │ └── Resource │ │ ├── CvInfoPdb70.cs │ │ ├── GroupIconDirectory.cs │ │ ├── GroupIconDirectoryEntry.cs │ │ ├── Icon.cs │ │ ├── ResourceLocation.cs │ │ ├── Resources.cs │ │ ├── StringFileInfo.cs │ │ ├── StringTable.cs │ │ ├── TString.cs │ │ ├── Var.cs │ │ ├── VarFileInfo.cs │ │ ├── VsFixedFileInfo.cs │ │ └── VsVersionInfo.cs │ ├── HeaderParser │ ├── Authenticode │ │ └── AuthenticodeParser.cs │ ├── Net │ │ ├── DotNetStructureParsers.cs │ │ ├── MetaDataHdrParser.cs │ │ ├── MetaDataStreamBlobParser.cs │ │ ├── MetaDataStreamGUIDParser.cs │ │ ├── MetaDataStreamStringParser.cs │ │ ├── MetaDataStreamTablesHeaderParser.cs │ │ └── MetaDataStreamUSParser.cs │ ├── Pe │ │ ├── DataDirectoryParsers.cs │ │ ├── DelayImportedFunctionsParser.cs │ │ ├── ExportedFunctionsParser.cs │ │ ├── ImageBaseRelocationsParser.cs │ │ ├── ImageBoundImportDescriptorParser.cs │ │ ├── ImageCor20HeaderParser.cs │ │ ├── ImageDebugDirectoryParser.cs │ │ ├── ImageDelayImportDescriptorParser.cs │ │ ├── ImageDosHeaderParser.cs │ │ ├── ImageExportDirectoriesParser.cs │ │ ├── ImageImportDescriptorsParser.cs │ │ ├── ImageLoadConfigDirectoryParser.cs │ │ ├── ImageNtHeadersParser.cs │ │ ├── ImageResourceDirectoryParser.cs │ │ ├── ImageSectionHeadersParser.cs │ │ ├── ImageTlsDirectoryParser.cs │ │ ├── ImportedFunctionsParser.cs │ │ ├── NativeStructureParsers.cs │ │ ├── RuntimeFunctionsParser.cs │ │ └── WinCertificateParser.cs │ ├── Resource │ │ └── ResourcesParser.cs │ └── SafeParser.cs │ ├── NET48_Helpers.cs_ │ ├── PeFile.cs │ ├── PeNet.csproj │ ├── PeNet.csproj.DotSettings │ ├── PeNet.snk │ └── Properties │ └── PublishProfiles │ └── FolderProfile.pubxml └── test └── PeNet.Test ├── Binaries ├── AddImportsRegression.exe ├── DRWUI.exe ├── HelloWorld.TablesStream.ExtraData.exe ├── HelloWorld.exe ├── NetCoreConsole.dll ├── NetFrameworkConsole.exe ├── NetFrameworkConsole.exe.config ├── No_SEH.exe ├── README.md ├── TLSCallback_x64.dll ├── TLSCallback_x86.exe ├── TestCetCompatAndEhCont.exe ├── VB40032-2.DLL ├── VB40032.DLL ├── add-import.exe ├── add-section.exe ├── arm_binary.dll ├── arm_dotnet_binary.dll ├── cff-chrome_elf.dll ├── chrome_elf.dll ├── dotnet_x64.dll ├── filezilla_dll_without_Version.dll ├── firefox_invalid_x64.exe ├── firefox_invalid_x86.exe ├── firefox_x64.exe ├── firefox_x64_copy1.exe ├── firefox_x64_copy2.exe ├── firefox_x64_manipulated.exe ├── firefox_x86.exe ├── firefox_x86_2.exe ├── krnl_test.sys ├── mmf_test.bin ├── notPeFile.txt ├── old_firefox_x86.exe ├── osx_vb_netcore.dll ├── pdb_guid.exe ├── pidgin.exe ├── pidgin_manipulated_GroupIconDirectory.exe ├── pidgin_manipulated_GroupIconDirectory_withNullIcon.exe ├── pidgin_manipulated_Icons.exe ├── pidgin_two_icons_with_same_id.exe ├── pidgin_with_additional_firefox_version_entry.exe ├── pidgin_with_double_iconGroupEntries.exe ├── pidgin_with_iconGroupEntry_without_icon.exe ├── pidgin_with_one_icon_without_IconGroupDirectoryEntry.exe ├── pidgin_without_groupIconDirectory.exe ├── remove-section.exe └── win_test.dll ├── Editor ├── ImportTest.cs └── SectionTest.cs ├── FileParser ├── MMFileTest.cs └── StreamFileTest.cs ├── Header ├── AbstractStructureTest.cs ├── Authenticode │ ├── AuthenticodeHashTest.cs │ ├── AuthenticodeTest.cs │ ├── pidgin.pkcs7 │ └── pkcs7.bin ├── ImpHash │ └── ImpHashTest.cs ├── Net │ ├── MetaDataHdrTest.cs │ ├── MetaDataTablesHdrTest.cs │ ├── NetCoreConsoleTest.cs │ ├── NetFrameworkConsoleTest.cs │ ├── RawDotNetStructures.cs │ └── TypeRefHashTest.cs ├── Pe │ ├── CopyrightTest.cs │ ├── ImageBaseRelocationTest.cs │ ├── ImageBoundImportDescriptorTest.cs │ ├── ImageCor20HeaderTest.cs │ ├── ImageDataDirectoryTest.cs │ ├── ImageDebugDirectoryTest.cs │ ├── ImageDelayImportDescriptorTest.cs │ ├── ImageDosHeaderTest.cs │ ├── ImageExportDirectoryTest.cs │ ├── ImageFileHeaderTest.cs │ ├── ImageImportByNameTest.cs │ ├── ImageImportDescriptorTest.cs │ ├── ImageLoadConfigDirectoryTest.cs │ ├── ImageNtHeadersTest.cs │ ├── ImageOptionalHeaderTest.cs │ ├── ImageResourceDataEntryTest.cs │ ├── ImageResourceDirStringUTest.cs │ ├── ImageResourceDirectoryEntryTest.cs │ ├── ImageResourceDirectoryTest.cs │ ├── ImageSectionHeaderTest.cs │ ├── ImageThunkDateTest.cs │ ├── ImageTlsCallbackTest.cs │ ├── ImageTlsDirectoryTest.cs │ ├── RawStructures.cs │ ├── RuntimeFunctionTest.cs │ ├── UnwindCodeTest.cs │ ├── UnwindInfoTest.cs │ └── WinCertificateTest.cs └── Resource │ └── ResourcesTest.cs ├── Icons ├── README.md ├── firefox_x64.exe │ └── ico │ │ ├── Icon1.ico │ │ ├── Icon10.ico │ │ ├── Icon11.ico │ │ ├── Icon12.ico │ │ ├── Icon13.ico │ │ ├── Icon14.ico │ │ ├── Icon15.ico │ │ ├── Icon16.ico │ │ ├── Icon17.ico │ │ ├── Icon18.ico │ │ ├── Icon2.ico │ │ ├── Icon3.ico │ │ ├── Icon4.ico │ │ ├── Icon5.ico │ │ ├── Icon6.ico │ │ ├── Icon7.ico │ │ ├── Icon8.ico │ │ └── Icon9.ico └── pidgin.exe │ └── ico │ ├── Icon1.ico │ ├── Icon2.ico │ ├── Icon3.ico │ ├── Icon4.ico │ ├── Icon5.ico │ ├── Icon6.ico │ ├── Icon7.ico │ ├── Icon8.ico │ └── Icon9.ico ├── PeFileTest.cs └── PeNet.Test.csproj /.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 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: secana 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: nuget 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | -------------------------------------------------------------------------------- /PeNet.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28527.54 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7F4B3781-06A5-442E-A00C-926D0BC812D0}" 7 | ProjectSection(SolutionItems) = preProject 8 | .gitattributes = .gitattributes 9 | .gitignore = .gitignore 10 | azure-pipelines.yml = azure-pipelines.yml 11 | LICENSE = LICENSE 12 | README.md = README.md 13 | EndProjectSection 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C6BBC182-0EA7-4DEA-8D06-C7B27B863B92}" 16 | EndProject 17 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{B7DE051E-5D6F-4209-8472-B8A407C3D257}" 18 | EndProject 19 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PeNet", "src\PeNet\PeNet.csproj", "{12794D4D-98EA-4A5C-92EA-D3282790C3D3}" 20 | EndProject 21 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PeNet.Test", "test\PeNet.Test\PeNet.Test.csproj", "{2A160801-CC38-4986-AC00-B742ACC567D7}" 22 | EndProject 23 | Global 24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 25 | Debug|Any CPU = Debug|Any CPU 26 | Debug|x64 = Debug|x64 27 | Release|Any CPU = Release|Any CPU 28 | Release|x64 = Release|x64 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3}.Debug|x64.ActiveCfg = Debug|Any CPU 34 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3}.Debug|x64.Build.0 = Debug|Any CPU 35 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3}.Release|x64.ActiveCfg = Release|Any CPU 38 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3}.Release|x64.Build.0 = Release|Any CPU 39 | {2A160801-CC38-4986-AC00-B742ACC567D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {2A160801-CC38-4986-AC00-B742ACC567D7}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {2A160801-CC38-4986-AC00-B742ACC567D7}.Debug|x64.ActiveCfg = Debug|Any CPU 42 | {2A160801-CC38-4986-AC00-B742ACC567D7}.Debug|x64.Build.0 = Debug|Any CPU 43 | {2A160801-CC38-4986-AC00-B742ACC567D7}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {2A160801-CC38-4986-AC00-B742ACC567D7}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {2A160801-CC38-4986-AC00-B742ACC567D7}.Release|x64.ActiveCfg = Release|Any CPU 46 | {2A160801-CC38-4986-AC00-B742ACC567D7}.Release|x64.Build.0 = Release|Any CPU 47 | EndGlobalSection 48 | GlobalSection(SolutionProperties) = preSolution 49 | HideSolutionNode = FALSE 50 | EndGlobalSection 51 | GlobalSection(NestedProjects) = preSolution 52 | {12794D4D-98EA-4A5C-92EA-D3282790C3D3} = {C6BBC182-0EA7-4DEA-8D06-C7B27B863B92} 53 | {2A160801-CC38-4986-AC00-B742ACC567D7} = {B7DE051E-5D6F-4209-8472-B8A407C3D257} 54 | EndGlobalSection 55 | GlobalSection(ExtensibilityGlobals) = postSolution 56 | SolutionGuid = {DDEF9B8E-AB65-440B-86B9-BF0BE9BE5993} 57 | EndGlobalSection 58 | EndGlobal 59 | -------------------------------------------------------------------------------- /PeNet.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![license](https://img.shields.io/github/license/secana/penet.svg)](https://raw.githubusercontent.com/secana/PeNet/master/LICENSE) 2 | [![NuGet](https://img.shields.io/nuget/v/PeNet.svg)](https://www.nuget.org/packages/PeNet/) 3 | [![NuGet](https://img.shields.io/nuget/dt/PeNet.svg)](https://www.nuget.org/packages/PeNet/) 4 | [![Build](https://img.shields.io/azure-devops/build/secana/PeNet/2.svg)](https://dev.azure.com/secana/PeNet/_build?definitionId=2) 5 | [![Test](https://img.shields.io/azure-devops/tests/secana/PeNet/2.svg)](https://dev.azure.com/secana/PeNet/_build?definitionId=2) 6 | [![BuiltWithDot.Net shield](https://builtwithdot.net/project/492/penet-csharp-net-standard-file-parser/badge)](https://builtwithdot.net/project/492/penet-csharp-net-standard-file-parser) 7 | 8 | ![PeNet Logo](https://raw.githubusercontent.com/secana/PeNet/master/resource/linkedin_banner_image_2.png "PeNet - PE analysis made easy") 9 | PeNet is a parser for Windows Portable Executable headers. It completely written in C# and does not rely on any native Windows APIs. 10 | Furthermore it supports the creation of Import Hashes (ImpHash), which is a feature often used in malware analysis. You can extract Certificate Revocation List, compute different hash sums and other useful stuff for working with PE files. 11 | 12 | ## Getting Started & API Reference 13 | 14 | The API reference can be found here: [PeNet Documentation & API Reference](http://secana.github.io/PeNet). 15 | 16 | For an overview of *PeNet* or to analyze PE files go to: [penet.io](http://penet.io) 17 | 18 | ## Continuous Integration 19 | 20 | The project is automatically build, tested and released with an [Azure Pipeline](https://dev.azure.com/secana/PeNet). 21 | 22 | To release a new version, push a tagged commit. For example: 23 | 24 | ```powershell 25 | git tag -a v2.0.0 -m 'Release version 2.0.0' 26 | git push origin v2.0.0 27 | ``` 28 | -------------------------------------------------------------------------------- /docfx/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # folder # 3 | ############### 4 | /**/DROP/ 5 | /**/TEMP/ 6 | /**/packages/ 7 | /**/bin/ 8 | /**/obj/ 9 | ../docs 10 | -------------------------------------------------------------------------------- /docfx/api/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # temp file # 3 | ############### 4 | *.yml 5 | .manifest 6 | -------------------------------------------------------------------------------- /docfx/api/index.md: -------------------------------------------------------------------------------- 1 | # PeNet API Documentation 2 | 3 | In the left panel, you find the API documentation for all accessible structures and functionality of the PeNet library. -------------------------------------------------------------------------------- /docfx/articles/filehash.md: -------------------------------------------------------------------------------- 1 | # File Hashes 2 | 3 | When comparing PE files for equality, file hashes come in handy. **PeNet** exports the following file hashes for convenience reasons. 4 | 5 | The MD5 can be accessed with the property MD5 6 | 7 | ```csharp 8 | var pe = new PeNet.PeFile(@"c:\windows\system32\calc.exe"); 9 | Console.WriteLine($"MD5: {pe.Md5}"); 10 | ``` 11 | 12 | The SHA-1 can be accessed with the property SHA1 13 | 14 | ```csharp 15 | var pe = new PeNet.PeFile(@"c:\windows\system32\calc.exe"); 16 | Console.WriteLine($"SHA-1: {pe.Sha1}"); 17 | ``` 18 | 19 | The SHA-256 can be accessed with the property SHA256 20 | 21 | ```csharp 22 | var pe = new PeNet.PeFile(@"c:\windows\system32\calc.exe"); 23 | Console.WriteLine($"SHA256: {pe.Sha256}"); 24 | ``` -------------------------------------------------------------------------------- /docfx/articles/imphash.md: -------------------------------------------------------------------------------- 1 | # Import Hash 2 | 3 | The **Import Hash** (ImpHash) is a hash over the imported functions by PE file. It is often used in malware analysis to identify malware binaries that belong to the same family. 4 | 5 | You can access the **Import Hash** with **PeNet** like this: 6 | 7 | ```csharp 8 | var ih = peHeader.ImpHash 9 | ``` 10 | 11 | The algorithm works like the following: 12 | 13 | Resolve ordinals to function names when they appear and convert DLL name and function name to lower case. Now, remove the file extension from the imported module names. Store all strings in an ordered list and generate a MD5 over the list. The DLLs oleaut32, ws2_32 and wsock32 have a lot of ordinals without function names. That's why these DLL function names are resolved manually. This implementation is equal to the pefile 1.2.10-139 implementation of the ImpHash. -------------------------------------------------------------------------------- /docfx/articles/imports.md: -------------------------------------------------------------------------------- 1 | # Imports 2 | 3 | You can access the imported functions and also add imports to the PE file. 4 | 5 | ## Access Import Descriptors 6 | 7 | The following code snipped shows how to access the `IMAGE_IMPORT_DESCRIPTOR`, `IMAGE_BOUND_IMPORT_DESCRIPTOR` and `IMAGE_DELAY_IMPORT_DESCRIPTOR` arrays. 8 | 9 | ```csharp 10 | var peFile = new PeFile("myapp.exe"); 11 | 12 | var idescs = peFile.ImageImportDescriptors; 13 | var bdescs = peFile.ImageBoundImportDescriptor; 14 | var ddescs = peFile.ImageDelayImportDescriptor; 15 | ``` 16 | 17 | ## Access imported functions 18 | 19 | As a shortcut, it's possible to access the imported functions sorted by the module/DLL they are imported from. 20 | 21 | ```csharp 22 | var peFile = new PeFile("myapp.exe"); 23 | 24 | // Print all imported modules with their corresponding functions. 25 | foreach(var imp in peFile.ImportedFunctions) 26 | { 27 | Console.WriteLine($"{imp.DLL} - {imp.Name} - {imp.Hint} - {imp.IATOffset}"); 28 | } 29 | ``` 30 | 31 | ## Add Imports 32 | 33 | It is also possible to add new imports to the PE file. If the PE file is signed, the signature will be invalid afterwards. 34 | 35 | To add only **one import**, use the code below. 36 | 37 | ```csharp 38 | var peFile = new PeFile("myapp.exe"); 39 | peFile.AddImport("gdi32.dll", "StartPage"); 40 | ``` 41 | 42 | If you intend to add **multiple imports** from either the same module or different modules, use the function below. 43 | 44 | ```csharp 45 | var peFile = new PeFile("myapp.exe"); 46 | 47 | var ai1 = new AdditionalImport("gdi32.dll", new List { "StartPage" }); 48 | var ai2 = new AdditionalImport("ADVAPI32.dll", new List { "RegCloseKey" }); 49 | var importList = new List {ai1, ai2}; 50 | 51 | peFile.AddImports(importList); 52 | ``` 53 | -------------------------------------------------------------------------------- /docfx/articles/intro.md: -------------------------------------------------------------------------------- 1 | # PeNet Help and Examples 2 | 3 | You can find useful examples for different topics in the left pane. If you think that something is missing, feel free to create a pull request with a documentation update, of file an issue with what is missing. -------------------------------------------------------------------------------- /docfx/articles/pdb.md: -------------------------------------------------------------------------------- 1 | # PDB & Debug Information 2 | 3 | *PeNet* is able to extract *Code View PDB v7* information if one is present in a debug entry in the debug directory. 4 | 5 | The information is valuable for malware analysis, as the `PdbFileName` if often unique to a malware family. 6 | 7 | For memory forensics with [Rekall](https://github.com/google/rekall) or any debugger that uses PDB files, the `Signature` GUID can be used to download the correct PDB file from the [Microsoft public symbol server](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/microsoft-public-symbols). 8 | 9 | ```csharp 10 | using System; 11 | using System.Linq; 12 | using PeNet; 13 | 14 | namespace Pdb 15 | { 16 | class Program 17 | { 18 | static void Main(string[] args) 19 | { 20 | var peFile = new PeFile("peWithDbgInfo.exe"); 21 | 22 | // Select the first debug directory with 23 | // PDB information available. 24 | var pdbInfo = peFile 25 | .ImageDebugDirectory 26 | .First(idb => idb.CvInfoPdb70 != null) 27 | .CvInfoPdb70; 28 | 29 | // Print content of the Code View PDB v7 structure 30 | Console.WriteLine(pdbInfo); 31 | } 32 | } 33 | } 34 | ``` 35 | 36 | Output: 37 | 38 | ```shell 39 | CvInfoPdb70 40 | CvSignature: 1396986706 41 | Signature: 0de6dc23-8e19-4bb7-8608-d54b1e6fa379 42 | Age: 1 43 | PdbFileName: ntkrnlmp.pdb 44 | ``` 45 | -------------------------------------------------------------------------------- /docfx/articles/sections.md: -------------------------------------------------------------------------------- 1 | # Sections 2 | 3 | You can not only access the sections in the PE file but also add and remove section. 4 | 5 | ## Access sections 6 | 7 | Access the section table entries. 8 | 9 | ```csharp 10 | var peFile = new PeFile("myapp.exe"); 11 | 12 | // Get array with all section table entries. 13 | var sections = peFile.ImageSectionHeaders; 14 | ``` 15 | 16 | ## Add section 17 | 18 | Adds a new section at the end of the file. 19 | 20 | ```csharp 21 | var peFile = new PeFile("myapp.exe"); 22 | 23 | // Add a new section with the name ".name", the size 100 and section characteristics. 24 | // Section names have a max. length of 8 characters. 25 | peFile.AddSection(".name", 100, (ScnCharacteristicsType)0x40000040); 26 | ``` 27 | 28 | ## Remove section 29 | 30 | ```csharp 31 | var peFile = new PeFile("myapp.exe"); 32 | 33 | // Remove the resource section from the section table and the content 34 | // of the section from the file. 35 | peFile.RemoveSection(".rsrc"); 36 | 37 | // Alternatively you can only remove the section from the section table 38 | // and keep the content of the section in the file. 39 | peFile.RemoveSection(".rsrc", false); 40 | ``` 41 | -------------------------------------------------------------------------------- /docfx/articles/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Introduction 2 | href: intro.md 3 | - name: Parser Options 4 | href: parseroptions.md 5 | - name: Import Hash 6 | href: imphash.md 7 | - name: TypeRefHash 8 | href: typerefhash.md 9 | - name: File Hashes 10 | href: filehash.md 11 | - name: Export Data 12 | href: export.md 13 | - name: PDB and Debug Info 14 | href: pdb.md 15 | - name: Sections 16 | href: sections.md 17 | - name: Imports 18 | href: imports.md 19 | -------------------------------------------------------------------------------- /docfx/articles/typerefhash.md: -------------------------------------------------------------------------------- 1 | # TypeRefHash 2 | 3 | The TypeRefHash (TRH) is a hash similar to the ImpHash, but for .NET samples where the ImpHash does not work. 4 | It is calculated over the imported .NET namespaces and types and can be used to identify malware families which share code. 5 | 6 | ```csharp 7 | var peFile = new PeFile(file); 8 | 9 | // get the TRH as a hex-string. 10 | var trh = peFile.TypeRefHash; 11 | 12 | Console.WriteLine(trh); 13 | // prints for example the TRH: 14 | // > d633db771449e2c37e1689a8c291a4f4646ce156652a9dad5f67394c0d92a8c4 15 | ``` 16 | 17 | For more information on the TRH see: [Introducing the TypeRefHash (TRH)](https://www.gdatasoftware.com/blog/2020/06/36164-introducing-the-typerefhash-trh) -------------------------------------------------------------------------------- /docfx/docfx.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": [ 3 | { 4 | "src": [ 5 | { 6 | "files": ["**/PeNet.csproj"], 7 | "exclude": [ 8 | "**/bin/**", 9 | "**/obj/**" 10 | ], 11 | "src": "../src" 12 | } 13 | ], 14 | "dest": "api", 15 | "disableGitFeatures": false, 16 | "disableDefaultFilter": false, 17 | "properties": 18 | { 19 | "TargetFramework": "netstandard2.0" 20 | } 21 | } 22 | ], 23 | "build": { 24 | "content": [ 25 | { 26 | "files": [ 27 | "api/**.yml", 28 | "api/index.md" 29 | ] 30 | }, 31 | { 32 | "files": [ 33 | "articles/**.md", 34 | "articles/**/toc.yml", 35 | "toc.yml", 36 | "*.md" 37 | ] 38 | } 39 | ], 40 | "resource": [ 41 | { 42 | "files": [ 43 | "images/**" 44 | ] 45 | } 46 | ], 47 | "overwrite": [ 48 | { 49 | "files": [ 50 | "apidoc/**.md" 51 | ], 52 | "exclude": [ 53 | "obj/**", 54 | "../docs/**" 55 | ] 56 | } 57 | ], 58 | "dest": "../docs", 59 | "globalMetadataFiles": [], 60 | "fileMetadataFiles": [], 61 | "template": [ 62 | "default" 63 | ], 64 | "postProcessors": [], 65 | "markdownEngineName": "markdig", 66 | "noLangKeyword": false, 67 | "keepFileLink": false, 68 | "cleanupCacheHistory": false, 69 | "disableGitFeatures": false 70 | } 71 | } -------------------------------------------------------------------------------- /docfx/index.md: -------------------------------------------------------------------------------- 1 | # About **PeNet** 2 | 3 | PeNet is a library to parse and analyse Windows [Portable Executables (PE)](https://docs.microsoft.com/en-us/windows/desktop/Debug/pe-format) files. It is completely written in C# and compiles to a cross-platform conform .Net Standard library. 4 | 5 | Besides access to all typical PE structures (native and .Net header), some utility function like the [Import Hash](https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html) used in malware-analysis are provided. 6 | 7 | ## Quick Start 8 | 9 | This paragraph gives a short introduction on how to use PeNet with a few examples. For a full API documentation, see the link in the header. For more example check the Article link in the header. 10 | 11 | ### Install the library 12 | 13 | You can install PeNet into your project directly from [Nuget](https://www.nuget.org/packages/PeNet/). 14 | 15 | ### Open a PE file 16 | 17 | You can open a file on disk or parse a byte array of a PE file. 18 | 19 | ```csharp 20 | var peHeader1 = new PeNet.PeFile(@"C:\Windows\System32\kernel32.dll"); 21 | ``` 22 | 23 | ```csharp 24 | var bin = File.ReadAllBytes(@"C:\Windows\System32\kernel32.dll"); 25 | var peHeader2 = new PeNet.PeFile(bin); 26 | ``` 27 | 28 | For more information on the different methods to open a parse a PE file see: [Parser options](articles/parseroptions.md) 29 | 30 | ### Work with the PE header 31 | 32 | The parsed PE header is split into multiple modules and sub-modules. To see how the parser structures the PE header and which information can be found where see the API documentation page (link in header). Here are a few examples on how to access different parts of the PE header. For more examples, check the Article link in the header. 33 | 34 | Get the file alignment of the PE file: 35 | 36 | ```csharp 37 | var fileAlignment = peHeader.WindowsSpecificFields.FileAlignment; 38 | ``` 39 | 40 | Get the import descriptors of the PE file: 41 | 42 | ```csharp 43 | var if = peHeader.DataDirectories.ImageImportDescriptors; 44 | ``` 45 | 46 | Get the imported and exported functions of the PE file in a parsed form: 47 | 48 | ```csharp 49 | var if = peHeader.ImportedFunctions; 50 | var ef = peHeader.ExportedFunctions; 51 | ``` 52 | -------------------------------------------------------------------------------- /docfx/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Articles 2 | href: articles/ 3 | - name: Api Documentation 4 | href: api/ 5 | homepage: api/index.md 6 | -------------------------------------------------------------------------------- /docs/info.txt: -------------------------------------------------------------------------------- 1 | folder used to build API docs -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1743814133, 24 | "narHash": "sha256-drDyYyUmjeYGiHmwB9eOPTQRjmrq3Yz26knwmMPLZFk=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "250b695f41e0e2f5afbf15c6b12480de1fe0001b", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixpkgs-unstable", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "root": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nixpkgs": "nixpkgs" 41 | } 42 | }, 43 | "systems": { 44 | "locked": { 45 | "lastModified": 1681028828, 46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 47 | "owner": "nix-systems", 48 | "repo": "default", 49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "nix-systems", 54 | "repo": "default", 55 | "type": "github" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A flake for a .NET 8.0 development environment"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | }; 8 | 9 | outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: 10 | let 11 | pkgs = import nixpkgs { inherit system; }; 12 | in 13 | { 14 | devShells.default = pkgs.mkShell { 15 | buildInputs = [ 16 | pkgs.dotnet-sdk_8 17 | ]; 18 | }; 19 | } 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /resource/facebook_cover_photo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/facebook_cover_photo_2.png -------------------------------------------------------------------------------- /resource/facebook_profile_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/facebook_profile_image.png -------------------------------------------------------------------------------- /resource/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/favicon.png -------------------------------------------------------------------------------- /resource/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/icon.png -------------------------------------------------------------------------------- /resource/icon_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/icon_large.png -------------------------------------------------------------------------------- /resource/instagram_profile_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/instagram_profile_image.png -------------------------------------------------------------------------------- /resource/linkedin_banner_image_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/linkedin_banner_image_1.png -------------------------------------------------------------------------------- /resource/linkedin_banner_image_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/linkedin_banner_image_2.png -------------------------------------------------------------------------------- /resource/linkedin_profile_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/linkedin_profile_image.png -------------------------------------------------------------------------------- /resource/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/logo.png -------------------------------------------------------------------------------- /resource/logo_transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/logo_transparent.png -------------------------------------------------------------------------------- /resource/pinterest_board_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/pinterest_board_photo.png -------------------------------------------------------------------------------- /resource/pinterest_profile_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/pinterest_profile_image.png -------------------------------------------------------------------------------- /resource/twitter_header_photo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/twitter_header_photo_2.png -------------------------------------------------------------------------------- /resource/twitter_profile_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/twitter_profile_image.png -------------------------------------------------------------------------------- /resource/youtube_profile_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/resource/youtube_profile_image.png -------------------------------------------------------------------------------- /src/PeNet/Crypto/Algorithm.cs: -------------------------------------------------------------------------------- 1 | namespace PeNet.Crypto 2 | { 3 | internal enum Algorithm 4 | { 5 | Md5, 6 | Sha1, 7 | Sha256 8 | } 9 | } -------------------------------------------------------------------------------- /src/PeNet/Crypto/Pack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PeNet.Crypto 4 | { 5 | internal static class Pack 6 | { 7 | internal static void UInt32_To_BE(uint n, Span bs, int off) 8 | { 9 | bs[off] = (byte)(n >> 24); 10 | bs[off + 1] = (byte)(n >> 16); 11 | bs[off + 2] = (byte)(n >> 8); 12 | bs[off + 3] = (byte)(n); 13 | } 14 | 15 | internal static uint BE_To_UInt32(Span bs, int off) 16 | { 17 | return (uint)bs[off] << 24 18 | | (uint)bs[off + 1] << 16 19 | | (uint)bs[off + 2] << 8 20 | | (uint)bs[off + 3]; 21 | } 22 | 23 | internal static void UInt32_To_LE(uint n, Span bs, int off) 24 | { 25 | bs[off] = (byte)(n); 26 | bs[off + 1] = (byte)(n >> 8); 27 | bs[off + 2] = (byte)(n >> 16); 28 | bs[off + 3] = (byte)(n >> 24); 29 | } 30 | 31 | internal static uint LE_To_UInt32(Span bs, int off) 32 | { 33 | return (uint)bs[off] 34 | | (uint)bs[off + 1] << 8 35 | | (uint)bs[off + 2] << 16 36 | | (uint)bs[off + 3] << 24; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/PeNet/Editor/AdditionalImport.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace PeNet 4 | { 5 | /// 6 | /// Additional import used to add new 7 | /// imports to the PE file. 8 | /// 9 | public class AdditionalImport 10 | { 11 | /// 12 | /// Module name to add the imports from, e.g. "kernel32.dll" or "HAL.dll". 13 | /// 14 | public string Module { get; } 15 | 16 | /// 17 | /// List with functions names to import from the module. 18 | /// 19 | public List Functions { get; } 20 | 21 | /// 22 | /// Create new instance. 23 | /// 24 | /// Module name to add the imports from, e.g. "kernel32.dll" or "HAL.dll". 25 | /// List with functions names to import from the module. 26 | public AdditionalImport(string module, List funcs) 27 | { 28 | Module = module; 29 | Functions = funcs; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/PeNet/Header/AbstractStructure.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Reflection; 3 | using System.Text; 4 | using PeNet.FileParser; 5 | 6 | namespace PeNet.Header 7 | { 8 | /// 9 | /// Abstract class for a Windows structure. 10 | /// 11 | public abstract class AbstractStructure 12 | { 13 | /// 14 | /// A PE file. 15 | /// 16 | internal readonly IRawFile PeFile; 17 | 18 | /// 19 | /// The offset to the structure in the buffer. 20 | /// 21 | internal readonly long Offset; 22 | 23 | 24 | /// 25 | /// Creates a new AbstractStructure which holds fields 26 | /// that all structures have in common. 27 | /// 28 | /// A PE file. 29 | /// The offset to the structure in the buffer. 30 | protected AbstractStructure(IRawFile peFile, long offset) 31 | { 32 | PeFile = peFile; 33 | Offset = offset; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/PeNet/Header/Authenticode/X509AuthentiCodeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PeNet.Asn1; 3 | 4 | namespace PeNet.Header.Authenticode 5 | { 6 | public class ContentInfo 7 | { 8 | public Asn1Node? Content { get; } 9 | public string ContentType { get; } 10 | 11 | public ContentInfo(Span data) 12 | : this(Asn1Node.ReadNode(data.ToArray())) {} 13 | 14 | public ContentInfo(Asn1Node asn1) 15 | { 16 | var nodes = asn1.Nodes; 17 | // SEQUENCE with 1 or 2 elements 18 | if ((asn1.NodeType != Asn1UniversalNodeType.Sequence) || (nodes.Count < 1 && nodes.Count > 2)) 19 | throw new ArgumentException("Invalid ASN1"); 20 | if (!(nodes[0] is Asn1ObjectIdentifier)) 21 | throw new ArgumentException("Invalid contentType"); 22 | ContentType = ((Asn1ObjectIdentifier) nodes[0]).FriendlyName; 23 | if (nodes.Count <= 1) return; 24 | if (nodes[1].TagClass != Asn1TagClass.ContextDefined || nodes[1].TagForm != Asn1TagForm.Constructed) 25 | throw new ArgumentException("Invalid content"); 26 | Content = nodes[1]; 27 | } 28 | } 29 | 30 | public class SignedData 31 | { 32 | public SignedData(Asn1Node asn1) 33 | { 34 | var node = asn1.Nodes[0]; 35 | if ((node.NodeType != Asn1UniversalNodeType.Sequence) || (node.Nodes.Count < 4)) 36 | throw new ArgumentException("Invalid SignedData"); 37 | 38 | if (node.Nodes[0].NodeType != Asn1UniversalNodeType.Integer) 39 | throw new ArgumentException("Invalid version"); 40 | 41 | ContentInfo = new ContentInfo(node.Nodes[2]); 42 | } 43 | 44 | public ContentInfo ContentInfo { get; } 45 | } 46 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Net/HeapSizes.cs: -------------------------------------------------------------------------------- 1 | namespace PeNet.Header.Net 2 | { 3 | /// 4 | /// Size of the meta data heaps. 5 | /// 6 | public class HeapSizes 7 | { 8 | /// 9 | /// Size of the offsets into the "String" heap. 10 | /// 11 | public uint String {get;} 12 | 13 | /// 14 | /// Size of the offset into the "Guid" heap. 15 | /// 16 | public uint Guid {get;} 17 | 18 | /// 19 | /// Size of the offset into the "Blob" heap. 20 | /// 21 | public uint Blob {get;} 22 | 23 | /// 24 | /// Gets a value indicating whether the tables stream header contains an additional 32-bits after the table 25 | /// row counts. 26 | /// 27 | /// 28 | /// This is an undocumented feature of the CLR. 29 | /// See also: https://github.com/dotnet/runtime/blob/ce2165d8084cca98b95f5d8ff9386759bfd8c722/src/coreclr/md/runtime/metamodel.cpp#L290 30 | /// 31 | public bool HasExtraData { get; } 32 | 33 | /// 34 | /// Create a new HeapSizes instances. 35 | /// 36 | /// HeapSizes value from the MetaDataTablesHdr. 37 | public HeapSizes(byte heapSizes) 38 | { 39 | String = (heapSizes & 0x1) == 0 ? 2U: 4U; 40 | Guid = (heapSizes & 0x2) == 0 ? 2U: 4U; 41 | Blob = (heapSizes & 0x4) == 0 ? 2U: 4U; 42 | HasExtraData = (heapSizes & 0x40) == 0; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataStreamGuid.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using PeNet.FileParser; 5 | 6 | namespace PeNet.Header.Net 7 | { 8 | /// 9 | /// Represents the "GUID" meta data stream from the .Net header which 10 | /// contains all application GUIDs to idenfitfy different assembly versions. 11 | /// 12 | public class MetaDataStreamGuid : AbstractStructure 13 | { 14 | private readonly uint _size; 15 | 16 | /// 17 | /// List with all GUIDs from the Meta Data stream "GUID". 18 | /// 19 | public List Guids { get; } 20 | 21 | /// 22 | /// List with all GUIDs and their index from the 23 | /// Meta Data stream "GUID". 24 | /// 25 | public List> GuidsAndIndices { get; } 26 | 27 | public MetaDataStreamGuid(IRawFile peFile, long offset, uint size) 28 | : base(peFile, offset) 29 | { 30 | _size = size; 31 | GuidsAndIndices = ParseGuidsAndIndices(); 32 | Guids = GuidsAndIndices.Select(x => x.Item1).ToList(); 33 | } 34 | 35 | /// 36 | /// Return the GUID at the index from the stream. 37 | /// 38 | /// Index of the GUID to return. 39 | /// GUID at the position index. Null if not available. 40 | public Guid? GetGuidAtIndex(uint index) 41 | { 42 | return GuidsAndIndices.FirstOrDefault(x => x.Item2 == index)?.Item1; 43 | } 44 | 45 | private List> ParseGuidsAndIndices() 46 | { 47 | // A GUID is an 128 bit (16 bytes) long identifier 48 | var numOfGuiDs = _size / 16; 49 | var guidsAndIndicies = new List>((int)numOfGuiDs); 50 | 51 | for (var i = Offset; i < Offset + _size; i += 16) 52 | { 53 | #if NET48 || NETSTANDARD2_0 54 | guidsAndIndicies.Add(new Tuple(new Guid(PeFile.AsSpan(i, 16).ToArray()), (uint)guidsAndIndicies.Count + 1)); 55 | #else 56 | guidsAndIndicies.Add(new Tuple(new Guid(PeFile.AsSpan(i, 16)), (uint) guidsAndIndicies.Count + 1)); 57 | #endif 58 | } 59 | 60 | return guidsAndIndicies; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataStreamHdr.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net 4 | { 5 | /// 6 | /// The Meta Data Stream Header contains information about data streams (sections) 7 | /// in a .Net assembly. 8 | /// 9 | public class MetaDataStreamHdr : AbstractStructure 10 | { 11 | internal uint HeaderLength => GetHeaderLength(); 12 | 13 | /// 14 | /// Create a new Meta Data Stream Header instance from a byte array. 15 | /// 16 | /// PE file which contains a Meta Data Stream Header. 17 | /// Offset in the buffer, where the header starts. 18 | public MetaDataStreamHdr(IRawFile peFile, long offset) 19 | : base(peFile, offset) 20 | { 21 | } 22 | 23 | /// 24 | /// Relative offset (from Meta Data Header) to 25 | /// the stream. 26 | /// 27 | public uint RelOffset 28 | { 29 | get => PeFile.ReadUInt(Offset); 30 | set => PeFile.WriteUInt(Offset, value); 31 | } 32 | 33 | /// 34 | /// Size of the stream content. 35 | /// 36 | public uint Size 37 | { 38 | get => PeFile.ReadUInt(Offset + 0x4); 39 | set => PeFile.WriteUInt(Offset + 0x4, value); 40 | } 41 | 42 | /// 43 | /// Name of the stream. 44 | /// 45 | public string StreamName => PeFile.ReadAsciiString(Offset + 0x8); 46 | 47 | private uint GetHeaderLength() 48 | { 49 | var maxHeaderLength = 100; 50 | var headerLength = 0; 51 | for (var inHdrOffset = 8; inHdrOffset < maxHeaderLength; inHdrOffset++) 52 | { 53 | if (PeFile.ReadByte(Offset + inHdrOffset) == 0x00) 54 | { 55 | headerLength = inHdrOffset; 56 | break; 57 | } 58 | 59 | } 60 | 61 | return (uint) AddHeaderPaddingLength(headerLength); 62 | } 63 | 64 | private int AddHeaderPaddingLength(int headerLength) 65 | { 66 | if (headerLength%4 == 0) 67 | return headerLength + 4; 68 | else 69 | { 70 | return headerLength + (4-(headerLength%4)); 71 | } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataStreamString.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net 4 | { 5 | /// 6 | /// Represents the "String" meta data stream from the .Net header which 7 | /// contains all application interal strings. 8 | /// 9 | public class MetaDataStreamString : AbstractStructure 10 | { 11 | private readonly uint _size; 12 | 13 | public MetaDataStreamString(IRawFile peFile, long offset, uint size) 14 | : base(peFile, offset) 15 | { 16 | _size = size; 17 | } 18 | 19 | /// 20 | /// Return the string at the index from the stream. 21 | /// 22 | /// Index of the string to return. 23 | /// String at the position index. 24 | public string GetStringAtIndex(uint index) 25 | { 26 | return PeFile.ReadAsciiString(Offset + index); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataStreamUs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using PeNet.FileParser; 5 | 6 | namespace PeNet.Header.Net 7 | { 8 | /// 9 | /// Represents the "US" (user string) meta data stream from the .Net header which 10 | /// contains all application internal strings. 11 | /// 12 | public class MetaDataStreamUs : AbstractStructure 13 | { 14 | private readonly uint _size; 15 | 16 | /// 17 | /// List with strings in the Meta Data stream "US". 18 | /// 19 | public List UserStrings { get; } 20 | 21 | /// 22 | /// List with strings and their index in the Meta Data stream "US". 23 | /// 24 | public List> UserStringsAndIndices { get; } 25 | 26 | public MetaDataStreamUs(IRawFile peFile, long offset, uint size) 27 | : base(peFile, offset) 28 | { 29 | _size = size; 30 | UserStringsAndIndices = ParseUserStringsAndIndices(); 31 | UserStrings = UserStringsAndIndices.Select(x => x.Item1).ToList(); 32 | 33 | } 34 | 35 | /// 36 | /// Return the user string at the index from the stream. 37 | /// 38 | /// Index of the user string to return. 39 | /// User string at the position index. 40 | public string? GetUserStringAtIndex(uint index) 41 | { 42 | return UserStringsAndIndices.FirstOrDefault(x => x.Item2 == index)?.Item1; 43 | } 44 | 45 | private List> ParseUserStringsAndIndices() 46 | { 47 | var stringsAndIncides = new List>(); 48 | 49 | // The #US stream starts with a "0x00" byte. That's why 50 | // we skip the first byte in the buffer 51 | for (var i = Offset + 1; i < Offset + _size; i++) 52 | { 53 | if (PeFile.ReadByte(i) >= 0x80) // Not sure why this works but it does. 54 | i++; 55 | 56 | int length = PeFile.ReadByte(i); 57 | 58 | if (length == 0) // Stop if a string has the length 0 since the end 59 | break; // of the list is reached. 60 | 61 | i += 1; // Add "length byte" to current offset. 62 | var tmpString = PeFile.ReadUnicodeString(i); // Read the UTF-16 string 63 | i += (uint)length - 1; // Add the string length to the current offset. 64 | 65 | stringsAndIncides.Add(new Tuple(tmpString, (uint) i - (uint) length - (uint) Offset)); 66 | } 67 | 68 | return stringsAndIncides; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/AbstractTable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PeNet.FileParser; 3 | 4 | namespace PeNet.Header.Net.MetaDataTables 5 | { 6 | public class AbstractTable : AbstractStructure 7 | { 8 | protected HeapSizes HeapSizes {get;} 9 | protected IndexSize IndexSizes {get;} 10 | protected long CurrentOffset; 11 | 12 | public AbstractTable(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 13 | : base(peFile, offset) 14 | { 15 | HeapSizes = heapSizes; 16 | IndexSizes = indexSizes; 17 | CurrentOffset = Offset; 18 | } 19 | 20 | private uint ReadSize(uint size, ref long offset) 21 | { 22 | switch(size) 23 | { 24 | case 1: 25 | offset += 1; 26 | return PeFile.ReadByte(offset - 1); 27 | case 2: 28 | offset += 2; 29 | return PeFile.ReadUShort(offset - 2); 30 | case 4: 31 | offset += 4; 32 | return PeFile.ReadUInt(offset - 4); 33 | default: 34 | throw new ArgumentException("Unsupported offset size."); 35 | } 36 | } 37 | 38 | protected uint ReadSize(uint size) 39 | { 40 | return ReadSize(size, ref CurrentOffset); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/Assembly.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class Assembly : AbstractTable 6 | { 7 | public Assembly(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | HashAlgId = ReadSize(4); 11 | MajorVersion = (ushort) ReadSize(2); 12 | MinorVersion = (ushort) ReadSize(2); 13 | BuildNumber = (ushort) ReadSize(2); 14 | RevisionNumber = (ushort) ReadSize(2); 15 | Flags = ReadSize(4); 16 | PublicKey = ReadSize(HeapSizes.Blob); 17 | Name = ReadSize(HeapSizes.String); 18 | Culture = ReadSize(HeapSizes.String); 19 | } 20 | 21 | public uint HashAlgId {get;} 22 | public ushort MajorVersion {get;} 23 | public ushort MinorVersion {get;} 24 | public ushort BuildNumber {get;} 25 | public ushort RevisionNumber {get;} 26 | public uint Flags {get;} 27 | public uint PublicKey {get;} 28 | public uint Name {get;} 29 | public uint Culture {get;} 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/AssemblyOS.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class AssemblyOS : AbstractTable 6 | { 7 | public AssemblyOS(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | OSPlatformID = ReadSize(4); 11 | OSMajorVersion = ReadSize(4); 12 | OSMinorVersion = ReadSize(4); 13 | } 14 | 15 | public uint OSPlatformID {get;} 16 | public uint OSMajorVersion {get;} 17 | public uint OSMinorVersion {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/AssemblyProcessor.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class AssemblyProcessor : AbstractTable 6 | { 7 | public AssemblyProcessor(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Processor = ReadSize(4); 11 | } 12 | 13 | public uint Processor {get;} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/AssemblyRef.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class AssemblyRef : AbstractTable 6 | { 7 | public AssemblyRef(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | MajorVersion = (ushort) ReadSize(2); 11 | MinorVersion = (ushort) ReadSize(2); 12 | BuildNumber = (ushort) ReadSize(2); 13 | RevisionNumber = (ushort) ReadSize(2); 14 | Flags = ReadSize(4); 15 | PublicKeyOrToken = ReadSize(HeapSizes.Blob); 16 | Name = ReadSize(HeapSizes.String); 17 | Culture = ReadSize(HeapSizes.String); 18 | HashValue = ReadSize(HeapSizes.Blob); 19 | } 20 | 21 | public ushort MajorVersion {get;} 22 | public ushort MinorVersion {get;} 23 | public ushort BuildNumber {get;} 24 | public ushort RevisionNumber {get;} 25 | public uint Flags {get;} 26 | public uint PublicKeyOrToken {get;} 27 | public uint Name {get;} 28 | public uint Culture {get;} 29 | public uint HashValue {get;} 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/AssemblyRefOS.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class AssemblyRefOS : AbstractTable 6 | { 7 | public AssemblyRefOS(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | OSPlatformID = ReadSize(4); 11 | OSMajorVersion = ReadSize(4); 12 | OSMinorVersion = ReadSize(4); 13 | AssemblyRef = ReadSize(IndexSizes[Index.AssemblyRef]); 14 | } 15 | 16 | public uint OSPlatformID {get;} 17 | public uint OSMajorVersion {get;} 18 | public uint OSMinorVersion {get;} 19 | public uint AssemblyRef {get;} 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/AssemblyRefProcessor.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class AssemblyRefProcessor : AbstractTable 6 | { 7 | public AssemblyRefProcessor(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Processor = ReadSize(4); 11 | AssemblyRef = ReadSize(IndexSizes[Index.AssemblyRef]); 12 | } 13 | 14 | public uint Processor {get;} 15 | public uint AssemblyRef {get;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/ClassLayout.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class ClassLayout : AbstractTable 6 | { 7 | public ClassLayout(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | PackingSize = (ushort) ReadSize(2); 11 | ClassSize = ReadSize(4); 12 | Parent = ReadSize(IndexSizes[Index.TypeDef]); 13 | } 14 | 15 | public ushort PackingSize {get;} 16 | public uint ClassSize {get;} 17 | public uint Parent {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/Constant.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class Constant : AbstractTable 6 | { 7 | public Constant(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Type = (byte) ReadSize(1); 11 | CurrentOffset += 1; // Padding after "Type" 12 | Parent = ReadSize(IndexSizes[Index.HasConstant]); 13 | Value = ReadSize(HeapSizes.Blob); 14 | } 15 | 16 | public byte Type {get;} 17 | public uint Parent {get;} 18 | public uint Value {get;} 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/CustomAttribute.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class CustomAttribute : AbstractTable 6 | { 7 | public CustomAttribute(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Parent = ReadSize(IndexSizes[Index.HasCustomAttribute]); 11 | Type = ReadSize(IndexSizes[Index.CustomAttributeType]); 12 | Value = ReadSize(HeapSizes.Blob); 13 | } 14 | 15 | public uint Parent {get;} 16 | public uint Type {get;} 17 | public uint Value {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/DeclSecurity.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class DeclSecurity : AbstractTable 6 | { 7 | public DeclSecurity(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Action = (ushort) ReadSize(2); 11 | Parent = ReadSize(IndexSizes[Index.HasDeclSecurity]); 12 | PermissionSet = ReadSize(HeapSizes.Blob); 13 | } 14 | 15 | public ushort Action {get;} 16 | public uint Parent {get;} 17 | public uint PermissionSet {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/Event.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class Event : AbstractTable 6 | { 7 | public Event(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | EventFlags = (ushort) ReadSize(2); 11 | Name = ReadSize(HeapSizes.String); 12 | EventType = ReadSize(IndexSizes[Index.TypeDefOrRef]); 13 | } 14 | 15 | public ushort EventFlags {get;} 16 | public uint Name {get;} 17 | public uint EventType {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/EventMap.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class EventMap : AbstractTable 6 | { 7 | public EventMap(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Parent = ReadSize(IndexSizes[Index.TypeDef]); 11 | EventList = ReadSize(IndexSizes[Index.Event]); 12 | } 13 | 14 | public uint Parent {get;} 15 | public uint EventList {get;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/ExportedType.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class ExportedType : AbstractTable 6 | { 7 | public ExportedType(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Flags = ReadSize(4); 11 | TypeDefId = ReadSize(IndexSizes[Index.TypeDef]); 12 | TypeName = ReadSize(HeapSizes.String); 13 | TypeNamespace = ReadSize(HeapSizes.String); 14 | } 15 | 16 | public uint Flags {get;} 17 | public uint TypeDefId {get;} 18 | public uint TypeName {get;} 19 | public uint TypeNamespace {get;} 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/Field.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class Field : AbstractTable 6 | { 7 | public Field(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Flags = (ushort) ReadSize(2); 11 | Name = ReadSize(HeapSizes.String); 12 | Signature = ReadSize(HeapSizes.Blob); 13 | } 14 | 15 | public ushort Flags {get;} 16 | 17 | public uint Name {get;} 18 | 19 | public uint Signature {get;} 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/FieldLayout.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class FieldLayout : AbstractTable 6 | { 7 | public FieldLayout(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Offset = ReadSize(4); 11 | Field = ReadSize(IndexSizes[Index.Field]); 12 | } 13 | 14 | public new uint Offset {get;} 15 | public uint Field {get;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/FieldMarshal.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class FieldMarshal : AbstractTable 6 | { 7 | public FieldMarshal(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Parent = ReadSize(IndexSizes[Index.HasFieldMarshal]); 11 | NativeType = ReadSize(HeapSizes.Blob); 12 | } 13 | 14 | public uint Parent {get;} 15 | public uint NativeType {get;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/FieldRVA.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class FieldRVA : AbstractTable 6 | { 7 | public FieldRVA(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | RVA = ReadSize(4); 11 | Field = ReadSize(IndexSizes[Index.Field]); 12 | } 13 | 14 | public uint RVA {get;} 15 | public uint Field {get;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/File.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class File : AbstractTable 6 | { 7 | public File(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Flags = ReadSize(4); 11 | Name = ReadSize(HeapSizes.String); 12 | HashValue = ReadSize(HeapSizes.Blob); 13 | } 14 | 15 | public uint Flags {get;} 16 | public uint Name {get;} 17 | public uint HashValue {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/GenericParam.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class GenericParam : AbstractTable 6 | { 7 | public GenericParam(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Number = (ushort) ReadSize(2); 11 | Flags = (ushort) ReadSize(2); 12 | Owner = ReadSize(IndexSizes[Index.TypeOrMethodDef]); 13 | Name = ReadSize(HeapSizes.String); 14 | } 15 | 16 | public ushort Number {get;} 17 | public ushort Flags {get;} 18 | public uint Owner {get;} 19 | public uint Name {get;} 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/GenericParamConstraint.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class GenericParamConstraint : AbstractTable 6 | { 7 | public GenericParamConstraint(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Owner = ReadSize(IndexSizes[Index.GenericParam]); 11 | } 12 | 13 | public uint Owner {get;} 14 | public uint Constraint {get;} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/ImplMap.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class ImplMap : AbstractTable 6 | { 7 | public ImplMap(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | MappingFlags = (ushort) ReadSize(2); 11 | MemberForwarded = ReadSize(IndexSizes[Index.MemberForwarded]); 12 | ImportName = ReadSize(HeapSizes.String); 13 | ImportScope = ReadSize(IndexSizes[Index.ModuleRef]); 14 | } 15 | 16 | public ushort MappingFlags {get;} 17 | public uint MemberForwarded {get;} 18 | public uint ImportName {get;} 19 | public uint ImportScope {get;} 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/InterfaceImpl.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class InterfaceImpl : AbstractTable 6 | { 7 | public InterfaceImpl(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Class = ReadSize(IndexSizes[Index.TypeDef]); 11 | Interface = ReadSize(IndexSizes[Index.TypeDefOrRef]); 12 | } 13 | 14 | public uint Class {get;} 15 | public uint Interface {get;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/ManifestResource.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class ManifestResource : AbstractTable 6 | { 7 | public ManifestResource(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Offset = ReadSize(4); 11 | Flags = ReadSize(4); 12 | Name = ReadSize(HeapSizes.String); 13 | Implementation = ReadSize(IndexSizes[Index.Implementation]); 14 | } 15 | 16 | public new uint Offset {get;} 17 | public uint Flags {get;} 18 | public uint Name {get;} 19 | public uint Implementation {get;} 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/MemberRef.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class MemberRef : AbstractTable 6 | { 7 | public MemberRef(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Class = ReadSize(IndexSizes[Index.MemberRefParent]); 11 | Name = ReadSize(HeapSizes.String); 12 | Signature = ReadSize(HeapSizes.Blob); 13 | } 14 | 15 | public uint Class {get;} 16 | public uint Name {get;} 17 | public uint Signature {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/MethodDef.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class MethodDef : AbstractTable 6 | { 7 | public MethodDef(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | RVA = ReadSize(4); 11 | ImplFlags = (ushort) ReadSize(2); 12 | Flags = (ushort) ReadSize(2); 13 | Name = ReadSize(HeapSizes.String); 14 | Signature = ReadSize(HeapSizes.Blob); 15 | ParamList = ReadSize(IndexSizes[Index.Param]); 16 | } 17 | 18 | public uint RVA {get;} 19 | public ushort ImplFlags {get;} 20 | public ushort Flags {get;} 21 | public uint Name {get;} 22 | public uint Signature {get;} 23 | public uint ParamList {get;} 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/MethodImpl.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class MethodImpl : AbstractTable 6 | { 7 | public MethodImpl(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Class = ReadSize(IndexSizes[Index.TypeDef]); 11 | MethodBody = ReadSize(IndexSizes[Index.MethodDefOrRef]); 12 | MethodDeclaration = ReadSize(IndexSizes[Index.MethodDefOrRef]); 13 | } 14 | 15 | public uint Class {get;} 16 | public uint MethodBody {get;} 17 | public uint MethodDeclaration {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/MethodSemantics.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class MethodSemantics : AbstractTable 6 | { 7 | public MethodSemantics(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Semantics = (ushort) ReadSize(2); 11 | Method = ReadSize(IndexSizes[Index.MethodDef]); 12 | Association = ReadSize(IndexSizes[Index.HasSemantics]); 13 | } 14 | 15 | public ushort Semantics {get;} 16 | public uint Method {get;} 17 | public uint Association {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/Module.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class Module : AbstractTable 6 | { 7 | public Module(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | 11 | Generation = (ushort) ReadSize(2); 12 | Name = ReadSize(HeapSizes.String); 13 | Mvid = ReadSize(HeapSizes.Guid); 14 | EncId = ReadSize(HeapSizes.Guid); 15 | EncBaseId = ReadSize(HeapSizes.Guid); 16 | } 17 | 18 | public ushort Generation {get;} 19 | 20 | public uint Name {get;} 21 | 22 | public uint Mvid {get;} 23 | 24 | public uint EncId {get;} 25 | 26 | public uint EncBaseId {get;} 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/ModuleRef.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class ModuleRef : AbstractTable 6 | { 7 | public ModuleRef(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Name = ReadSize(HeapSizes.String); 11 | } 12 | 13 | public uint Name {get;} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/NestedClass.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class NestedClass : AbstractTable 6 | { 7 | public NestedClass(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | NestedClassType = ReadSize(IndexSizes[Index.TypeDef]); 11 | EnclosingClassType = ReadSize(IndexSizes[Index.TypeDef]); 12 | } 13 | 14 | public uint NestedClassType {get;} 15 | public uint EnclosingClassType {get;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/Param.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class Param : AbstractTable 6 | { 7 | public Param(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Flags = (ushort) ReadSize(2); 11 | Sequence = (ushort) ReadSize(2); 12 | Name = ReadSize(HeapSizes.String); 13 | } 14 | 15 | public ushort Flags {get;} 16 | public ushort Sequence {get;} 17 | public uint Name {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/Property.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class Property : AbstractTable 6 | { 7 | public Property(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Flags = (ushort) ReadSize(2); 11 | Name = ReadSize(HeapSizes.String); 12 | Type = ReadSize(HeapSizes.Blob); 13 | } 14 | 15 | public ushort Flags {get;} 16 | public uint Name {get;} 17 | public uint Type {get;} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/PropertyMap.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class PropertyMap : AbstractTable 6 | { 7 | public PropertyMap(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Parent = ReadSize(IndexSizes[Index.TypeDef]); 11 | PropertyList = ReadSize(IndexSizes[Index.Property]); 12 | } 13 | 14 | public uint Parent {get;} 15 | public uint PropertyList {get;} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/StandAloneSig.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class StandAloneSig : AbstractTable 6 | { 7 | public StandAloneSig(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Signature = ReadSize(HeapSizes.Blob); 11 | } 12 | 13 | public uint Signature {get;} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/Tables.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class Tables 6 | { 7 | public List? Module {get; set;} 8 | public List? TypeRef {get; set;} 9 | public List? TypeDef {get; set;} 10 | public List? Field {get; set;} 11 | public List? MethodDef {get; set;} 12 | public List? Param {get; set;} 13 | public List? InterfaceImpl {get; set;} 14 | public List? MemberRef {get; set;} 15 | public List? Constant {get; set;} 16 | public List? CustomAttribute {get; set;} 17 | public List? FieldMarshal {get; set;} 18 | public List? DeclSecurity {get; set;} 19 | public List? ClassLayout {get; set;} 20 | public List? FieldLayout {get; set;} 21 | public List? StandAloneSig {get; set;} 22 | public List? EventMap {get; set;} 23 | public List? Event {get; set;} 24 | public List? PropertyMap {get; set;} 25 | public List? Property {get; set;} 26 | public List? MethodSemantic {get; set;} 27 | public List? MethodImpl {get; set;} 28 | public List? ModuleRef {get; set;} 29 | public List? TypeSpec {get; set;} 30 | public List? ImplMap {get; set;} 31 | public List? FieldRVA {get; set;} 32 | public List? Assembly {get; set;} 33 | public List? AssemblyProcessor {get; set;} 34 | public List? AssemblyOS {get; set;} 35 | public List? AssemblyRef {get; set;} 36 | public List? AssemblyRefProcessor {get; set;} 37 | public List? AssemblyRefOS {get; set;} 38 | public List? File {get; set;} 39 | public List? ExportedType {get; set;} 40 | public List? ManifestResource {get; set;} 41 | public List? NestedClass {get; set;} 42 | public List? GenericParam {get; set;} 43 | public List? GenericParamConstraints {get; set;} 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/TypeDef.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class TypeDef : AbstractTable 6 | { 7 | public TypeDef(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Flags = ReadSize(4); 11 | Name = ReadSize(HeapSizes.String); 12 | Namespace = ReadSize(HeapSizes.String); 13 | Extends = ReadSize(IndexSizes[Index.TypeDefOrRef]); 14 | FieldList = ReadSize(IndexSizes[Index.Field]); 15 | MethodList = ReadSize(IndexSizes[Index.MethodDef]); 16 | } 17 | 18 | public uint Flags {get;} 19 | 20 | public uint Name {get;} 21 | 22 | public uint Namespace {get;} 23 | 24 | public uint Extends {get;} 25 | 26 | public uint FieldList {get;} 27 | 28 | public uint MethodList {get;} 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/TypeRef.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class TypeRef : AbstractTable 6 | { 7 | public TypeRef(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | ResolutionScope = ReadSize(IndexSizes[Index.ResolutionScope]); 11 | TypeName = ReadSize(HeapSizes.String); 12 | TypeNamespace = ReadSize(HeapSizes.String); 13 | } 14 | 15 | public uint ResolutionScope {get;} 16 | 17 | public uint TypeName {get;} 18 | 19 | public uint TypeNamespace {get;} 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/MetaDataTables/TypeSpec.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Net.MetaDataTables 4 | { 5 | public class TypeSpec : AbstractTable 6 | { 7 | public TypeSpec(IRawFile peFile, long offset, HeapSizes heapSizes, IndexSize indexSizes) 8 | : base(peFile, offset, heapSizes, indexSizes) 9 | { 10 | Signature = ReadSize(HeapSizes.Blob); 11 | } 12 | 13 | public uint Signature {get;} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/PeNet/Header/Net/TypeRefHash.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using PeNet.Crypto; 5 | 6 | namespace PeNet.Header.Net 7 | { 8 | public class TypeRefHash 9 | { 10 | public MetaDataTablesHdr? MdtHdr { get; } 11 | public MetaDataStreamString? MdsStream { get; } 12 | 13 | public TypeRefHash(MetaDataTablesHdr? mdtHdr, MetaDataStreamString? mdsStream) 14 | => (MdtHdr, MdsStream) = (mdtHdr, mdsStream); 15 | 16 | public string? ComputeHash() 17 | { 18 | static string GetSha256(string typeRefsAsString) 19 | { 20 | var input = Encoding.UTF8.GetBytes(typeRefsAsString); 21 | return Hash.ComputeHash(input, Algorithm.Sha256); 22 | } 23 | 24 | var typeRefs = MdtHdr?.Tables.TypeRef; 25 | if (typeRefs is null || MdsStream is null || MdtHdr?.TableDefinitions[(int)MetadataToken.TypeReference].IsInvalid == true) return null; 26 | 27 | try 28 | { 29 | var namespacesAndTypes = typeRefs 30 | .OrderBy(t => MdsStream.GetStringAtIndex(t.TypeNamespace)) 31 | .ThenBy(t => MdsStream.GetStringAtIndex(t.TypeName)) 32 | .Select(t => string.Join("-", 33 | MdsStream.GetStringAtIndex(t.TypeNamespace), 34 | MdsStream.GetStringAtIndex(t.TypeName) 35 | )) 36 | .ToList(); 37 | 38 | var typeRefsAsString = string.Join(",", namespacesAndTypes); 39 | return GetSha256(typeRefsAsString); 40 | } 41 | catch (Exception) { return null; } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/Copyright.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// The copyright ASCII (not 0-terminated) string of the PE file 7 | /// if any is given. 8 | /// 9 | public class Copyright : AbstractStructure 10 | { 11 | /// 12 | /// Create a new copyright object. 13 | /// 14 | /// A PE file. 15 | /// Offset to the copyright string in the binary. 16 | public Copyright(IRawFile peFile, long offset) 17 | : base(peFile, offset) 18 | { 19 | } 20 | 21 | /// 22 | /// The copyright string. 23 | /// 24 | public string CopyrightString => PeFile.ReadAsciiString(Offset); 25 | } 26 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ExportFunction.cs: -------------------------------------------------------------------------------- 1 | namespace PeNet.Header.Pe 2 | { 3 | /// 4 | /// Represents an exported function. 5 | /// 6 | public class ExportFunction 7 | { 8 | /// 9 | /// Create a new ExportFunction object. 10 | /// 11 | /// Name of the function. 12 | /// Address of function. 13 | /// Ordinal of the function. 14 | public ExportFunction(string? name, uint address, ushort ordinal) 15 | { 16 | Name = name; 17 | Address = address; 18 | Ordinal = ordinal; 19 | } 20 | 21 | /// 22 | /// Create a new ExportFunction object. 23 | /// 24 | /// Name of the function. 25 | /// Address of function. 26 | /// Ordinal of the function. 27 | /// Name of the DLL and function this export forwards to. 28 | public ExportFunction(string name, uint address, ushort ordinal, string forwardName) 29 | { 30 | Name = name; 31 | Address = address; 32 | Ordinal = ordinal; 33 | ForwardName = forwardName; 34 | } 35 | 36 | /// 37 | /// Function name. 38 | /// 39 | public string? Name { get; } 40 | 41 | /// 42 | /// Function RVA. 43 | /// 44 | public uint Address { get; } 45 | 46 | /// 47 | /// Function Ordinal. 48 | /// 49 | public ushort Ordinal { get; } 50 | 51 | /// 52 | /// Function name if the function is 53 | /// forwarded to another DLL. 54 | /// Format "DLLName.ExportName". 55 | /// 56 | public string? ForwardName { get; } 57 | 58 | 59 | /// 60 | /// True if the export has a name and is not forwarded. 61 | /// 62 | public bool HasName => !string.IsNullOrEmpty(Name); 63 | 64 | /// 65 | /// True if the export has an ordinal. 66 | /// 67 | public bool HasOrdinal => Ordinal != 0; 68 | 69 | /// 70 | /// True if the export is forwarded and has 71 | /// a ForwardName. 72 | /// 73 | public bool HasForward => !string.IsNullOrEmpty(ForwardName); 74 | } 75 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageBoundImportDescriptor.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// Bound import descriptor. 7 | /// 8 | public class ImageBoundImportDescriptor : AbstractStructure 9 | { 10 | /// 11 | /// Create new bound import descriptor structure. 12 | /// 13 | /// A PE file. 14 | /// Offset of bound import descriptor in the PE file. 15 | public ImageBoundImportDescriptor(IRawFile peFile, long offset) 16 | : base(peFile, offset) 17 | { 18 | } 19 | 20 | /// 21 | /// Time date stamp. 22 | /// 23 | public uint TimeDateStamp 24 | { 25 | get => PeFile.ReadUInt(Offset + 0); 26 | set => PeFile.WriteUInt(Offset + 0, value); 27 | } 28 | 29 | /// 30 | /// Offset module name. 31 | /// 32 | public ushort OffsetModuleName 33 | { 34 | get => PeFile.ReadUShort(Offset + 4); 35 | set => PeFile.WriteUShort(Offset + 2, value); 36 | } 37 | 38 | /// 39 | /// Number of module forwarder references. 40 | /// 41 | public ushort NumberOfModuleForwarderRefs 42 | { 43 | get => PeFile.ReadUShort(Offset + 6); 44 | set => PeFile.WriteUShort(Offset + 4, value); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageDelayImportDescriptor.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// The ImageDelayImportDirectory describes delayed imports. 7 | /// 8 | public class ImageDelayImportDescriptor : AbstractStructure 9 | { 10 | /// 11 | /// Create a new ImageDelayImportDirectory object. 12 | /// 13 | /// A PE file. 14 | /// Offset to the delay import descriptor. 15 | public ImageDelayImportDescriptor(IRawFile peFile, long offset) 16 | : base(peFile, offset) 17 | { 18 | } 19 | 20 | /// 21 | /// 22 | /// 23 | public uint GrAttrs 24 | { 25 | get => PeFile.ReadUInt(Offset); 26 | set => PeFile.WriteUInt(Offset, value); 27 | } 28 | 29 | /// 30 | /// 31 | /// 32 | public uint SzName 33 | { 34 | get => PeFile.ReadUInt(Offset + 0x4); 35 | set => PeFile.WriteUInt(Offset + 0x4, value); 36 | } 37 | 38 | /// 39 | /// 40 | /// 41 | public uint Phmod 42 | { 43 | get => PeFile.ReadUInt(Offset + 0x8); 44 | set => PeFile.WriteUInt(Offset + 0x8, value); 45 | } 46 | 47 | /// 48 | /// 49 | /// 50 | public uint PIat 51 | { 52 | get => PeFile.ReadUInt(Offset + 0xc); 53 | set => PeFile.WriteUInt(Offset + 0xc, value); 54 | } 55 | 56 | /// 57 | /// 58 | /// 59 | public uint PInt 60 | { 61 | get => PeFile.ReadUInt(Offset + 0x10); 62 | set => PeFile.WriteUInt(Offset + 0x10, value); 63 | } 64 | 65 | /// 66 | /// 67 | /// 68 | public uint PBoundIAT 69 | { 70 | get => PeFile.ReadUInt(Offset + 0x14); 71 | set => PeFile.WriteUInt(Offset + 0x14, value); 72 | } 73 | 74 | /// 75 | /// 76 | /// 77 | public uint PUnloadIAT 78 | { 79 | get => PeFile.ReadUInt(Offset + 0x18); 80 | set => PeFile.WriteUInt(Offset + 0x16, value); 81 | } 82 | 83 | /// 84 | /// 85 | /// 86 | public uint DwTimeStamp 87 | { 88 | get => PeFile.ReadUInt(Offset + 0x1c); 89 | set => PeFile.WriteUInt(Offset + 0x1c, value); 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageImportByName.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using System; 3 | using System.Text; 4 | 5 | namespace PeNet.Header.Pe 6 | { 7 | /// 8 | /// The ImageImportByName structure is used to 9 | /// describes imports of functions or symbols by their name. 10 | /// The AddressOfData in the ImageThunkData from the 11 | /// ImageImportDescriptor points to it. 12 | /// 13 | public class ImageImportByName : AbstractStructure 14 | { 15 | /// 16 | /// Create new ImageImportByName object. 17 | /// 18 | /// A PE file. 19 | /// Raw offset of the ImageImportByName. 20 | public ImageImportByName(IRawFile peFile, uint offset) 21 | : base(peFile, offset) 22 | { 23 | } 24 | 25 | /// 26 | /// Hint. 27 | /// 28 | public ushort Hint 29 | { 30 | get => PeFile.ReadUShort(Offset); 31 | set => PeFile.WriteUShort(Offset, value); 32 | } 33 | 34 | /// 35 | /// Name of the function to import as a C-string (null terminated). 36 | /// 37 | public string Name 38 | { 39 | get => PeFile.ReadAsciiString(Offset + 0x2); 40 | set { 41 | var source = Encoding.ASCII.GetBytes(value); 42 | var dest = new byte[source.Length + 1]; 43 | Array.Copy(source, dest, source.Length); 44 | PeFile.WriteBytes(Offset + 0x2, dest); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageImportDescriptor.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// The ImageImportDescriptors are contained in the Import Directory 7 | /// and holds all the information about function and symbol imports. 8 | /// 9 | public class ImageImportDescriptor : AbstractStructure 10 | { 11 | /// 12 | /// Create a new ImageImportDescriptor object. 13 | /// 14 | /// A PE file. 15 | /// Raw offset of the descriptor. 16 | public ImageImportDescriptor(IRawFile peFile, long offset) 17 | : base(peFile, offset) 18 | { 19 | } 20 | 21 | /// 22 | /// Points to the first ImageImportByName struct. 23 | /// 24 | public uint OriginalFirstThunk 25 | { 26 | get => PeFile.ReadUInt(Offset); 27 | set => PeFile.WriteUInt(Offset, value); 28 | } 29 | 30 | /// 31 | /// Time and date stamp. 32 | /// 33 | public uint TimeDateStamp 34 | { 35 | get => PeFile.ReadUInt(Offset + 0x4); 36 | set => PeFile.WriteUInt(Offset + 0x4, value); 37 | } 38 | 39 | /// 40 | /// Forwarder Chain. 41 | /// 42 | public uint ForwarderChain 43 | { 44 | get => PeFile.ReadUInt(Offset + 0x8); 45 | set => PeFile.WriteUInt(Offset + 0x8, value); 46 | } 47 | 48 | /// 49 | /// RVA to the name of the DLL. 50 | /// 51 | public uint Name 52 | { 53 | get => PeFile.ReadUInt(Offset + 0xC); 54 | set => PeFile.WriteUInt(Offset + 0xC, value); 55 | } 56 | 57 | /// 58 | /// Points to an ImageImportByName struct or 59 | /// to the address of the first function. 60 | /// 61 | public uint FirstThunk 62 | { 63 | get => PeFile.ReadUInt(Offset + 0x10); 64 | set => PeFile.WriteUInt(Offset + 0x10, value); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageNtHeaders.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// The NT header is the main header for modern Windows applications. 7 | /// It contains the file header and the optional header. 8 | /// 9 | public class ImageNtHeaders : AbstractStructure 10 | { 11 | /// 12 | /// Access to the File header. 13 | /// 14 | public readonly ImageFileHeader FileHeader; 15 | 16 | /// 17 | /// Access to the Optional header. 18 | /// 19 | public readonly ImageOptionalHeader OptionalHeader; 20 | 21 | /// 22 | /// Create a new ImageNtHeaders object. 23 | /// 24 | /// A PE file . 25 | /// Raw offset of the NT header. 26 | public ImageNtHeaders(IRawFile peFile, long offset) 27 | : base(peFile, offset) 28 | { 29 | FileHeader = new ImageFileHeader(peFile, offset + 0x4); 30 | OptionalHeader = new ImageOptionalHeader(peFile, offset + 0x18, peFile.Is64Bit()); 31 | } 32 | 33 | /// 34 | /// NT header signature. 35 | /// 36 | public uint Signature 37 | { 38 | get => PeFile.ReadUInt(Offset); 39 | set => PeFile.WriteUInt(Offset, value); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageResourceDataEntry.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// The ImageResourceDataEntry points to the data of 7 | /// the resources in the PE file like version info, strings etc. 8 | /// 9 | public class ImageResourceDataEntry : AbstractStructure 10 | { 11 | /// 12 | /// Construct a ImageResourceDataEntry at a given offset. 13 | /// 14 | /// PE file. 15 | /// ImageResourceDirectoryEntry in which this entry resides. 16 | /// Offset to the structure in the file. 17 | public ImageResourceDataEntry(IRawFile peFile, ImageResourceDirectoryEntry parent, long offset) 18 | : base(peFile, offset) 19 | { 20 | Parent = parent; 21 | } 22 | 23 | /// 24 | /// Backwards connection to the parent. 25 | /// ImageResourceDirectoryEntry in which this entry resides. 26 | /// 27 | public ImageResourceDirectoryEntry Parent { get; } 28 | 29 | /// 30 | /// Offset to the data of the resource. 31 | /// 32 | public uint OffsetToData 33 | { 34 | get => PeFile.ReadUInt(Offset); 35 | set => PeFile.WriteUInt(Offset, value); 36 | } 37 | 38 | /// 39 | /// Size of the resource data. 40 | /// 41 | public uint Size1 42 | { 43 | get => PeFile.ReadUInt(Offset + 0x4); 44 | set => PeFile.WriteUInt(Offset + 0x4, value); 45 | } 46 | 47 | /// 48 | /// Code Page 49 | /// 50 | public uint CodePage 51 | { 52 | get => PeFile.ReadUInt(Offset + 0x8); 53 | set => PeFile.WriteUInt(Offset + 0x8, value); 54 | } 55 | 56 | /// 57 | /// Reserved 58 | /// 59 | public uint Reserved 60 | { 61 | get => PeFile.ReadUInt(Offset + 0xC); 62 | set => PeFile.WriteUInt(Offset + 0xC, value); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageResourceDirStringU.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// Represents a Unicode string used for resource names 7 | /// in the resource section. 8 | /// 9 | public class ImageResourceDirStringU : AbstractStructure 10 | { 11 | /// 12 | /// Create a new ImageResourceDirStringU Unicode string. 13 | /// 14 | /// A PE file. 15 | /// Raw offset of the string. 16 | public ImageResourceDirStringU(IRawFile peFile, long offset) 17 | : base(peFile, offset) 18 | { 19 | } 20 | 21 | /// 22 | /// Length of the string in Unicode characters, *not* in bytes. 23 | /// 1 Unicode char = 2 bytes. 24 | /// 25 | public ushort Length 26 | { 27 | get => PeFile.ReadUShort(Offset); 28 | set => PeFile.WriteUShort(Offset, value); 29 | } 30 | 31 | /// 32 | /// The Unicode string as a .Net string. 33 | /// 34 | public string NameString 35 | { 36 | get => PeFile.ReadUnicodeString(Offset + 2, Length); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageThunkData.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// The thunk data is used by for the imports 7 | /// in the import section. 8 | /// 9 | public class ImageThunkData : AbstractStructure 10 | { 11 | private readonly bool _is64Bit; 12 | 13 | /// 14 | /// Create a new ImageThunkData object. 15 | /// 16 | /// A PE file. 17 | /// Raw offset of the thunk data. 18 | /// Set to true if the PE file is a x64 application. 19 | public ImageThunkData(IRawFile peFile, uint offset, bool is64Bit) 20 | : base(peFile, offset) 21 | { 22 | _is64Bit = is64Bit; 23 | } 24 | 25 | /// 26 | /// Points to the address in the IAT or to an 27 | /// ImageImportByName struct. 28 | /// 29 | public ulong AddressOfData 30 | { 31 | get => _is64Bit ? PeFile.ReadULong(Offset) : PeFile.ReadUInt(Offset); 32 | set 33 | { 34 | if (!_is64Bit) 35 | PeFile.WriteUInt(Offset, (uint) value); 36 | else 37 | PeFile.WriteULong(Offset, value); 38 | } 39 | } 40 | 41 | /// 42 | /// Same as AddressOfFunction. 43 | /// 44 | public ulong Ordinal 45 | { 46 | get => AddressOfData; 47 | set => AddressOfData = value; 48 | } 49 | 50 | /// 51 | /// Same as AddressOfFunction. 52 | /// 53 | public ulong ForwarderString 54 | { 55 | get => AddressOfData; 56 | set => AddressOfData = value; 57 | } 58 | 59 | /// 60 | /// Same as AddressOfFunction. 61 | /// 62 | public ulong Function 63 | { 64 | get => AddressOfData; 65 | set => AddressOfData = value; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImageTlsCallback.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// Thread Local Storage callback. 7 | /// 8 | public class ImageTlsCallback : AbstractStructure 9 | { 10 | private readonly bool _is64Bit; 11 | 12 | /// 13 | /// Create a new TLS callback structure. 14 | /// 15 | /// A PE file. 16 | /// Offset of the TLS callback structure in the buffer. 17 | /// Flag is the PE file is 64 Bit. 18 | public ImageTlsCallback(IRawFile peFile, long offset, bool is64Bit) 19 | : base(peFile, offset) 20 | { 21 | _is64Bit = is64Bit; 22 | } 23 | 24 | /// 25 | /// Address of actual callback code. 26 | /// 27 | public ulong Callback 28 | { 29 | get => _is64Bit ? PeFile.ReadULong(Offset + 0) : PeFile.ReadUInt(Offset + 0); 30 | set 31 | { 32 | if(_is64Bit) 33 | PeFile.WriteULong(Offset + 0, value); 34 | else 35 | PeFile.WriteUInt(Offset + 0, (uint) value); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/ImportFunction.cs: -------------------------------------------------------------------------------- 1 | namespace PeNet.Header.Pe 2 | { 3 | /// 4 | /// Represents an imported function. 5 | /// 6 | public class ImportFunction 7 | { 8 | /// 9 | /// Create a new ImportFunction object. 10 | /// 11 | /// Function name. 12 | /// DLL where the function comes from. 13 | /// Function hint. 14 | /// Offset into the Import Address Table. 15 | public ImportFunction(string? name, string dll, ushort hint, uint iatOffset) 16 | { 17 | Name = name; 18 | DLL = dll; 19 | Hint = hint; 20 | IATOffset = iatOffset; 21 | } 22 | 23 | /// 24 | /// Function name. 25 | /// 26 | public string? Name { get; } 27 | 28 | /// 29 | /// DLL where the function comes from. 30 | /// 31 | public string DLL { get; } 32 | 33 | /// 34 | /// Function hint. 35 | /// 36 | public ushort Hint { get; } 37 | 38 | /// 39 | /// Offset into the Import Address Table. 40 | /// 41 | public uint IATOffset { get; } 42 | } 43 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/RuntimeFunction.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Pe 4 | { 5 | /// 6 | /// The runtime function struct is represents 7 | /// a function in the exception header for x64 8 | /// applications. 9 | /// 10 | public class RuntimeFunction : AbstractStructure 11 | { 12 | private UnwindInfo? _resolvedUnwindInfo; 13 | private readonly ImageSectionHeader[] _sectionHeaders; 14 | 15 | /// 16 | /// Create a new RuntimeFunction object. 17 | /// 18 | /// A PE file. 19 | /// Raw offset of the runtime function struct. 20 | /// Section Headers of the PE file. 21 | public RuntimeFunction(IRawFile peFile, long offset, ImageSectionHeader[] sh) 22 | : base(peFile, offset) 23 | { 24 | _sectionHeaders = sh; 25 | } 26 | 27 | /// 28 | /// RVA Start of the function in code. 29 | /// 30 | public uint FunctionStart 31 | { 32 | get => PeFile.ReadUInt(Offset); 33 | set => PeFile.WriteUInt(Offset, value); 34 | } 35 | 36 | /// 37 | /// RVA End of the function in code. 38 | /// 39 | public uint FunctionEnd 40 | { 41 | get => PeFile.ReadUInt(Offset + 0x4); 42 | set => PeFile.WriteUInt(Offset + 0x4, value); 43 | } 44 | 45 | /// 46 | /// Pointer to the unwind information. 47 | /// 48 | public uint UnwindInfo 49 | { 50 | get => PeFile.ReadUInt(Offset + 0x8); 51 | set => PeFile.WriteUInt(Offset + 0x8, value); 52 | } 53 | 54 | /// 55 | /// Unwind Info object belonging to this Runtime Function. 56 | /// 57 | public UnwindInfo ResolvedUnwindInfo { 58 | get 59 | { 60 | _resolvedUnwindInfo ??= GetUnwindInfo(_sectionHeaders); 61 | return _resolvedUnwindInfo; 62 | } 63 | } 64 | 65 | /// 66 | /// Get the UnwindInfo from a runtime function form the 67 | /// Exception header in x64 applications. 68 | /// 69 | /// Section Headers of the PE file. 70 | /// UnwindInfo for the runtime function. 71 | private UnwindInfo GetUnwindInfo(ImageSectionHeader[] sh) 72 | { 73 | // Check if the last bit is set in the UnwindInfo. If so, it is a chained 74 | // information. 75 | var uwAddress = (UnwindInfo & 0x1) == 0x1 76 | ? UnwindInfo & 0xFFFE 77 | : UnwindInfo; 78 | 79 | var uw = new UnwindInfo(PeFile, uwAddress.RvaToOffset(sh)); 80 | return uw; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Pe/WinCertificate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PeNet.FileParser; 3 | 4 | namespace PeNet.Header.Pe 5 | { 6 | /// 7 | /// The WinCertificate the information 8 | /// in the security directory of the PE file. 9 | /// It contains information about any certificates 10 | /// used to sign the binary. 11 | /// 12 | public class WinCertificate : AbstractStructure 13 | { 14 | /// 15 | /// Create a new WinCertificate object. 16 | /// 17 | /// A PE file. 18 | /// Raw offset to the structure. 19 | public WinCertificate(IRawFile peFile, long offset) 20 | : base(peFile, offset) 21 | { 22 | } 23 | 24 | /// 25 | /// Length of the certificate. 26 | /// 27 | public uint DwLength 28 | { 29 | get => PeFile.ReadUInt(Offset); 30 | set => PeFile.WriteUInt(Offset, value); 31 | } 32 | 33 | /// 34 | /// Revision. 35 | /// 36 | public ushort WRevision 37 | { 38 | get => PeFile.ReadUShort(Offset + 0x4); 39 | set => PeFile.WriteUShort(Offset + 0x4, value); 40 | } 41 | 42 | /// 43 | /// The certificate type. 44 | /// 45 | public WinCertificateType WCertificateType 46 | { 47 | get => (WinCertificateType) PeFile.ReadUShort(Offset + 0x6); 48 | set => PeFile.WriteUShort(Offset + 0x6, (ushort) value); 49 | } 50 | 51 | /// 52 | /// The certificate. 53 | /// 54 | public Span BCertificate 55 | { 56 | get 57 | { 58 | if (Offset + 0x8 > PeFile.Length || Offset + DwLength > PeFile.Length) 59 | { 60 | throw new IndexOutOfRangeException("BCertificate not in PE file range."); 61 | } 62 | return PeFile.AsSpan(Offset + 0x8, DwLength - 8); 63 | } 64 | } 65 | } 66 | 67 | /// 68 | /// WinCertificate wCertificateType constants. 69 | /// 70 | [Flags] 71 | public enum WinCertificateType : ushort 72 | { 73 | /// 74 | /// Certificate is X509 standard. 75 | /// 76 | X509 = 0x0001, 77 | 78 | /// 79 | /// Certificate is PKCS signed data. 80 | /// 81 | PkcsSignedData = 0x0002, 82 | 83 | /// 84 | /// Reserved 85 | /// 86 | Reserved1 = 0x0003, 87 | 88 | /// 89 | /// Certificate is PKCS1 signature. 90 | /// 91 | Pkcs1Sign = 0x0009 92 | } 93 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Resource/CvInfoPdb70.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PeNet.FileParser; 3 | 4 | namespace PeNet.Header.Resource 5 | { 6 | /// 7 | /// Codeview PDB information from the Debug directory. 8 | /// 9 | public class CvInfoPdb70 : AbstractStructure 10 | { 11 | public CvInfoPdb70(IRawFile peFile, uint offset) 12 | : base(peFile, offset) 13 | { 14 | } 15 | 16 | /// 17 | /// Codeview signature. 18 | /// Typically 0x53445352 = 'RSDS' 19 | /// 20 | public uint CvSignature 21 | { 22 | get => PeFile.ReadUInt(Offset); 23 | set => PeFile.WriteUInt(Offset, value); 24 | } 25 | 26 | /// 27 | /// The PDB signature is a GUID to identify the PDB file 28 | /// which belongs to the PE file. 29 | /// 30 | public Guid Signature 31 | { 32 | #if NET48 || NETSTANDARD2_0 33 | get => new Guid(PeFile.AsSpan(Offset + 4, 16).ToArray()); 34 | #else 35 | get => new Guid(PeFile.AsSpan(Offset + 4, 16)); 36 | #endif 37 | set => PeFile.WriteBytes(Offset + 4, value.ToByteArray()); 38 | } 39 | 40 | /// 41 | /// PDB Age is the iteration of the PDB. The first iteration is 1. 42 | /// The iteration is incremented each time the PDB content is augmented. 43 | /// 44 | public uint Age 45 | { 46 | get => PeFile.ReadUInt(Offset + 0x14); 47 | set => PeFile.WriteUInt(Offset + 0x14, value); 48 | } 49 | 50 | /// 51 | /// Original file name of the PDB that belongs to the 52 | /// PE file. 53 | /// 54 | public string PdbFileName => PeFile.ReadAsciiString(Offset + 0x18); 55 | } 56 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Resource/ResourceLocation.cs: -------------------------------------------------------------------------------- 1 | using PeNet.Header.Pe; 2 | 3 | namespace PeNet.Header.Resource 4 | { 5 | /// 6 | /// Record to handel location information. 7 | /// 8 | /// An ImageResourceDataEntry. 9 | /// Offset of the ImageResourceDataEntry in the PE file. 10 | /// Size of the ImageResourceDataEntry in the PE file. 11 | public record ResourceLocation(ImageResourceDataEntry Resource, uint Offset, uint Size) 12 | { 13 | public ImageResourceDataEntry Resource { get; } = Resource; 14 | public uint Offset { get; } = Offset; 15 | public uint Size { get; } = Size; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PeNet/Header/Resource/StringFileInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using PeNet.FileParser; 3 | 4 | namespace PeNet.Header.Resource 5 | { 6 | /// 7 | /// Describes the data representation in a file-version resource. 8 | /// Information about different languages and codes pages is contained in 9 | /// this structure. 10 | /// 11 | public class StringFileInfo : AbstractStructure 12 | { 13 | private StringTable[]? _stringTable; 14 | 15 | /// 16 | /// Create a new StringFileInfo instance. 17 | /// 18 | /// A PE file. 19 | /// Offset of a StringFileInfo structure in the PE file. 20 | public StringFileInfo(IRawFile peFile, long offset) 21 | : base(peFile, offset) 22 | { 23 | } 24 | 25 | /// 26 | /// Length of the StringFileInfo in bytes, including all children. 27 | /// 28 | public ushort WLength 29 | { 30 | get => PeFile.ReadUShort(Offset); 31 | set => PeFile.WriteUShort(Offset, value); 32 | } 33 | 34 | /// 35 | /// Always zero. 36 | /// 37 | public ushort WValueLength 38 | { 39 | get => PeFile.ReadUShort(Offset + 0x2); 40 | set => PeFile.WriteUShort(Offset + 0x2, value); 41 | } 42 | 43 | /// 44 | /// Type of the data in the version resource. Contains a 1 if the data 45 | /// is text data and a 0 if it contains binary data. 46 | /// 47 | public ushort WType 48 | { 49 | get => PeFile.ReadUShort(Offset + 0x4); 50 | set => PeFile.WriteUShort(Offset + 0x4, value); 51 | } 52 | 53 | /// 54 | /// Contains the Unicode string "StringFileInfo". 55 | /// 56 | public string SzKey => PeFile.ReadUnicodeString(Offset + 0x6); 57 | 58 | /// 59 | /// One ore more StringTable structures, where each tables szKey indicates 60 | /// the language and code page for displaying the text in the StringTable. 61 | /// 62 | public StringTable[] StringTable { 63 | get 64 | { 65 | _stringTable ??= ReadChildren(); 66 | return _stringTable; 67 | } 68 | } 69 | 70 | private StringTable[] ReadChildren() 71 | { 72 | var currentOffset = 73 | Offset + 6 + SzKey.UStringByteLength() 74 | + (Offset + 6 + SzKey.UStringByteLength()).PaddingBytes(32); 75 | 76 | var children = new List(); 77 | 78 | while (currentOffset < Offset + WLength) 79 | { 80 | var st = new StringTable(PeFile, currentOffset); 81 | 82 | if (st.WLength == 0) 83 | break; 84 | 85 | currentOffset += st.WLength; 86 | children.Add(st); 87 | } 88 | 89 | return children.ToArray(); 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Resource/TString.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.Header.Resource 4 | { 5 | /// 6 | /// Contains a string that describes specifics of a file. For example 7 | /// the version, copyright information or original file name. 8 | /// 9 | public class TString : AbstractStructure 10 | { 11 | /// 12 | /// Create a new TString structure. 13 | /// 14 | /// A PE file. 15 | /// Offset of a String structure in the PE file. 16 | public TString(IRawFile peFile, long offset) 17 | : base(peFile, offset) 18 | { 19 | } 20 | 21 | /// 22 | /// Length of the String structure in bytes. 23 | /// 24 | public ushort WLength 25 | { 26 | get => PeFile.ReadUShort(Offset); 27 | set => PeFile.WriteUShort(Offset, value); 28 | } 29 | 30 | /// 31 | /// Size of the Value member in words. 32 | /// 33 | public ushort WValueLength 34 | { 35 | get => PeFile.ReadUShort(Offset + 0x2); 36 | set => PeFile.WriteUShort(Offset + 0x2, value); 37 | } 38 | 39 | /// 40 | /// Type of the data in the version resource. Contains a 1 if the data 41 | /// is text data and a 0 if it contains binary data. 42 | /// 43 | public ushort WType 44 | { 45 | get => PeFile.ReadUShort(Offset + 0x4); 46 | set => PeFile.WriteUShort(Offset + 0x4, value); 47 | } 48 | 49 | /// 50 | /// Arbitrary Unicode string, which describes the kind of 51 | /// the following data, e.g. "Comments", "CompanyName" and so 52 | /// on. 53 | /// 54 | public string SzKey => PeFile.ReadUnicodeString(Offset + 0x6); 55 | 56 | /// 57 | /// Arbitrary string which contains the information for the 58 | /// szKey member. 59 | /// 60 | public string Value { 61 | get 62 | { 63 | var currentOffset = Offset + 0x6 + SzKey.UStringByteLength() + 64 | (Offset + 0x6 + SzKey.UStringByteLength()).PaddingBytes(32); 65 | 66 | return PeFile.ReadUnicodeString(currentOffset); 67 | } 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Resource/Var.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using PeNet.FileParser; 3 | 4 | namespace PeNet.Header.Resource 5 | { 6 | /// 7 | /// Usually a list of languages that the 8 | /// application or DLL supports. 9 | /// 10 | public class Var : AbstractStructure 11 | { 12 | private uint[]? _value; 13 | 14 | /// 15 | /// Create a new Var instance. 16 | /// 17 | /// A PE file. 18 | /// Offset of a Var structure in the PE file. 19 | public Var(IRawFile peFile, long offset) 20 | : base(peFile, offset) 21 | { 22 | } 23 | 24 | /// 25 | /// Length of the Var structure in bytes. 26 | /// 27 | public ushort WLength 28 | { 29 | get => PeFile.ReadUShort(Offset); 30 | set => PeFile.WriteUShort(Offset, value); 31 | } 32 | 33 | /// 34 | /// Length of the Value member in bytes. 35 | /// 36 | public ushort WValueLength 37 | { 38 | get => PeFile.ReadUShort(Offset + 0x2); 39 | set => PeFile.WriteUShort(Offset + 0x2, value); 40 | } 41 | 42 | /// 43 | /// Contains a 1 if the version resource is text and a 44 | /// 0 if the version resource is binary data. 45 | /// 46 | public ushort WType 47 | { 48 | get => PeFile.ReadUShort(Offset + 0x4); 49 | set => PeFile.WriteUShort(Offset + 04, value); 50 | } 51 | 52 | /// 53 | /// Unicode string "Translation" 54 | /// 55 | public string SzKey => PeFile.ReadUnicodeString(Offset + 0x6); 56 | 57 | /// 58 | /// DWORD value where the lower-order word contains the Microsoft 59 | /// language identifier and the high-order word the IBM code page number. 60 | /// Both values can be zero, indicating that the file is code page 61 | /// or language independent. 62 | /// 63 | public uint[] Value { 64 | get 65 | { 66 | _value ??= ReadValues(); 67 | return _value; 68 | } 69 | } 70 | 71 | private uint[] ReadValues() 72 | { 73 | var currentOffset = 74 | Offset + 6 + SzKey.UStringByteLength() 75 | + (Offset + 6 + SzKey.UStringByteLength()).PaddingBytes(32); 76 | 77 | var startOfValues = currentOffset; 78 | 79 | var values = new List(); 80 | 81 | while (currentOffset < startOfValues + WValueLength) 82 | { 83 | values.Add(PeFile.ReadUInt(currentOffset)); 84 | currentOffset += sizeof(uint); 85 | } 86 | 87 | return values.ToArray(); 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/PeNet/Header/Resource/VarFileInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using PeNet.FileParser; 3 | 4 | namespace PeNet.Header.Resource 5 | { 6 | /// 7 | /// Information about the file not dependent on any language and code page 8 | /// combination. 9 | /// 10 | public class VarFileInfo : AbstractStructure 11 | { 12 | private Var[]? _children; 13 | 14 | /// 15 | /// Create a VarFileInfo instance. 16 | /// 17 | /// A PE file. 18 | /// Offset of a VarFileInfo in the PE file. 19 | public VarFileInfo(IRawFile peFile, long offset) 20 | : base(peFile, offset) 21 | { 22 | } 23 | 24 | /// 25 | /// Length of the VarFileInfo structure including 26 | /// all children. 27 | /// 28 | public ushort WLength 29 | { 30 | get => PeFile.ReadUShort(Offset); 31 | set => PeFile.WriteUShort(Offset, value); 32 | } 33 | 34 | /// 35 | /// Always zero. 36 | /// 37 | public ushort WValueLength 38 | { 39 | get => PeFile.ReadUShort(Offset + 0x2); 40 | set => PeFile.WriteUShort(Offset + 0x2, value); 41 | } 42 | 43 | /// 44 | /// Contains a 1 if the version resource is text and a 45 | /// 0 if the version resource is binary data. 46 | /// 47 | public ushort WType 48 | { 49 | get => PeFile.ReadUShort(Offset + 0x4); 50 | set => PeFile.WriteUShort(Offset + 04, value); 51 | } 52 | 53 | /// 54 | /// Unicode string "VarFileInfo" 55 | /// 56 | public string SzKey => PeFile.ReadUnicodeString(Offset + 0x6); 57 | 58 | 59 | /// 60 | /// Usually a list of languages that the 61 | /// application or DLL supports. 62 | /// 63 | public Var[] Children { 64 | get 65 | { 66 | _children ??= ReadChildren(); 67 | return _children; 68 | } 69 | } 70 | 71 | private Var[] ReadChildren() 72 | { 73 | var currentOffset = 74 | Offset + 6 + SzKey.UStringByteLength() 75 | + (Offset + 6 + SzKey.UStringByteLength()).PaddingBytes(32); 76 | 77 | var values = new List(); 78 | 79 | while (currentOffset < Offset + WLength) 80 | { 81 | var v = new Var(PeFile, currentOffset); 82 | if (v.WLength == 0) 83 | break; 84 | 85 | currentOffset += v.WLength; 86 | values.Add(v); 87 | } 88 | 89 | return values.ToArray(); 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Authenticode/AuthenticodeParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PeNet.Header.Authenticode; 3 | 4 | namespace PeNet.HeaderParser.Authenticode 5 | { 6 | internal class AuthenticodeParser 7 | { 8 | private readonly PeFile _peFile; 9 | 10 | internal AuthenticodeParser(PeFile peFile) 11 | { 12 | _peFile = peFile; 13 | } 14 | 15 | internal AuthenticodeInfo? ParseTarget() 16 | { 17 | try 18 | { 19 | return new AuthenticodeInfo(_peFile); 20 | } 21 | catch(Exception) 22 | { 23 | return null; 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Net/MetaDataHdrParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Net; 3 | 4 | namespace PeNet.HeaderParser.Net 5 | { 6 | internal class MetaDataHdrParser : SafeParser 7 | { 8 | public MetaDataHdrParser(IRawFile peFile, long offset) 9 | : base(peFile, offset) 10 | { 11 | } 12 | 13 | protected override MetaDataHdr ParseTarget() 14 | { 15 | return new MetaDataHdr(PeFile, Offset); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Net/MetaDataStreamBlobParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | 3 | namespace PeNet.HeaderParser.Net 4 | { 5 | internal class MetaDataStreamBlobParser : SafeParser 6 | { 7 | private readonly uint _size; 8 | 9 | public MetaDataStreamBlobParser( 10 | IRawFile peFile, 11 | long offset, 12 | uint size) 13 | : base(peFile, offset) 14 | { 15 | _size = size; 16 | } 17 | 18 | protected override byte[] ParseTarget() => PeFile.AsSpan(Offset, _size).ToArray(); 19 | } 20 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Net/MetaDataStreamGUIDParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Net; 3 | 4 | namespace PeNet.HeaderParser.Net 5 | { 6 | internal class MetaDataStreamGuidParser : SafeParser 7 | { 8 | private readonly uint _size; 9 | 10 | public MetaDataStreamGuidParser( 11 | IRawFile peFile, 12 | long offset, 13 | uint size 14 | ) 15 | : base(peFile, offset) 16 | 17 | { 18 | _size = size; 19 | } 20 | 21 | protected override MetaDataStreamGuid ParseTarget() 22 | { 23 | return new MetaDataStreamGuid(PeFile, Offset, _size); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Net/MetaDataStreamStringParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Net; 3 | 4 | namespace PeNet.HeaderParser.Net 5 | { 6 | internal class MetaDataStreamStringParser : SafeParser 7 | { 8 | private readonly uint _size; 9 | 10 | public MetaDataStreamStringParser( 11 | IRawFile peFile, 12 | long offset, 13 | uint size 14 | ) 15 | : base(peFile, offset) 16 | { 17 | _size = size; 18 | } 19 | 20 | protected override MetaDataStreamString ParseTarget() 21 | { 22 | return new MetaDataStreamString(PeFile, Offset, _size); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Net/MetaDataStreamTablesHeaderParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Net; 3 | 4 | namespace PeNet.HeaderParser.Net 5 | { 6 | internal class MetaDataStreamTablesHeaderParser : SafeParser 7 | { 8 | public MetaDataStreamTablesHeaderParser(IRawFile peFile, long offset) 9 | : base(peFile, offset) 10 | { 11 | } 12 | 13 | protected override MetaDataTablesHdr ParseTarget() 14 | { 15 | return new MetaDataTablesHdr(PeFile, Offset); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Net/MetaDataStreamUSParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Net; 3 | 4 | namespace PeNet.HeaderParser.Net 5 | { 6 | internal class MetaDataStreamUsParser : SafeParser 7 | { 8 | private readonly uint _size; 9 | 10 | public MetaDataStreamUsParser(IRawFile peFile, long offset, uint size) 11 | : base(peFile, offset) 12 | { 13 | _size = size; 14 | } 15 | 16 | protected override MetaDataStreamUs ParseTarget() 17 | { 18 | return new MetaDataStreamUs(PeFile, Offset, _size); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageBaseRelocationsParser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using PeNet.FileParser; 4 | using PeNet.Header.Pe; 5 | 6 | namespace PeNet.HeaderParser.Pe 7 | { 8 | internal class ImageBaseRelocationsParser : SafeParser 9 | { 10 | private readonly uint _directorySize; 11 | 12 | public ImageBaseRelocationsParser( 13 | IRawFile peFile, 14 | uint offset, 15 | uint directorySize 16 | ) 17 | : base(peFile, offset) 18 | { 19 | _directorySize = directorySize; 20 | } 21 | 22 | protected override ImageBaseRelocation[]? ParseTarget() 23 | { 24 | if (Offset == 0) 25 | return null; 26 | 27 | var imageBaseRelocations = new List(); 28 | var currentBlock = Offset; 29 | 30 | 31 | while (true) 32 | { 33 | if (currentBlock >= Offset + _directorySize - 8) 34 | break; 35 | 36 | imageBaseRelocations.Add(new ImageBaseRelocation(PeFile, currentBlock, _directorySize)); 37 | currentBlock += imageBaseRelocations.Last().SizeOfBlock; 38 | } 39 | 40 | return imageBaseRelocations.ToArray(); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageBoundImportDescriptorParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class ImageBoundImportDescriptorParser : SafeParser 7 | { 8 | internal ImageBoundImportDescriptorParser(IRawFile peFile, long offset) 9 | : base(peFile, offset) 10 | { 11 | } 12 | 13 | protected override ImageBoundImportDescriptor ParseTarget() 14 | { 15 | return new ImageBoundImportDescriptor(PeFile, Offset); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageCor20HeaderParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class ImageCor20HeaderParser : SafeParser 7 | { 8 | public ImageCor20HeaderParser(IRawFile peFile, long offset) 9 | : base(peFile, offset) 10 | { 11 | } 12 | 13 | protected override ImageCor20Header ParseTarget() 14 | { 15 | return new ImageCor20Header(PeFile, Offset); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageDebugDirectoryParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class ImageDebugDirectoryParser : SafeParser 7 | { 8 | private readonly uint _size; 9 | 10 | internal ImageDebugDirectoryParser(IRawFile peFile, uint offset, uint size) 11 | : base(peFile, offset) 12 | { 13 | this._size = size; 14 | } 15 | 16 | protected override ImageDebugDirectory[] ParseTarget() 17 | { 18 | var numEntries = _size / 28; // Debug entry is 28 bytes 19 | var entries = new ImageDebugDirectory[numEntries]; 20 | 21 | for(uint i = 0; i < numEntries; i++) 22 | { 23 | entries[i] = new ImageDebugDirectory(PeFile, Offset + (i * 28)); 24 | } 25 | 26 | return entries; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageDelayImportDescriptorParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using System.Collections.Generic; 4 | 5 | namespace PeNet.HeaderParser.Pe 6 | { 7 | internal class ImageDelayImportDescriptorParser : SafeParser 8 | { 9 | internal ImageDelayImportDescriptorParser(IRawFile peFile, long offset) 10 | : base(peFile, offset) 11 | { 12 | } 13 | 14 | protected override ImageDelayImportDescriptor[]? ParseTarget() 15 | { 16 | if (Offset == 0) 17 | return null; 18 | 19 | var idescs = new List(); 20 | uint idescSize = 32; // Size of ImageDelayImportDescriptor (8 * 4 Byte) 21 | int round = 0; 22 | 23 | while (true) 24 | { 25 | var idesc = new ImageDelayImportDescriptor(PeFile, Offset + idescSize * round); 26 | 27 | // Find the last ImageDelayImportDescriptor which is completely null (except for TimeDateStamp member). 28 | if (idesc.GrAttrs == 0 29 | && idesc.SzName == 0 30 | && idesc.Phmod == 0 31 | && idesc.PIat == 0 32 | && idesc.PInt == 0 33 | && idesc.PBoundIAT == 0 34 | && idesc.PUnloadIAT == 0 35 | ) 36 | { 37 | break; 38 | } 39 | 40 | idescs.Add(idesc); 41 | round++; 42 | } 43 | 44 | return idescs.ToArray(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageDosHeaderParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class ImageDosHeaderParser : SafeParser 7 | { 8 | internal ImageDosHeaderParser(IRawFile peFile, long offset) 9 | : base(peFile, offset) 10 | { 11 | } 12 | 13 | protected override ImageDosHeader ParseTarget() 14 | { 15 | return new ImageDosHeader(PeFile, Offset); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageExportDirectoriesParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class ImageExportDirectoriesParser : SafeParser 7 | { 8 | public ImageExportDirectoriesParser(IRawFile peFile, long offset) 9 | : base(peFile, offset) 10 | { 11 | } 12 | 13 | 14 | protected override ImageExportDirectory ParseTarget() 15 | { 16 | return new ImageExportDirectory(PeFile, Offset); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageImportDescriptorsParser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using PeNet.FileParser; 3 | using PeNet.Header.Pe; 4 | 5 | namespace PeNet.HeaderParser.Pe 6 | { 7 | internal class ImageImportDescriptorsParser : SafeParser 8 | { 9 | public ImageImportDescriptorsParser(IRawFile peFile, long offset) 10 | : base(peFile, offset) 11 | { 12 | } 13 | 14 | protected override ImageImportDescriptor[]? ParseTarget() 15 | { 16 | if (Offset == 0) 17 | return null; 18 | 19 | var idescs = new List(); 20 | uint idescSize = 20; // Size of ImageImportDescriptor (5 * 4 Byte) 21 | uint round = 0; 22 | 23 | while (true) 24 | { 25 | var idesc = new ImageImportDescriptor(PeFile, Offset + idescSize*round); 26 | 27 | // Found the last ImageImportDescriptor which is completely null (except TimeDateStamp). 28 | if (idesc.OriginalFirstThunk == 0 29 | && idesc.ForwarderChain == 0 30 | && idesc.Name == 0 31 | && idesc.FirstThunk == 0) 32 | { 33 | break; 34 | } 35 | 36 | idescs.Add(idesc); 37 | round++; 38 | } 39 | 40 | 41 | return idescs.ToArray(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageLoadConfigDirectoryParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class ImageLoadConfigDirectoryParser : SafeParser 7 | { 8 | private readonly bool _is64Bit; 9 | 10 | internal ImageLoadConfigDirectoryParser(IRawFile peFile, uint offset, bool is64Bit) 11 | : base(peFile, offset) 12 | { 13 | _is64Bit = is64Bit; 14 | } 15 | 16 | protected override ImageLoadConfigDirectory ParseTarget() 17 | { 18 | return new ImageLoadConfigDirectory(PeFile, Offset, _is64Bit); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageNtHeadersParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class ImageNtHeadersParser : SafeParser 7 | { 8 | internal ImageNtHeadersParser(IRawFile peFile, uint offset) 9 | : base(peFile, offset) 10 | { 11 | } 12 | 13 | protected override ImageNtHeaders ParseTarget() 14 | { 15 | return new ImageNtHeaders(PeFile, Offset); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageResourceDirectoryParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class ImageResourceDirectoryParser : SafeParser 7 | { 8 | private long _resourceDirSize; 9 | 10 | internal ImageResourceDirectoryParser(IRawFile peFile, long offset, long size) 11 | : base(peFile, offset) 12 | { 13 | _resourceDirSize = size; 14 | } 15 | 16 | protected override ImageResourceDirectory? ParseTarget() 17 | { 18 | if (Offset == 0) 19 | return null; 20 | 21 | // Parse the root directory. 22 | var root = new ImageResourceDirectory(PeFile, null, Offset, Offset, _resourceDirSize); 23 | 24 | // Check if the number of entries is bigger than the resource directory 25 | // and thus cannot be parsed correctly. 26 | // 10 byte is the minimal size of an entry. 27 | if ((root.NumberOfIdEntries + root.NumberOfNameEntries) * 10 >= _resourceDirSize) 28 | return root; 29 | 30 | if (root.DirectoryEntries is null) 31 | return root; 32 | 33 | // Parse the second stage (type) 34 | foreach (var de in root.DirectoryEntries) 35 | { 36 | de!.ResourceDirectory = new ImageResourceDirectory( 37 | PeFile, 38 | de, 39 | Offset + de.OffsetToDirectory, 40 | Offset, 41 | _resourceDirSize 42 | ); 43 | 44 | var sndLevel = de?.ResourceDirectory?.DirectoryEntries; 45 | if(sndLevel is null) 46 | continue; 47 | 48 | // Parse the third stage (name/IDs) 49 | foreach (var de2 in sndLevel) 50 | { 51 | de2!.ResourceDirectory = new ImageResourceDirectory( 52 | PeFile, 53 | de2, 54 | Offset + de2.OffsetToDirectory, 55 | Offset, 56 | _resourceDirSize 57 | ); 58 | 59 | var thrdLevel = de2?.ResourceDirectory?.DirectoryEntries; 60 | if(thrdLevel is null) 61 | continue; 62 | 63 | 64 | // Parse the forth stage (language) with the data. 65 | foreach (var de3 in thrdLevel) 66 | { 67 | de3!.ResourceDataEntry = new ImageResourceDataEntry(PeFile, de3, 68 | Offset + de3.OffsetToData); 69 | } 70 | } 71 | } 72 | 73 | return root; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageSectionHeadersParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PeNet.FileParser; 3 | using PeNet.Header.Pe; 4 | 5 | namespace PeNet.HeaderParser.Pe 6 | { 7 | internal class ImageSectionHeadersParser : SafeParser 8 | { 9 | private readonly ushort _numOfSections; 10 | private readonly ulong _imageBaseAddress; 11 | 12 | internal ImageSectionHeadersParser(IRawFile peFile, uint offset, ushort numOfSections, ulong imageBaseAddress) 13 | : base(peFile, offset) 14 | { 15 | _numOfSections = numOfSections; 16 | _imageBaseAddress = imageBaseAddress; 17 | } 18 | 19 | protected override ImageSectionHeader[] ParseTarget() 20 | { 21 | // Permanence and memory optimization for sorting the section headers 22 | static int Comparison(ImageSectionHeader x, ImageSectionHeader y) 23 | { 24 | if (x.VirtualAddress > y.VirtualAddress) 25 | return 1; 26 | if (x.VirtualAddress < y.VirtualAddress) 27 | return -1; 28 | 29 | return 0; 30 | } 31 | 32 | var sh = new ImageSectionHeader[_numOfSections]; 33 | const uint secSize = 0x28; // Every section header is 40 bytes in size. 34 | for (uint i = 0; i < _numOfSections; i++) 35 | { 36 | sh[i] = new ImageSectionHeader(PeFile, Offset + i*secSize, _imageBaseAddress); 37 | } 38 | 39 | Array.Sort(sh, Comparison); 40 | 41 | return sh; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/ImageTlsDirectoryParser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using PeNet.FileParser; 3 | using PeNet.Header.Pe; 4 | 5 | namespace PeNet.HeaderParser.Pe 6 | { 7 | internal class ImageTlsDirectoryParser : SafeParser 8 | { 9 | private readonly bool _is64Bit; 10 | private readonly ImageSectionHeader[] _sectionsHeaders; 11 | 12 | internal ImageTlsDirectoryParser( 13 | IRawFile peFile, 14 | uint offset, 15 | bool is64Bit, 16 | ImageSectionHeader[] sectionHeaders 17 | ) 18 | : base(peFile, offset) 19 | { 20 | _is64Bit = is64Bit; 21 | _sectionsHeaders = sectionHeaders; 22 | } 23 | 24 | protected override ImageTlsDirectory ParseTarget() 25 | { 26 | var tlsDir = new ImageTlsDirectory(PeFile, Offset, _is64Bit); 27 | tlsDir.TlsCallbacks = ParseTlsCallbacks(tlsDir.AddressOfCallBacks); 28 | return tlsDir; 29 | } 30 | 31 | private ImageTlsCallback[] ParseTlsCallbacks(ulong addressOfCallBacks) 32 | { 33 | var callbacks = new List(); 34 | var rawAddressOfCallbacks = (uint) addressOfCallBacks.VaToOffset(_sectionsHeaders); 35 | 36 | uint count = 0; 37 | while (true) 38 | { 39 | if (_is64Bit) 40 | { 41 | var cb = new ImageTlsCallback(PeFile, rawAddressOfCallbacks + count*8, _is64Bit); 42 | if (cb.Callback == 0) 43 | break; 44 | 45 | callbacks.Add(cb); 46 | count++; 47 | } 48 | else 49 | { 50 | var cb = new ImageTlsCallback(PeFile, rawAddressOfCallbacks + count*4, _is64Bit); 51 | if (cb.Callback == 0) 52 | break; 53 | 54 | callbacks.Add(cb); 55 | count++; 56 | } 57 | } 58 | 59 | return callbacks.ToArray(); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/NativeStructureParsers.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class NativeStructureParsers 7 | { 8 | private readonly IRawFile _peFile; 9 | private readonly ImageDosHeaderParser _imageDosHeaderParser; 10 | private readonly ImageNtHeadersParser? _imageNtHeadersParser; 11 | private ImageSectionHeadersParser? _imageSectionHeadersParser; 12 | 13 | internal NativeStructureParsers(IRawFile peFile) 14 | { 15 | _peFile = peFile; 16 | 17 | // Init all parsers 18 | _imageDosHeaderParser = InitImageDosHeaderParser(); 19 | _imageNtHeadersParser = InitNtHeadersParser(); 20 | _imageSectionHeadersParser = InitImageSectionHeadersParser(); 21 | } 22 | 23 | public ImageDosHeader? ImageDosHeader => _imageDosHeaderParser.GetParserTarget(); 24 | public ImageNtHeaders? ImageNtHeaders => _imageNtHeadersParser?.GetParserTarget(); 25 | public ImageSectionHeader[]? ImageSectionHeaders => _imageSectionHeadersParser?.GetParserTarget(); 26 | 27 | private ImageSectionHeadersParser? InitImageSectionHeadersParser() 28 | { 29 | uint GetSecHeaderOffset() 30 | { 31 | var x = (uint)ImageNtHeaders!.FileHeader.SizeOfOptionalHeader + 0x18; 32 | return ImageDosHeader!.E_lfanew + x; 33 | } 34 | 35 | if (ImageNtHeaders is null || ImageDosHeader is null) 36 | return null; 37 | 38 | return new ImageSectionHeadersParser( 39 | _peFile, GetSecHeaderOffset(), 40 | ImageNtHeaders.FileHeader.NumberOfSections, 41 | ImageNtHeaders.OptionalHeader.ImageBase 42 | ); 43 | } 44 | 45 | internal void ReparseSectionHeaders() 46 | { 47 | _imageSectionHeadersParser = InitImageSectionHeadersParser(); 48 | } 49 | 50 | private ImageNtHeadersParser? InitNtHeadersParser() 51 | { 52 | if (ImageDosHeader is null) 53 | return null; 54 | 55 | return new ImageNtHeadersParser(_peFile, ImageDosHeader.E_lfanew); 56 | } 57 | 58 | private ImageDosHeaderParser InitImageDosHeaderParser() 59 | { 60 | return new ImageDosHeaderParser(_peFile, 0); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/RuntimeFunctionsParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class RuntimeFunctionsParser : SafeParser 7 | { 8 | private readonly uint _directorySize; 9 | private readonly bool _is32Bit; 10 | private readonly ImageSectionHeader[] _sectionHeaders; 11 | 12 | public RuntimeFunctionsParser( 13 | IRawFile peFile, 14 | long offset, 15 | bool is32Bit, 16 | uint directorySize, 17 | ImageSectionHeader[] sectionHeaders 18 | ) 19 | : base(peFile, offset) 20 | { 21 | _is32Bit = is32Bit; 22 | _directorySize = directorySize; 23 | _sectionHeaders = sectionHeaders; 24 | } 25 | 26 | protected override RuntimeFunction[]? ParseTarget() 27 | { 28 | if (_is32Bit || Offset == 0) 29 | return null; 30 | 31 | const int sizeOfRuntimeFunction = 0xC; 32 | var rf = new RuntimeFunction[_directorySize/sizeOfRuntimeFunction]; 33 | 34 | for (var i = 0; i < rf.Length; i++) 35 | { 36 | rf[i] = new RuntimeFunction(PeFile, (uint) (Offset + i*sizeOfRuntimeFunction), _sectionHeaders); 37 | } 38 | 39 | return rf; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Pe/WinCertificateParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | 4 | namespace PeNet.HeaderParser.Pe 5 | { 6 | internal class WinCertificateParser : SafeParser 7 | { 8 | internal WinCertificateParser(IRawFile peFile, long offset) 9 | : base(peFile, offset) 10 | { 11 | } 12 | 13 | protected override WinCertificate? ParseTarget() 14 | { 15 | return Offset == 0 ? null : new WinCertificate(PeFile, Offset); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/Resource/ResourcesParser.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Resource; 3 | 4 | namespace PeNet.HeaderParser.Resource 5 | { 6 | internal class ResourcesParser : SafeParser 7 | { 8 | private readonly ResourceLocation? _vsVersionLocation; 9 | private readonly ResourceLocation[] _iconDirectoryLocations; 10 | private readonly ResourceLocation[] _groupIconDirectoryLocations; 11 | 12 | public ResourcesParser(IRawFile peFile, uint offset, ResourceLocation? vsVersionLocation, ResourceLocation[] iconDirectoryLocations, ResourceLocation[] groupIconDirectoryLocations) : base(peFile, offset) 13 | { 14 | _vsVersionLocation = vsVersionLocation; 15 | _iconDirectoryLocations = iconDirectoryLocations; 16 | _groupIconDirectoryLocations = groupIconDirectoryLocations; 17 | } 18 | 19 | protected override Resources ParseTarget() 20 | { 21 | return new Resources(PeFile, Offset, _vsVersionLocation, _iconDirectoryLocations, _groupIconDirectoryLocations); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/PeNet/HeaderParser/SafeParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PeNet.FileParser; 3 | 4 | namespace PeNet.HeaderParser 5 | { 6 | internal abstract class SafeParser 7 | where T : class 8 | { 9 | protected readonly IRawFile PeFile; 10 | protected readonly long Offset; 11 | private bool _alreadyParsed; 12 | 13 | private T? _target; 14 | 15 | internal SafeParser(IRawFile peFile, long offset) 16 | { 17 | PeFile = peFile; 18 | Offset = offset; 19 | } 20 | 21 | private bool SanityCheckFailed() 22 | { 23 | return Offset > PeFile?.Length; 24 | } 25 | 26 | 27 | protected abstract T? ParseTarget(); 28 | 29 | public T? GetParserTarget() 30 | { 31 | if (_alreadyParsed) 32 | return _target; 33 | 34 | _alreadyParsed = true; 35 | 36 | if (SanityCheckFailed()) 37 | return null; 38 | 39 | try 40 | { 41 | _target = ParseTarget(); 42 | } 43 | catch (Exception) 44 | { 45 | _target = null; 46 | } 47 | 48 | return _target; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/PeNet/NET48_Helpers.cs_: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace PeNet 7 | { 8 | public static class NET48_Helpers 9 | { 10 | public static unsafe string GetString(this Encoding encoding, Span span) 11 | { 12 | if (span.IsEmpty) 13 | { 14 | throw new ArgumentException("Span cannot be empty."); 15 | } 16 | 17 | fixed (byte* ptr = span) 18 | { 19 | return encoding.GetString(ptr, span.Length); 20 | } 21 | } 22 | 23 | public static int Read(this Stream stream, Span span) 24 | { 25 | byte[] buffer = new byte[span.Length]; 26 | int ret = stream.Read(buffer, 0, buffer.Length); 27 | ((Span)buffer).CopyTo(span); 28 | return ret; 29 | } 30 | 31 | public static void Write(this Stream stream, Span span) 32 | { 33 | stream.Write(span.ToArray(), 0, span.Length); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/PeNet/PeNet.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.1;net8;net48;netstandard2 4 | 0.0.0 5 | enable 6 | 12 7 | true 8 | CS8600;CS8602;CS8603;CS8625;CS8618;CS8604;CS8601 9 | true 10 | true 11 | 12 | 13 | 15 | 17 | true 18 | true 19 | true 20 | true 21 | 22 | 23 | 24 | true 25 | snupkg 26 | true 27 | true 28 | PeNet.snk 29 | 30 | 31 | 32 | Stefan Hausotte 33 | Apache-2.0 34 | PeNet is a Windows PE (Portable Executable) parser written in C#. It parses all PE 35 | header structures for x32 and x64. 36 | 2017 @ Stefan Hausotte 37 | https://github.com/secana/PeNet 38 | PE Header Portable Executable 39 | https://raw.githubusercontent.com/secana/PeNet/master/resource/icon.png 40 | icon.png 41 | https://github.com/secana/PeNet 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | NET48_Helpers.cs 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/PeNet/PeNet.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | CSharp90 -------------------------------------------------------------------------------- /src/PeNet/PeNet.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/src/PeNet/PeNet.snk -------------------------------------------------------------------------------- /src/PeNet/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | netstandard2.0 11 | bin\Release\PublishOutput 12 | 13 | -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/AddImportsRegression.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/AddImportsRegression.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/DRWUI.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/DRWUI.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/HelloWorld.TablesStream.ExtraData.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/HelloWorld.TablesStream.ExtraData.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/HelloWorld.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/HelloWorld.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/NetCoreConsole.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/NetCoreConsole.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/NetFrameworkConsole.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/NetFrameworkConsole.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/NetFrameworkConsole.exe.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/No_SEH.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/No_SEH.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/README.md: -------------------------------------------------------------------------------- 1 | Information to: 2 | 1. pidgin_manipulated_GroupIconDirectory.exe: 3 | - Contains 5 GroupIconDirectories with [9,0,2,9,0] GroupIconDirectoryEntries. 4 | - These consist of: 5 | - The normal pidgin.exe GroupIconDirectory. 6 | - A GroupIconDirectory of random bytes. 7 | - A shortened version of the first GroupIconDirectory with only 2 GroupIconDirectoryEntries. 8 | - A version of the first GroupIconDirectory extended with random bytes. 9 | - A shortened version of the first GroupIconDirectory with only 4 bytes. 10 | 11 | 2. pidgin_manipulated_GroupIconDirectory_withNullIcon.exe: 12 | - Contains 5 GroupIconDirectories with [9,0,2,9,0] GroupIconDirectoryEntries and an additionally dummy Icon with ID 17473. 13 | - These consist of: 14 | - The normal pidgin.exe GroupIconDirectory. 15 | - A GroupIconDirectory of random bytes. 16 | - A shortened version of the first GroupIconDirectory with only 2 GroupIconDirectoryEntries. 17 | - A version of the first GroupIconDirectory extended with random bytes. 18 | - A shortened version of the first GroupIconDirectory with less than a whole GroupIconDirectoryEntry. 19 | 20 | 3. pidgin_manipulated_Icons.exe: 21 | - Contains 15 Icons: 22 | - Icon 1-9 are the normal Icons from pidgin.exe. [Displayable, Extractable] 23 | - Icon 10 is a shortened version of Icon 9. [Extractable] 24 | - Icon 11 is a version of Icon 9 with random byte in his header. [Extractable] 25 | - Icon 12 is a shortened version of Icon 9 which is shorter than the header. 26 | - Icon 13 is a version of Icon 9 extended with random bytes. [Displayable, Extractable] 27 | - Icon 14 consists of only 1 byte. 28 | - Icon 15 contains an image consisting of random bytes with the header of Icon 9. [Displayable, Extractable] -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/TLSCallback_x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/TLSCallback_x64.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/TLSCallback_x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/TLSCallback_x86.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/TestCetCompatAndEhCont.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/TestCetCompatAndEhCont.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/VB40032-2.DLL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/VB40032-2.DLL -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/VB40032.DLL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/VB40032.DLL -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/add-import.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/add-import.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/add-section.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/add-section.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/arm_binary.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/arm_binary.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/arm_dotnet_binary.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/arm_dotnet_binary.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/cff-chrome_elf.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/cff-chrome_elf.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/chrome_elf.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/chrome_elf.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/dotnet_x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/dotnet_x64.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/filezilla_dll_without_Version.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/filezilla_dll_without_Version.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/firefox_invalid_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/firefox_invalid_x64.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/firefox_invalid_x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/firefox_invalid_x86.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/firefox_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/firefox_x64.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/firefox_x64_copy1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/firefox_x64_copy1.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/firefox_x64_copy2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/firefox_x64_copy2.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/firefox_x64_manipulated.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/firefox_x64_manipulated.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/firefox_x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/firefox_x86.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/firefox_x86_2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/firefox_x86_2.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/krnl_test.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/krnl_test.sys -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/mmf_test.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/mmf_test.bin -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/notPeFile.txt: -------------------------------------------------------------------------------- 1 | This is not a pe file -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/old_firefox_x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/old_firefox_x86.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/osx_vb_netcore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/osx_vb_netcore.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pdb_guid.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pdb_guid.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_manipulated_GroupIconDirectory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_manipulated_GroupIconDirectory.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_manipulated_GroupIconDirectory_withNullIcon.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_manipulated_GroupIconDirectory_withNullIcon.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_manipulated_Icons.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_manipulated_Icons.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_two_icons_with_same_id.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_two_icons_with_same_id.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_with_additional_firefox_version_entry.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_with_additional_firefox_version_entry.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_with_double_iconGroupEntries.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_with_double_iconGroupEntries.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_with_iconGroupEntry_without_icon.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_with_iconGroupEntry_without_icon.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_with_one_icon_without_IconGroupDirectoryEntry.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_with_one_icon_without_IconGroupDirectoryEntry.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/pidgin_without_groupIconDirectory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/pidgin_without_groupIconDirectory.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/remove-section.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/remove-section.exe -------------------------------------------------------------------------------- /test/PeNet.Test/Binaries/win_test.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Binaries/win_test.dll -------------------------------------------------------------------------------- /test/PeNet.Test/Editor/SectionTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.Header.Pe; 2 | using System.Linq; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Editor 6 | { 7 | public class SectionTest 8 | { 9 | [Fact] 10 | public void AddSection_NewSectionAtEndOfFile() 11 | { 12 | var peFile = new PeFile(@"Binaries/add-section.exe"); 13 | 14 | // Before adding the new section 15 | Assert.Equal(27_648, peFile.RawFile.Length); 16 | Assert.Equal(6, peFile.ImageNtHeaders.FileHeader.NumberOfSections); 17 | Assert.Equal(0xb000u, peFile.ImageNtHeaders.OptionalHeader.SizeOfImage); 18 | Assert.Equal(6, peFile.ImageSectionHeaders.Length); 19 | 20 | 21 | peFile.AddSection(".newSec", 100, (ScnCharacteristicsType)0x40000040); 22 | 23 | // After adding the new section 24 | Assert.Equal(28_160, peFile.RawFile.Length); 25 | Assert.Equal(7, peFile.ImageNtHeaders.FileHeader.NumberOfSections); 26 | Assert.Equal(0xc000u, peFile.ImageNtHeaders.OptionalHeader.SizeOfImage); 27 | Assert.Equal(7, peFile.ImageSectionHeaders.Length); 28 | } 29 | 30 | [Fact] 31 | public void RemoveSection_SectionRemoved() 32 | { 33 | var peFile = new PeFile(@"Binaries/remove-section.exe"); 34 | peFile.RemoveSection(".rsrc"); 35 | 36 | Assert.Equal(5, peFile.ImageSectionHeaders.Length); 37 | Assert.False(peFile.ImageSectionHeaders.ToList().Exists(s => s.Name == ".rsrc")); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/PeNet.Test/Header/AbstractStructureTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header 6 | { 7 | public class AbstractStructureTest 8 | { 9 | class SubStructure : AbstractStructure 10 | { 11 | public int SubInt { get; } = 11; 12 | public int SubString { get; } = 12; 13 | public SubStructure() 14 | : base(new BufferFile(new byte[0]), 0) 15 | { 16 | } 17 | } 18 | class Structure : AbstractStructure 19 | { 20 | public int Integer { get; } = 10; 21 | public string String { get; } = "Hello"; 22 | public long Long { get; } = 20; 23 | public string[] StringArray { get; } = new string[] { "Hello", "World" }; // Must not be in the results 24 | public int[] NullArray { get; } = null; // Must not be in the results 25 | public string NullString { get; } = null; 26 | public SubStructure[] SubStructure { get; } = new SubStructure[] { new SubStructure(), new SubStructure() }; 27 | 28 | #pragma warning disable IDE0051 // Remove unused private members 29 | private string PrivString { get; } = "ShallNotSee"; // Must not be in the results 30 | #pragma warning restore IDE0051 // Remove unused private members 31 | protected int ProtInt { get; } = -1; 32 | 33 | public Structure() 34 | : base(new BufferFile(new byte[0]), 0) 35 | { 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Authenticode/AuthenticodeHashTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using System.Linq; 3 | 4 | namespace PeNet.Test.Header.Authenticode 5 | { 6 | public class AuthenticodeHashTest 7 | { 8 | [Theory] 9 | [InlineData(@"./Binaries/add-import.exe","68555fb55b4d974628d429eda7f5e282d647b426")] 10 | [InlineData(@"./Binaries/add-section.exe","68555fb55b4d974628d429eda7f5e282d647b426")] 11 | [InlineData(@"./Binaries/arm_binary.dll","c722f439a2630f31b993917190c29604b8aad3b8")] 12 | [InlineData(@"./Binaries/arm_dotnet_binary.dll","9bca7cc604e504475e46c2a2192a24c4c11abb43")] 13 | [InlineData(@"./Binaries/chrome_elf.dll","33ea37b6958a008549dc395e2932095f34bcbf8b")] 14 | [InlineData(@"./Binaries/dotnet_x64.dll","3a482db1ed60fdab5fa7862b414797cad4f00524")] 15 | [InlineData(@"./Binaries/firefox_invalid_x64.exe","79da1b80964d0ef4e661b74d09e4d01dfb71fa95")] 16 | [InlineData(@"./Binaries/firefox_invalid_x86.exe","90dfa709c0ad470a44a6155aa6af7b136318967b")] 17 | [InlineData(@"./Binaries/firefox_x64_copy1.exe","f9e7919f2e19cacc6af2cdd5919a31999c9d2fb6")] 18 | [InlineData(@"./Binaries/firefox_x64_copy2.exe","f9e7919f2e19cacc6af2cdd5919a31999c9d2fb6")] 19 | [InlineData(@"./Binaries/firefox_x64_manipulated.exe","6dece04e93fca237197f53d31b18bb3bda72b15d")] 20 | [InlineData(@"./Binaries/firefox_x64.exe","f9e7919f2e19cacc6af2cdd5919a31999c9d2fb6")] 21 | [InlineData(@"./Binaries/firefox_x86_2.exe","0b4ba5ddad3dedef928db97c674703f5bf3e5f81")] 22 | [InlineData(@"./Binaries/firefox_x86.exe","0b4ba5ddad3dedef928db97c674703f5bf3e5f81")] 23 | [InlineData(@"./Binaries/krnl_test.sys","b0020506b5b26ba8327d3dcce41ca134c633824b")] 24 | [InlineData(@"./Binaries/NetCoreConsole.dll","61420d9b7cf60b37caab6918c4ce89ce5a029bfc")] 25 | [InlineData(@"./Binaries/NetFrameworkConsole.exe","5728a7e8d46bbccb3b46804678d32e89000cf97c")] 26 | [InlineData(@"./Binaries/No_SEH.exe","796ffb54e4df71bbba8802f514aefb609f6eb901")] 27 | [InlineData(@"./Binaries/old_firefox_x86.exe","c8d6c881cdd701f8630ca25ed6624ace69010ca0")] 28 | [InlineData(@"./Binaries/osx_vb_netcore.dll","73297a8a0693b2024c4800d38fa67d1fae9fa2e1")] 29 | [InlineData(@"./Binaries/pdb_guid.exe","1deaa6bf0c338973d81742e0a4930be35348f813")] 30 | [InlineData(@"./Binaries/pidgin.exe","5cf1e042d80711ec0bc3ce05be8c34a280e5f512")] 31 | [InlineData(@"./Binaries/remove-section.exe","68555fb55b4d974628d429eda7f5e282d647b426")] 32 | [InlineData(@"./Binaries/TLSCallback_x64.dll","92e1156b6a0b77d863388ad0a08e766b91a11aeb")] 33 | [InlineData(@"./Binaries/TLSCallback_x86.exe","4546c11743b919ce740d40de71369493ae1dde46")] 34 | [InlineData(@"./Binaries/win_test.dll","314d1a82f923679d76446bcbeb557de2a390519c")] 35 | public void AuthenticodeHash_GivenABinary_ComputesCorrectHash(string file, string expected) 36 | { 37 | var peFile = new PeFile(file); 38 | var hash = System.Security.Cryptography.SHA1.Create(); 39 | var bytes = peFile.AuthenticodeInfo.ComputeAuthenticodeHashFromPeFile(hash); 40 | var digest = bytes.ToList().ToHexString().Substring(2); 41 | 42 | Assert.Equal(expected, digest); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Authenticode/pidgin.pkcs7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Header/Authenticode/pidgin.pkcs7 -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Authenticode/pkcs7.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Header/Authenticode/pkcs7.bin -------------------------------------------------------------------------------- /test/PeNet.Test/Header/ImpHash/ImpHashTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace PeNet.Test.Header.ImpHash 4 | { 5 | public class ImpHashTest 6 | { 7 | [Theory] 8 | [InlineData(@"./Binaries/win_test.dll", "f9f97e60cfcd78be051d9570c88ffb6f")] 9 | [InlineData(@"./Binaries/NetCoreConsole.dll", "f34d5f2d4577ed6d9ceec516c1f5a744")] 10 | [InlineData(@"./Binaries/pidgin.exe", "91f96ce80cb6ee2b5e5fb6cc19bac72b")] 11 | public void ImpHash_GivenABinary_ComputesCorrectHash(string file, string expected) 12 | { 13 | var peFile = new PeFile(file); 14 | Assert.Equal(expected, peFile.ImpHash); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Net/TypeRefHashTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace PeNet.Test.Header.Net 4 | { 5 | public class TypeRefHashTest 6 | { 7 | [Theory] 8 | [InlineData(@"./Binaries/NetCoreConsole.dll", "9b435fef12d55da7073890330a9a4d7f6e02194aa63e6093429db574407458ba")] 9 | [InlineData(@"./Binaries/NetFrameworkConsole.exe", "c4bc255f816ae338fba805256b078bb023d339d2b80dc84a21444367539038cb")] 10 | [InlineData(@"./Binaries/osx_vb_netcore.dll", "5fda416c838f34364173ed8c3cd7181dad676aaf7e8b2b37e54953405462f42d")] 11 | [InlineData(@"./Binaries/arm_dotnet_binary.dll", "d633db771449e2c37e1689a8c291a4f4646ce156652a9dad5f67394c0d92a8c4")] 12 | public void DotNetFile_ReturnsCorrectTypeRefHash(string file, string hash) 13 | { 14 | var peFile = new PeFile(file); 15 | 16 | Assert.Equal(hash, peFile.TypeRefHash); 17 | } 18 | 19 | [Theory] 20 | [InlineData(@"./Binaries/krnl_test.sys")] 21 | [InlineData(@"./Binaries/No_SEH.exe")] 22 | [InlineData(@"./Binaries/win_test.dll")] 23 | public void NotDotNetFile_ReturnsNull(string file) 24 | { 25 | var peFile = new PeFile(file); 26 | 27 | Assert.Null(peFile.TypeRefHash); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/CopyrightTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class CopyrightTest 9 | { 10 | [Fact] 11 | public void CopyrightConstructorWorks_Test() 12 | { 13 | var copyright = new Copyright(new BufferFile(RawStructures.RawCopyright), 2); 14 | Assert.Equal("copyright", copyright.CopyrightString); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageBaseRelocationTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PeNet.FileParser; 3 | using PeNet.Header.Pe; 4 | using Xunit; 5 | 6 | namespace PeNet.Test.Header.Pe 7 | { 8 | 9 | public class ImageBaseRelocationTest 10 | { 11 | [Fact] 12 | public void SizeOfBlockIsBiggerThanRelocDirSize_Test() 13 | { 14 | var rawImageBaseRelocBroken = new byte[] 15 | {0x00, 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x30, 0xC4, 0x30}; 16 | Assert.Throws(() => new ImageBaseRelocation(new BufferFile(rawImageBaseRelocBroken), 0, 0)); 17 | } 18 | 19 | [Fact] 20 | public void OffsetIsBiggerThanBuffer_Test() 21 | { 22 | Assert.Throws(() => new ImageBaseRelocation(new BufferFile(RawStructures.RawImageBaseRelocation), 1234, 12)); 23 | } 24 | 25 | [Fact] 26 | public void ImageBaseRelocationConstructorWorks_Test() 27 | { 28 | var ibr = new ImageBaseRelocation(new BufferFile(RawStructures.RawImageBaseRelocation), 2, 12); 29 | 30 | Assert.Equal((uint) 0x10000, ibr.VirtualAddress); 31 | Assert.Equal((uint) 0xc, ibr.SizeOfBlock); 32 | Assert.Equal(2, ibr.TypeOffsets.Length); 33 | Assert.Equal(0x2211 >> 12, ibr.TypeOffsets[0].Type); 34 | Assert.Equal(0x2211 & 0xfff, ibr.TypeOffsets[0].Offset); 35 | Assert.Equal(0x4433 >> 12, ibr.TypeOffsets[1].Type); 36 | Assert.Equal(0x4433 & 0xfff, ibr.TypeOffsets[1].Offset); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageBoundImportDescriptorTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageBoundImportDescriptorTest 9 | { 10 | [Fact] 11 | public void ImageBoundImportDescriptorConstructorWorks_Test() 12 | { 13 | var boundImportDescriptor = new ImageBoundImportDescriptor(new BufferFile(RawStructures.RawBoundImportDescriptor), 2); 14 | Assert.Equal((uint) 0x33221100, boundImportDescriptor.TimeDateStamp); 15 | Assert.Equal((ushort) 0x5544, boundImportDescriptor.OffsetModuleName); 16 | Assert.Equal((ushort) 0x7766, boundImportDescriptor.NumberOfModuleForwarderRefs); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageDataDirectoryTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageDataDirectoryTest 9 | { 10 | [Fact] 11 | public void ImageDataDirectoryConstructorWorks_Test() 12 | { 13 | var dataDirectory = new ImageDataDirectory(new BufferFile(RawStructures.RawDataDirectory), 2); 14 | 15 | Assert.Equal((uint) 0x44332211, dataDirectory.VirtualAddress); 16 | Assert.Equal(0x88776655, dataDirectory.Size); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageDelayImportDescriptorTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageDelayImportDescriptorTest 9 | { 10 | [Fact] 11 | public void ImageDelayImportDescriptorConstructorWorks_Test() 12 | { 13 | var delayImportDescriptor = new ImageDelayImportDescriptor(new BufferFile(RawStructures.RawDelayImportDescriptor), 0x2); 14 | Assert.Equal((uint) 0x33221100, delayImportDescriptor.GrAttrs); 15 | Assert.Equal((uint) 0x77665544, delayImportDescriptor.SzName); 16 | Assert.Equal((uint) 0xbbaa9988, delayImportDescriptor.Phmod); 17 | Assert.Equal((uint) 0xffeeddcc, delayImportDescriptor.PIat); 18 | Assert.Equal((uint) 0x44332211, delayImportDescriptor.PInt); 19 | Assert.Equal((uint) 0xccbbaa99, delayImportDescriptor.PUnloadIAT); 20 | Assert.Equal((uint) 0x00ffeedd, delayImportDescriptor.DwTimeStamp); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageDosHeaderTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageDosHeaderTest 9 | { 10 | [Fact] 11 | public void ImageDosHeaderConstructorWorks_Test() 12 | { 13 | var idh = new ImageDosHeader(new BufferFile(RawStructures.RawDosHeader), 0); 14 | Assert.Equal((uint) 0x1100, idh.E_magic); 15 | Assert.Equal((uint) 0x3322, idh.E_cblp); 16 | Assert.Equal((uint) 0x5544, idh.E_cp); 17 | Assert.Equal((uint) 0x7766, idh.E_crlc); 18 | Assert.Equal((uint) 0x9988, idh.E_cparhdr); 19 | Assert.Equal((uint) 0xbbaa, idh.E_minalloc); 20 | Assert.Equal((uint) 0xddcc, idh.E_maxalloc); 21 | Assert.Equal((uint) 0x00ff, idh.E_ss); 22 | Assert.Equal((uint) 0x2211, idh.E_sp); 23 | Assert.Equal((uint) 0x4433, idh.E_csum); 24 | Assert.Equal((uint) 0x6655, idh.E_ip); 25 | Assert.Equal((uint) 0x8877, idh.E_cs); 26 | Assert.Equal((uint) 0xaa99, idh.E_lfarlc); 27 | Assert.Equal((uint) 0xccbb, idh.E_ovno); 28 | AssertEqual(new ushort[] 29 | { 30 | 0xeedd, 31 | 0x00ff, 32 | 0x2211, 33 | 0x4433 34 | }, idh.E_res); 35 | Assert.Equal((uint) 0x6655, idh.E_oemid); 36 | Assert.Equal((uint) 0x8877, idh.E_oeminfo); 37 | AssertEqual(new ushort[] 38 | { 39 | 0xaa99, 40 | 0xccbb, 41 | 0xeedd, 42 | 0x11ff, 43 | 0x3322, 44 | 0x5544, 45 | 0x7766, 46 | 0x9988, 47 | 0xbbaa, 48 | 0xbbcc 49 | }, idh.E_res2); 50 | } 51 | 52 | private void AssertEqual(ushort[] expected, ushort[] actual) 53 | { 54 | Assert.Equal(expected.Length, actual.Length); 55 | for (var i = 0; i < expected.Length; i++) 56 | { 57 | Assert.Equal(expected[i], actual[i]); 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageExportDirectoryTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageExportDirectoryTest 9 | { 10 | [Fact] 11 | public void ImageExportDirectoryConstructorWorks_Test() 12 | { 13 | var exportDirectory = new ImageExportDirectory(new BufferFile(RawStructures.RawExportDirectory), 2); 14 | 15 | Assert.Equal((uint) 0x33221100, exportDirectory.Characteristics); 16 | Assert.Equal((uint) 0x77665544, exportDirectory.TimeDateStamp); 17 | Assert.Equal((ushort) 0x9988, exportDirectory.MajorVersion); 18 | Assert.Equal((ushort) 0xbbaa, exportDirectory.MinorVersion); 19 | Assert.Equal(0xffeeddcc, exportDirectory.Name); 20 | Assert.Equal((uint) 0x55443322, exportDirectory.Base); 21 | Assert.Equal((uint) 0x44332211, exportDirectory.NumberOfFunctions); 22 | Assert.Equal(0x88776655, exportDirectory.NumberOfNames); 23 | Assert.Equal(0xccbbaa99, exportDirectory.AddressOfFunctions); 24 | Assert.Equal((uint) 0x00ffeedd, exportDirectory.AddressOfNames); 25 | Assert.Equal((uint) 0x55443322, exportDirectory.AddressOfNameOrdinals); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageFileHeaderTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageFileHeaderTest 9 | { 10 | [Fact] 11 | public void ImageFileHeaderConstructorWorks_Test() 12 | { 13 | var fileHeader = new ImageFileHeader(new BufferFile(RawStructures.RawFileHeader), 2); 14 | Assert.Equal(MachineType.Amd64, fileHeader.Machine); 15 | Assert.Equal("AMD64", fileHeader.MachineResolved); 16 | Assert.Equal((ushort) 0x3322, fileHeader.NumberOfSections); 17 | Assert.Equal((uint) 0x77665544, fileHeader.TimeDateStamp); 18 | Assert.Equal(0xbbaa9988, fileHeader.PointerToSymbolTable); 19 | Assert.Equal(0xffeeddcc, fileHeader.NumberOfSymbols); 20 | Assert.Equal((ushort) 0x2211, fileHeader.SizeOfOptionalHeader); 21 | Assert.True(fileHeader.Characteristics.HasFlag(FileCharacteristicsType.Dll)); 22 | Assert.Contains("Dll", fileHeader.CharacteristicsResolved); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageImportByNameTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageImportByNameTest 9 | { 10 | [Fact] 11 | public void ImageImportByNameConstructorWorks_Test() 12 | { 13 | var importByName = new ImageImportByName(new BufferFile(RawStructures.RawImportByName), 2); 14 | Assert.Equal((ushort) 0x1100, importByName.Hint); 15 | Assert.Equal("Hello World", importByName.Name); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageImportDescriptorTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageImportDescriptorTest 9 | { 10 | [Fact] 11 | public void ImageImportDescriptorConstructorWorks_Test() 12 | { 13 | var importDescriptor = new ImageImportDescriptor(new BufferFile(RawStructures.RawImportDescriptor), 2); 14 | Assert.Equal((uint) 0x33221100, importDescriptor.OriginalFirstThunk); 15 | Assert.Equal((uint) 0x77665544, importDescriptor.TimeDateStamp); 16 | Assert.Equal(0xbbaa9988, importDescriptor.ForwarderChain); 17 | Assert.Equal(0xffeeddcc, importDescriptor.Name); 18 | Assert.Equal((uint) 0x44332211, importDescriptor.FirstThunk); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageNtHeadersTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageNtHeadersTest 9 | { 10 | [Fact] 11 | public void ImageNtHeadersConstructorWorks_Test() 12 | { 13 | var ntHeaders = new ImageNtHeaders(new BufferFile(RawStructures.RawImageNtHeaders64), 2); 14 | Assert.Equal((uint) 0x33221100, ntHeaders.Signature); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageResourceDataEntryTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageResourceDataEntryTest 9 | { 10 | [Fact] 11 | public void ImageResourceDataEntryConstructorWorks_Test() 12 | { 13 | var fakeParent = new ImageResourceDirectoryEntry(null, null, 0, 0); 14 | 15 | var resourceDataEntry = new ImageResourceDataEntry(new BufferFile(RawStructures.RawResourceDataEntry), fakeParent, 2); 16 | 17 | Assert.Equal((uint) 0x33221100, resourceDataEntry.OffsetToData); 18 | Assert.Equal((uint) 0x77665544, resourceDataEntry.Size1); 19 | Assert.Equal(0xbbaa9988, resourceDataEntry.CodePage); 20 | Assert.Equal(0xffeeddcc, resourceDataEntry.Reserved); 21 | Assert.Equal(fakeParent, resourceDataEntry.Parent); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageResourceDirStringUTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | public class ImageResourceDirStringUTest 8 | { 9 | [Fact] 10 | public void ImageResourceDirStringUConstructorWorks_Test() 11 | { 12 | var resourceDirStringU = new ImageResourceDirStringU(new BufferFile(RawStructures.RawResourceDirStringU), 2); 13 | Assert.Equal((uint) 0x000b, resourceDirStringU.Length); 14 | Assert.Equal("Hello World", resourceDirStringU.NameString); 15 | 16 | var secondResourceDirStringU = new ImageResourceDirStringU(new BufferFile(RawStructures.RawResourceDirStringU), 2 + 2 + (uint) 0x000b * 2 /* start offset + size of first length + length of first in bytes */); 17 | Assert.Equal((uint) 0x0006, secondResourceDirStringU.Length); 18 | Assert.Equal("Second", secondResourceDirStringU.NameString); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageResourceDirectoryEntryTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageResourceDirectoryEntryTest 9 | { 10 | [Fact] 11 | public void ResourceDirectoryEntryByNameConstructorWorks_Test() 12 | { 13 | var fakeParent = new ImageResourceDirectory(null, null, 0, 0, 0); 14 | 15 | var resourceDirectoryEntry = 16 | new ImageResourceDirectoryEntry(new BufferFile(RawStructures.RawResourceDirectoryEntryByName), fakeParent, 2, 2); 17 | 18 | Assert.True(resourceDirectoryEntry.IsNamedEntry); 19 | Assert.False(resourceDirectoryEntry.IsIdEntry); 20 | Assert.Equal(0x80332211, resourceDirectoryEntry.Name); 21 | Assert.Equal((uint) 0x55443322, resourceDirectoryEntry.OffsetToData); 22 | Assert.Equal(fakeParent, resourceDirectoryEntry.Parent); 23 | } 24 | 25 | [Fact] 26 | public void ResourceDirectoryEntryByIdConstructorWorks_Test() 27 | { 28 | var fakeParent = new ImageResourceDirectory(null, null, 0, 0, 0); 29 | 30 | var resourceDirectoryEntry = 31 | new ImageResourceDirectoryEntry(new BufferFile(RawStructures.RawResourceDirectoryEntryById), fakeParent, 2, 2); 32 | 33 | Assert.True(resourceDirectoryEntry.IsIdEntry); 34 | Assert.False(resourceDirectoryEntry.IsNamedEntry); 35 | Assert.Equal((uint) 0x00332211 & 0xFFFF, resourceDirectoryEntry.ID); 36 | Assert.Equal((uint) 0x55443322, resourceDirectoryEntry.OffsetToData); 37 | Assert.Equal(fakeParent, resourceDirectoryEntry.Parent); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageResourceDirectoryTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageResourceDirectoryTest 9 | { 10 | [Fact] 11 | public void ImageResourceDirectoryConstructorWorks_Test() 12 | { 13 | var fakeParent = new ImageResourceDirectoryEntry(null, null, 0, 0); 14 | 15 | var resourceDirectory = new ImageResourceDirectory(new BufferFile(RawStructures.RawResourceDirectory), fakeParent, 2, 2, RawStructures.RawResourceDirectory.Length); 16 | 17 | Assert.Equal((uint) 0x33221100, resourceDirectory.Characteristics); 18 | Assert.Equal((uint) 0x77665544, resourceDirectory.TimeDateStamp); 19 | Assert.Equal((ushort) 0x9988, resourceDirectory.MajorVersion); 20 | Assert.Equal((ushort) 0xbbaa, resourceDirectory.MinorVersion); 21 | Assert.Equal((ushort) 0x0001, resourceDirectory.NumberOfNameEntries); 22 | Assert.Equal((ushort) 0x0001, resourceDirectory.NumberOfIdEntries); 23 | Assert.Equal((uint) 0x44332211, resourceDirectory.DirectoryEntries[0].Name); 24 | Assert.Equal((uint) 0x00000011, resourceDirectory.DirectoryEntries[0].OffsetToData); 25 | Assert.Equal((uint) 0x44332222 & 0xFFFF, resourceDirectory.DirectoryEntries[1].ID); 26 | Assert.Equal((uint) 0x00000022, resourceDirectory.DirectoryEntries[1].OffsetToData); 27 | Assert.Equal(fakeParent, resourceDirectory.Parent); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageSectionHeaderTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageSectionHeaderTest 9 | { 10 | [Fact] 11 | public void ImageSectionHeaderConstructorWorks_Test() 12 | { 13 | var sectionHeader = new ImageSectionHeader(new BufferFile(RawStructures.RawSectionHeader), 2, 0); 14 | 15 | Assert.Equal(".data", sectionHeader.Name); 16 | Assert.Equal((uint) 0x33221100, sectionHeader.VirtualSize); 17 | Assert.Equal((uint) 0x77665544, sectionHeader.VirtualAddress); 18 | Assert.Equal(0xbbaa9988, sectionHeader.SizeOfRawData); 19 | Assert.Equal(0xffeeddcc, sectionHeader.PointerToRawData); 20 | Assert.Equal((uint) 0x44332211, sectionHeader.PointerToRelocations); 21 | Assert.Equal(0x88776655, sectionHeader.PointerToLinenumbers); 22 | Assert.Equal((ushort) 0xaa99, sectionHeader.NumberOfRelocations); 23 | Assert.Equal((ushort) 0xccbb, sectionHeader.NumberOfLinenumbers); 24 | Assert.Equal((ScnCharacteristicsType) 0x00000820, sectionHeader.Characteristics); 25 | Assert.Equal(2, sectionHeader.CharacteristicsResolved.Count); 26 | Assert.Contains("LnkRemove", sectionHeader.CharacteristicsResolved); 27 | Assert.Contains("CntCode", sectionHeader.CharacteristicsResolved); 28 | } 29 | 30 | [Fact] 31 | public void ImageSectionHeader_CorrectSectionNames() 32 | { 33 | var peFile = new PeFile(@"./Binaries/pdb_guid.exe"); 34 | var snc = peFile.ImageSectionHeaders; 35 | 36 | Assert.Equal(".text", snc[0].Name); 37 | Assert.Equal("ERRATA", snc[1].Name); 38 | Assert.Equal("INITKDBG", snc[2].Name); 39 | Assert.Equal("POOLCODE", snc[3].Name); 40 | Assert.Equal(".rdata", snc[4].Name); 41 | Assert.Equal(".data", snc[5].Name); 42 | Assert.Equal(".pdata", snc[6].Name); 43 | Assert.Equal("ALMOSTRO", snc[7].Name); 44 | Assert.Equal("CACHEALI", snc[8].Name); 45 | Assert.Equal("PAGELK", snc[9].Name); 46 | Assert.Equal("PAGE", snc[10].Name); 47 | Assert.Equal("PAGEKD", snc[11].Name); 48 | Assert.Equal("PAGEVRFY", snc[12].Name); 49 | Assert.Equal("PAGEHDLS", snc[13].Name); 50 | Assert.Equal("PAGEBGFX", snc[14].Name); 51 | Assert.Equal("PAGEVRFB", snc[15].Name); 52 | Assert.Equal(".edata", snc[16].Name); 53 | Assert.Equal("PAGEDATA", snc[17].Name); 54 | Assert.Equal("PAGEVRFD", snc[18].Name); 55 | Assert.Equal("INITDATA", snc[19].Name); 56 | Assert.Equal("INIT", snc[20].Name); 57 | Assert.Equal(".rsrc", snc[21].Name); 58 | Assert.Equal(".reloc", snc[22].Name); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageThunkDateTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class IMAGE_THUNK_DATA_Test 9 | { 10 | [Fact] 11 | public void ImageThunkData64ConstructorWorks_Test() 12 | { 13 | var thunkData64 = new ImageThunkData(new BufferFile(RawStructures.RawThunkData64), 2, true); 14 | 15 | Assert.Equal((ulong) 0x7766554433221100, thunkData64.AddressOfData); 16 | Assert.Equal((ulong) 0x7766554433221100, thunkData64.ForwarderString); 17 | Assert.Equal((ulong) 0x7766554433221100, thunkData64.Function); 18 | Assert.Equal((ulong) 0x7766554433221100, thunkData64.Ordinal); 19 | } 20 | 21 | [Fact] 22 | public void ImageThunkData32ConstructorWorks_Test() 23 | { 24 | var thunkData32 = new ImageThunkData(new BufferFile(RawStructures.RawThunkData32), 2, false); 25 | 26 | Assert.Equal((ulong) 0x33221100, thunkData32.AddressOfData); 27 | Assert.Equal((ulong) 0x33221100, thunkData32.ForwarderString); 28 | Assert.Equal((ulong) 0x33221100, thunkData32.Function); 29 | Assert.Equal((ulong) 0x33221100, thunkData32.Ordinal); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageTlsCallbackTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using PeNet.FileParser; 3 | using PeNet.Header.Pe; 4 | using Xunit; 5 | 6 | namespace PeNet.Test.Header.Pe 7 | { 8 | 9 | public class ImageTlsCallbackTest 10 | { 11 | [Fact] 12 | public void ImageTlsCallback64ConstructorWorks_Test() 13 | { 14 | var tlsCallback = new ImageTlsCallback(new BufferFile(RawStructures.RawTlsCallback64), 2, true); 15 | Assert.Equal((ulong) 0x7766554433221100, tlsCallback.Callback); 16 | } 17 | 18 | [Fact] 19 | public void ImageTlsCallback32ConstructorWorks_Test() 20 | { 21 | var tlsCallback = new ImageTlsCallback(new BufferFile(RawStructures.RawTlsCallback32), 2, false); 22 | Assert.Equal((ulong)0x33221100, tlsCallback.Callback); 23 | } 24 | 25 | [Fact] 26 | public void TLSCallback_x86_Works_Test() 27 | { 28 | // Given 29 | var peFile = new PeFile(@"../../../Binaries/TLSCallback_x86.exe"); 30 | 31 | // When 32 | var callbacks = peFile.ImageTlsDirectory.TlsCallbacks; 33 | 34 | // Then 35 | Assert.Single(callbacks); 36 | Assert.Equal((ulong) 0x004111CC, callbacks.First().Callback); 37 | } 38 | 39 | [Fact] 40 | public void TLSCallback_x64_Works1_Test() 41 | { 42 | // Given 43 | var peFile = new PeFile(@"../../../Binaries/TLSCallback_x64.dll"); 44 | 45 | // When 46 | var callbacks = peFile.ImageTlsDirectory.TlsCallbacks; 47 | 48 | // Then 49 | Assert.Single(callbacks); 50 | Assert.Equal((ulong) 0x0000000180001000, callbacks.First().Callback); 51 | } 52 | 53 | [Fact] 54 | public void TLSCallback_x64_Works2_Test() 55 | { 56 | // Given 57 | var peFile = new PeFile(@"../../../Binaries/firefox_x64.exe"); 58 | 59 | // When 60 | var callbacks = peFile.ImageTlsDirectory.TlsCallbacks; 61 | 62 | // Then 63 | Assert.Single(callbacks); 64 | Assert.Equal((ulong) 0x00000001400044a0, callbacks.First().Callback); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/ImageTlsDirectoryTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class ImageTlsDirectoryTest 9 | { 10 | [Fact] 11 | public void ImageTlsDirectory64ConstructorWorks_Test() 12 | { 13 | var tlsDirectory = new ImageTlsDirectory(new BufferFile(RawStructures.RawTlsDirectory64), 2, true); 14 | 15 | Assert.Equal((ulong) 0x7766554433221100, tlsDirectory.StartAddressOfRawData); 16 | Assert.Equal((ulong) 0xbbaa998877665544, tlsDirectory.EndAddressOfRawData); 17 | Assert.Equal((ulong) 0x221100ffeeddccbb, tlsDirectory.AddressOfIndex); 18 | Assert.Equal((ulong) 0xaa99887766554433, tlsDirectory.AddressOfCallBacks); 19 | Assert.Equal((uint) 0x44332211, tlsDirectory.SizeOfZeroFill); 20 | Assert.Equal((uint) 0x99887766, tlsDirectory.Characteristics); 21 | } 22 | 23 | [Fact] 24 | public void ImageTlsDirectory32ConstructorWorks_Test() 25 | { 26 | ImageTlsDirectory tlsDirectory = new ImageTlsDirectory(new BufferFile(RawStructures.RawTlsDirectory32), 2, false); 27 | 28 | Assert.Equal((ulong)0x33221100, tlsDirectory.StartAddressOfRawData); 29 | Assert.Equal((ulong)0x77665544, tlsDirectory.EndAddressOfRawData); 30 | Assert.Equal((ulong)0xeeddccbb, tlsDirectory.AddressOfIndex); 31 | Assert.Equal((ulong)0x66554433, tlsDirectory.AddressOfCallBacks); 32 | Assert.Equal((uint)0x44332211, tlsDirectory.SizeOfZeroFill); 33 | Assert.Equal((uint)0x99887766, tlsDirectory.Characteristics); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/RuntimeFunctionTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class RuntimeFunctionTest 9 | { 10 | [Fact] 11 | public void RuntimeFunctionConstructorWorks_Test() 12 | { 13 | var runtimeFunction = new RuntimeFunction(new BufferFile(RawStructures.RawRuntimeFunction), 2, null); 14 | 15 | Assert.Equal((uint) 0x33221100, runtimeFunction.FunctionStart); 16 | Assert.Equal((uint) 0x77665544, runtimeFunction.FunctionEnd); 17 | Assert.Equal((uint) 0xbbaa9988, runtimeFunction.UnwindInfo); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/UnwindCodeTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class UnwindCodeTest 9 | { 10 | [Fact] 11 | public void UnwindCodeConstructorWorks_Test() 12 | { 13 | var unwindCode = new UnwindCode(new BufferFile(RawStructures.RawUnwindCode), 2); 14 | 15 | Assert.Equal((byte) 0x11, unwindCode.CodeOffset); 16 | Assert.Equal(UnwindOpType.AllocSmall, unwindCode.UnwindOp); 17 | Assert.Equal((byte) 0x3, unwindCode.Opinfo); 18 | Assert.Equal((ushort) 0x5544, unwindCode.FrameOffset); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/UnwindInfoTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class UnwindInfoTest 9 | { 10 | [Fact] 11 | public void UnwindInfoConstructorWorks_Test() 12 | { 13 | var unwindInfo = new UnwindInfo(new BufferFile(RawStructures.RawUnwindInfo), 2); 14 | Assert.Equal((byte) 0x12, unwindInfo.Version); 15 | Assert.Equal((byte) 0x1, unwindInfo.Flags); 16 | Assert.Equal((byte) 0x33, unwindInfo.SizeOfProlog); 17 | Assert.Equal((byte) 0x5, unwindInfo.FrameRegister); 18 | Assert.Equal((byte) 0x6, unwindInfo.FrameOffset); 19 | 20 | Assert.Single(unwindInfo.UnwindCode); 21 | Assert.Equal((byte) 0x77, unwindInfo.UnwindCode[0].CodeOffset); 22 | Assert.Equal(UnwindOpType.SaveXmm128, unwindInfo.UnwindCode[0].UnwindOp); 23 | Assert.Equal((byte) 0x9, unwindInfo.UnwindCode[0].Opinfo); 24 | 25 | Assert.Equal(0xffeeddcc, unwindInfo.ExceptionHandler); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Header/Pe/WinCertificateTest.cs: -------------------------------------------------------------------------------- 1 | using PeNet.FileParser; 2 | using PeNet.Header.Pe; 3 | using Xunit; 4 | 5 | namespace PeNet.Test.Header.Pe 6 | { 7 | 8 | public class WinCertificateTest 9 | { 10 | [Fact] 11 | public void WinCertificateConstructorWorks_Test() 12 | { 13 | var winCertifiacte = new WinCertificate(new BufferFile(RawStructures.RawWinCertificate), 2); 14 | Assert.Equal((uint) 0x0000000b, winCertifiacte.DwLength); 15 | Assert.Equal((ushort) 0x5544, winCertifiacte.WRevision); 16 | Assert.Equal((ushort) 0x7766, (ushort) winCertifiacte.WCertificateType); 17 | Assert.Equal((byte) 0x11, winCertifiacte.BCertificate[0]); 18 | Assert.Equal((byte) 0x22, winCertifiacte.BCertificate[1]); 19 | Assert.Equal((byte) 0x33, winCertifiacte.BCertificate[2]); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/README.md: -------------------------------------------------------------------------------- 1 | Raw icons extracted with CFF Explorer VIII. 2 | 3 | -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon1.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon10.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon10.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon11.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon11.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon12.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon12.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon13.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon13.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon14.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon14.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon15.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon15.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon16.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon17.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon17.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon18.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon18.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon2.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon3.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon3.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon4.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon4.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon5.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon5.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon6.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon6.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon7.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon7.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon8.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon8.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon9.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/firefox_x64.exe/ico/Icon9.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon1.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon2.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon3.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon3.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon4.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon4.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon5.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon5.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon6.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon6.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon7.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon7.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon8.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon8.ico -------------------------------------------------------------------------------- /test/PeNet.Test/Icons/pidgin.exe/ico/Icon9.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secana/PeNet/e6e436158c06c8c35c7e52744ceb7de6cf20b5e6/test/PeNet.Test/Icons/pidgin.exe/ico/Icon9.ico --------------------------------------------------------------------------------