diff --git a/.editorconfig b/.editorconfig index cb51c9f..573f622 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,84 +8,101 @@ indent_style = tab trim_trailing_whitespace = true insert_final_newline = true -[*.xaml] -indent_style = space - # C# files [*.cs] #### .NET Coding Conventions #### +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = true + # this. and Me. preferences -dotnet_style_qualification_for_event = false:silent -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_event = false:suggestion +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_property = false:suggestion # Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion # Parentheses preferences -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion # Modifier preferences dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent # Expression-level preferences -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_style_inlined_variable_declaration = false:suggestion -csharp_style_throw_expression = false:suggestion dotnet_style_coalesce_expression = true:suggestion dotnet_style_collection_initializer = true:suggestion dotnet_style_explicit_tuple_names = true:suggestion dotnet_style_null_propagation = true:suggestion dotnet_style_object_initializer = true:suggestion -dotnet_style_prefer_auto_properties = false:silent +dotnet_style_prefer_auto_properties = false:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion dotnet_style_prefer_conditional_expression_over_assignment = true:silent dotnet_style_prefer_conditional_expression_over_return = true:silent dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion dotnet_style_prefer_inferred_tuple_names = true:suggestion dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion # Field preferences dotnet_style_readonly_field = true:suggestion +# Parameter preferences +dotnet_code_quality_unused_parameters = all:suggestion + #### C# Coding Conventions #### # var preferences -csharp_style_var_elsewhere = false:silent -csharp_style_var_for_built_in_types = false:silent -csharp_style_var_when_type_is_apparent = false:silent +csharp_style_var_elsewhere = true:suggestion +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion # Expression-bodied members -csharp_style_expression_bodied_accessors = true:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_lambdas = true:silent -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_accessors = true:suggestion +csharp_style_expression_bodied_constructors = false:suggestion +csharp_style_expression_bodied_indexers = true:suggestion +csharp_style_expression_bodied_lambdas = true:suggestion +csharp_style_expression_bodied_local_functions = false:suggestion +csharp_style_expression_bodied_methods = false:suggestion +csharp_style_expression_bodied_operators = false:suggestion +csharp_style_expression_bodied_properties = true:suggestion # Pattern matching preferences -csharp_style_pattern_matching_over_as_with_null_check = false:suggestion -csharp_style_pattern_matching_over_is_with_cast_check = false:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_switch_expression = true:suggestion # Null-checking preferences csharp_style_conditional_delegate_call = true:suggestion # Modifier preferences -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async +csharp_prefer_static_local_function = true:suggestion +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent # Code-block preferences csharp_prefer_braces = false:silent +csharp_prefer_simple_using_statement = true:suggestion # Expression-level preferences csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = unused_local_variable:silent +csharp_style_unused_value_expression_statement_preference = unused_local_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:suggestion #### C# Formatting Rules #### @@ -102,7 +119,7 @@ csharp_new_line_between_query_expression_clauses = false csharp_indent_block_contents = true csharp_indent_braces = false csharp_indent_case_contents = true -csharp_indent_case_contents_when_block = true +csharp_indent_case_contents_when_block = false csharp_indent_labels = one_less_than_current csharp_indent_switch_labels = false @@ -134,5 +151,44 @@ csharp_space_between_square_brackets = false csharp_preserve_single_line_blocks = true csharp_preserve_single_line_statements = true -# IDE0063: Use simple 'using' statement -csharp_prefer_simple_using_statement = true:none +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case diff --git a/.gitignore b/.gitignore index 3c4efe2..ff742d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files +*.rsuser *.suo *.user *.userosscache @@ -17,16 +20,21 @@ [Rr]eleases/ x64/ x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ -# Visual Studio 2015 cache/options directory +# Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ +# Visual Studio 2017 auto generated files +Generated\ Files/ + # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* @@ -40,19 +48,28 @@ TestResult.xml [Rr]eleasePS/ dlldata.c -# DNX +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core project.lock.json project.fragment.lock.json artifacts/ +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio *_i.c *_p.c -*_i.h +*_h.h *.ilk *.meta *.obj +*.iobj *.pch *.pdb +*.ipdb *.pgc *.pgd *.rsp @@ -62,6 +79,7 @@ artifacts/ *.tlh *.tmp *.tmp_proj +*_wpftmp.csproj *.log *.vspscc *.vssscc @@ -90,6 +108,9 @@ ipch/ *.vspx *.sap +# Visual Studio Trace Files +*.e2e + # TFS 2012 Local Workspace $tf/ @@ -110,6 +131,14 @@ _TeamCity* # DotCover is a Code Coverage Tool *.dotCover +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + # NCrunch _NCrunch_* .*crunch*.local.xml @@ -141,9 +170,9 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings +# Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted -#*.pubxml +*.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to @@ -154,12 +183,12 @@ PublishScripts/ # NuGet Packages *.nupkg # The packages folder can be ignored because of Package Restore -**/packages/* +**/[Pp]ackages/* # except build/, which is used as an MSBuild target. -!**/packages/build/ +!**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets @@ -176,12 +205,13 @@ AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt +*.appx # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache -!*.[Cc]ache/ +!?*.[Cc]ache/ # Others ClientBin/ @@ -192,9 +222,12 @@ ClientBin/ *.jfm *.pfx *.publishsettings -node_modules/ orleans.codegen.cs +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ @@ -209,15 +242,20 @@ _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak # SQL Server files *.mdf *.ldf +*.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl # Microsoft Fakes FakesAssemblies/ @@ -227,6 +265,7 @@ FakesAssemblies/ # Node.js Tools for Visual Studio .ntvs_analysis.dat +node_modules/ # Visual Studio 6 build log *.plg @@ -234,6 +273,9 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts @@ -253,9 +295,49 @@ paket-files/ .idea/ *.sln.iml -# CodeRush -.cr/ +# CodeRush personal settings +.cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# wwh1004 +launchSettings.json \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index da079d0..0000000 --- a/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "Libraries/clrmd"] - path = Libraries/clrmd - url = https://github.com/Microsoft/clrmd.git -[submodule "Libraries/dnlib"] - path = Libraries/dnlib - url = https://github.com/0xd4d/dnlib.git -[submodule "Libraries/MetadataLocator"] - path = Libraries/MetadataLocator - url = https://github.com/wwh1004/MetadataLocator.git diff --git a/ExtremeDumper-x86/ExtremeDumper-x86.csproj b/ExtremeDumper-x86/ExtremeDumper-x86.csproj index dd1e082..1bf590d 100644 --- a/ExtremeDumper-x86/ExtremeDumper-x86.csproj +++ b/ExtremeDumper-x86/ExtremeDumper-x86.csproj @@ -1,54 +1,6 @@ - - - - - Debug - AnyCPU - {F4ED1869-89DC-4A43-A2D7-0766533EB2BA} - WinExe - ExtremeDumper_x86 - ExtremeDumper-x86 - v4.0 - 512 - true - - - x86 - true - full - false - ..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - ..\bin\Release\ - TRACE - prompt - 4 - - - - - - ..\ExtremeDumper\Forms\Resources\Icon.ico - - - - - - - - {ba1d5a3e-330e-4d82-bff5-58b6cf52726c} - ExtremeDumper - - - - - - - \ No newline at end of file + + + x86 + + + diff --git a/ExtremeDumper-x86/Program.cs b/ExtremeDumper-x86/Program.cs index 45aa147..374030a 100644 --- a/ExtremeDumper-x86/Program.cs +++ b/ExtremeDumper-x86/Program.cs @@ -1,10 +1,12 @@ using System; +using System.IO; +using System.Reflection; namespace ExtremeDumper_x86 { internal static class Program { [STAThread] private static void Main() { - ExtremeDumper.Program.Main(); + Assembly.LoadFile(Path.GetFullPath("ExtremeDumper.exe")).EntryPoint.Invoke(null, null); } } } diff --git a/ExtremeDumper.AntiAntiDump/ExtremeDumper.AntiAntiDump.csproj b/ExtremeDumper.AntiAntiDump/ExtremeDumper.AntiAntiDump.csproj deleted file mode 100644 index c6b70eb..0000000 --- a/ExtremeDumper.AntiAntiDump/ExtremeDumper.AntiAntiDump.csproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - - Debug - AnyCPU - {DFFAB16F-40BE-46B2-AA4A-0FD49C1CCCAA} - Library - Properties - ExtremeDumper.AntiAntiDump - ExtremeDumper.AntiAntiDump - v3.5 - 512 - true - - - true - full - false - ..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - 7.3 - - - pdbonly - true - ..\bin\Release\ - TRACE - prompt - 4 - true - 7.3 - - - - - - - - - - - - - - - - - {aed69d77-8c7b-41ba-9967-ac9b522430f9} - MetadataLocator - - - - \ No newline at end of file diff --git a/ExtremeDumper.AntiAntiDump/Injection.cs b/ExtremeDumper.AntiAntiDump/Injection.cs deleted file mode 100644 index 8199704..0000000 --- a/ExtremeDumper.AntiAntiDump/Injection.cs +++ /dev/null @@ -1,18 +0,0 @@ -using ExtremeDumper.AntiAntiDump.Serialization; - -namespace ExtremeDumper.AntiAntiDump { - public static class Injection { - public static int Main(string arg) { - try { - InjectionOptions options; - - options = XmlSerializer.Deserialize(arg); - new MetadataInfoService().Start(options.PortName, options.ObjectName); - } - catch { - return -1; - } - return 0; - } - } -} diff --git a/ExtremeDumper.AntiAntiDump/InjectionOptions.cs b/ExtremeDumper.AntiAntiDump/InjectionOptions.cs deleted file mode 100644 index 8fc0a5b..0000000 --- a/ExtremeDumper.AntiAntiDump/InjectionOptions.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace ExtremeDumper.AntiAntiDump { - [Serializable] - public sealed class InjectionOptions { - public string PortName; - - public string ObjectName; - } -} diff --git a/ExtremeDumper.AntiAntiDump/MetadataInfo.cs b/ExtremeDumper.AntiAntiDump/MetadataInfo.cs deleted file mode 100644 index 0289266..0000000 --- a/ExtremeDumper.AntiAntiDump/MetadataInfo.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using MetadataLocator; -using InternalDotNetPEInfo = MetadataLocator.DotNetPEInfo; -using InternalMetadataInfo = MetadataLocator.MetadataInfo; -using InternalMetadataStreamInfo = MetadataLocator.MetadataStreamInfo; - -namespace ExtremeDumper.AntiAntiDump { - /// - /// Metadata stream info - /// - [Serializable] - public sealed class MetadataStreamInfo { - /// - public uint Rva; - - /// - public uint Length; - - /// - public MetadataStreamInfo() { - } - - internal unsafe MetadataStreamInfo(InternalMetadataStreamInfo streamInfo, IntPtr moduleHandle) { - Rva = (uint)((byte*)streamInfo.Address - (byte*)moduleHandle); - Length = streamInfo.Length; - } - } - - /// - /// .NET PE Info - /// - [Serializable] - public sealed class DotNetPEInfo { - /// - /// Determine if current instance is valid - /// - public bool IsValid; - - /// - /// ImageLayout - /// - public ImageLayout ImageLayout; - - /// - /// Rva of COR20_HEADER - /// NOTICE: It is calculated by (pCor20Header - methodHandle). So you can't direct use it to fill the field ".NET Metadata Directory Rva" - /// - public uint Cor20HeaderRva; - - /// - /// Rva of metadata - /// NOTICE: It is calculated by (pMetadata - methodHandle). So you can't direct use it to fill the field "Metadata Rva" - /// - public uint MetadataRva; - - /// - /// Size of metadata - /// - public uint MetadataSize; - - /// - public DotNetPEInfo() { - } - - internal unsafe DotNetPEInfo(InternalDotNetPEInfo peInfo, IntPtr moduleHandle) { - IsValid = peInfo.IsValid; - ImageLayout = peInfo.ImageLayout; - Cor20HeaderRva = (uint)((byte*)peInfo.Cor20HeaderAddress - (byte*)moduleHandle); - MetadataRva = (uint)((byte*)peInfo.MetadataAddress - (byte*)moduleHandle); - MetadataSize = peInfo.MetadataSize; - } - } - - /// - /// Metadata info - /// - [Serializable] - public sealed class MetadataInfo { - /// - /// #~ or #- info - /// - public MetadataStreamInfo TableStream; - - /// - /// #Strings heap info - /// - public MetadataStreamInfo StringHeap; - - /// - /// #US heap info - /// - public MetadataStreamInfo UserStringHeap; - - /// - /// #GUID heap info - /// - public MetadataStreamInfo GuidHeap; - - /// - /// #Blob heap info - /// - public MetadataStreamInfo BlobHeap; - - /// - /// .NET PE Info (invalid if PEInfo.IsNativeImage is true) - /// - public DotNetPEInfo PEInfo; - - /// - public MetadataInfo() { - } - - internal MetadataInfo(InternalMetadataInfo metadataInfo) { - if (metadataInfo is null) - throw new ArgumentNullException(nameof(metadataInfo)); - - IntPtr moduleHandle; - - moduleHandle = Marshal.GetHINSTANCE(metadataInfo.Module); - if (!(metadataInfo.TableStream is null)) - TableStream = new MetadataStreamInfo(metadataInfo.TableStream, moduleHandle); - if (!(metadataInfo.StringHeap is null)) - StringHeap = new MetadataStreamInfo(metadataInfo.StringHeap, moduleHandle); - if (!(metadataInfo.UserStringHeap is null)) - UserStringHeap = new MetadataStreamInfo(metadataInfo.UserStringHeap, moduleHandle); - if (!(metadataInfo.GuidHeap is null)) - GuidHeap = new MetadataStreamInfo(metadataInfo.GuidHeap, moduleHandle); - if (!(metadataInfo.BlobHeap is null)) - BlobHeap = new MetadataStreamInfo(metadataInfo.BlobHeap, moduleHandle); - PEInfo = new DotNetPEInfo(metadataInfo.PEInfo, moduleHandle); - } - } -} diff --git a/ExtremeDumper.AntiAntiDump/MetadataInfoService.cs b/ExtremeDumper.AntiAntiDump/MetadataInfoService.cs deleted file mode 100644 index d155a54..0000000 --- a/ExtremeDumper.AntiAntiDump/MetadataInfoService.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Remoting; -using System.Runtime.Remoting.Channels; -using System.Runtime.Remoting.Channels.Ipc; -using ExtremeDumper.AntiAntiDump.Serialization; -using InternalMetadataInfo = MetadataLocator.MetadataInfo; - -namespace ExtremeDumper.AntiAntiDump { - /// - /// Provide metadata info service - /// - public sealed unsafe class MetadataInfoService : MarshalByRefObject { - private static readonly Dictionary _cachedModules = new Dictionary(); - - public void Start(string portName, string objectName) { - if (string.IsNullOrEmpty(portName)) - throw new ArgumentNullException(nameof(portName)); - if (string.IsNullOrEmpty(objectName)) - throw new ArgumentNullException(nameof(objectName)); - - ChannelServices.RegisterChannel(new IpcServerChannel(null, portName), false); - RemotingServices.Marshal(this, objectName); - } - - /// - /// Get metadata info - /// - /// - /// - public string GetMetadataInfo(IntPtr moduleHandle) { - Module module; - MetadataInfo metadataInfo; - - module = GetModuleFromNativeModuleHandle(moduleHandle); - metadataInfo = new MetadataInfo(InternalMetadataInfo.GetMetadataInfo(module)); - return XmlSerializer.Serialize(metadataInfo); - } - - private static Module GetModuleFromNativeModuleHandle(IntPtr moduleHandle) { - Module module; - - if (!_cachedModules.TryGetValue(moduleHandle, out module)) { - module = EnumerateLoadedModules().FirstOrDefault(t => Marshal.GetHINSTANCE(t) == moduleHandle); - if (!(module is null)) - // 如果获取成功,缓存结果,EnumerateLoadedModules()是很耗时的操作 - _cachedModules.Add(moduleHandle, module); - } - if (module is null) - throw new InvalidOperationException($"Can't get System.Reflection.Module from a native module handle (0x{moduleHandle.ToString(IntPtr.Size == 4 ? "X8" : "X16")})."); - return module; - } - - private static IEnumerable EnumerateLoadedModules() { - return AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetLoadedModules()); - } - } -} diff --git a/ExtremeDumper.AntiAntiDump/Properties/AssemblyInfo.cs b/ExtremeDumper.AntiAntiDump/Properties/AssemblyInfo.cs deleted file mode 100644 index e3c0f36..0000000 --- a/ExtremeDumper.AntiAntiDump/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System.Reflection; - -[assembly: AssemblyTitle("ExtremeDumper.AntiAntiDump")] -[assembly: AssemblyProduct("ExtremeDumper.AntiAntiDump")] -[assembly: AssemblyCopyright("Copyright © 2019 Wwh")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] diff --git a/ExtremeDumper.AntiAntiDump/Serialization/XmlSerializer.cs b/ExtremeDumper.AntiAntiDump/Serialization/XmlSerializer.cs deleted file mode 100644 index 058a7c0..0000000 --- a/ExtremeDumper.AntiAntiDump/Serialization/XmlSerializer.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.IO; -using System.Text; - -namespace ExtremeDumper.AntiAntiDump.Serialization { - /// - /// 对对象进行XML序列化/反序列化操作,对象访问级别至少为public - /// - public static class XmlSerializer { - /// - /// 序列化对象为XML - /// - /// - /// 被序列化的对象 - /// - public static string Serialize(T obj) { - using (MemoryStream stream = new MemoryStream()) { - Serializer.Instance.Serialize(stream, obj); - return Encoding.UTF8.GetString(stream.ToArray()); - } - } - - /// - /// 反序列化XML为对象 - /// - /// - /// XML - /// - public static T Deserialize(string xml) { - using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml))) - return Deserialize(stream); - } - - /// - /// 反序列化XML为对象 - /// - /// - /// XML - /// - public static T Deserialize(Stream xml) { - return (T)Serializer.Instance.Deserialize(xml); - } - - private static class Serializer { - public static readonly System.Xml.Serialization.XmlSerializer Instance = new System.Xml.Serialization.XmlSerializer(typeof(T)); - } - } -} diff --git a/ExtremeDumper.Common.props b/ExtremeDumper.Common.props new file mode 100644 index 0000000..bc57b75 --- /dev/null +++ b/ExtremeDumper.Common.props @@ -0,0 +1,17 @@ + + + ExtremeDumper + 3.0.0.0 + Copyright © 2018-2020 Wwh + .NET Assemblies Dumper + ..\ExtremeDumper\Images\ExtremeDumper.ico + + + net45 + true + 7.3 + WinExe + ..\bin\$(Configuration) + false + + diff --git a/ExtremeDumper.sln b/ExtremeDumper.sln index 0c11751..49e74ed 100644 --- a/ExtremeDumper.sln +++ b/ExtremeDumper.sln @@ -5,16 +5,6 @@ VisualStudioVersion = 16.0.29006.145 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtremeDumper", "ExtremeDumper\ExtremeDumper.csproj", "{BA1D5A3E-330E-4D82-BFF5-58B6CF52726C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Diagnostics.Runtime.v2", "Libraries\clrmd\src\Microsoft.Diagnostics.Runtime\v2\Microsoft.Diagnostics.Runtime.v2.csproj", "{935D33C5-62F1-40FE-8DB0-46B6E01342FB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtremeDumper.AntiAntiDump", "ExtremeDumper.AntiAntiDump\ExtremeDumper.AntiAntiDump.csproj", "{DFFAB16F-40BE-46B2-AA4A-0FD49C1CCCAA}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dnlib", "Libraries\dnlib\src\dnlib.csproj", "{104CAC47-92E9-4634-A70E-17B3E697B1D1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetadataLocator", "Libraries\MetadataLocator\MetadataLocator\MetadataLocator.csproj", "{AED69D77-8C7B-41BA-9967-AC9B522430F9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{B6C797F4-3545-48E4-AC52-6551B6CF4EEA}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtremeDumper-x86", "ExtremeDumper-x86\ExtremeDumper-x86.csproj", "{F4ED1869-89DC-4A43-A2D7-0766533EB2BA}" EndProject Global @@ -27,22 +17,6 @@ Global {BA1D5A3E-330E-4D82-BFF5-58B6CF52726C}.Debug|Any CPU.Build.0 = Debug|Any CPU {BA1D5A3E-330E-4D82-BFF5-58B6CF52726C}.Release|Any CPU.ActiveCfg = Release|Any CPU {BA1D5A3E-330E-4D82-BFF5-58B6CF52726C}.Release|Any CPU.Build.0 = Release|Any CPU - {935D33C5-62F1-40FE-8DB0-46B6E01342FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {935D33C5-62F1-40FE-8DB0-46B6E01342FB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {935D33C5-62F1-40FE-8DB0-46B6E01342FB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {935D33C5-62F1-40FE-8DB0-46B6E01342FB}.Release|Any CPU.Build.0 = Release|Any CPU - {DFFAB16F-40BE-46B2-AA4A-0FD49C1CCCAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DFFAB16F-40BE-46B2-AA4A-0FD49C1CCCAA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DFFAB16F-40BE-46B2-AA4A-0FD49C1CCCAA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DFFAB16F-40BE-46B2-AA4A-0FD49C1CCCAA}.Release|Any CPU.Build.0 = Release|Any CPU - {104CAC47-92E9-4634-A70E-17B3E697B1D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {104CAC47-92E9-4634-A70E-17B3E697B1D1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {104CAC47-92E9-4634-A70E-17B3E697B1D1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {104CAC47-92E9-4634-A70E-17B3E697B1D1}.Release|Any CPU.Build.0 = Release|Any CPU - {AED69D77-8C7B-41BA-9967-AC9B522430F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AED69D77-8C7B-41BA-9967-AC9B522430F9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AED69D77-8C7B-41BA-9967-AC9B522430F9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AED69D77-8C7B-41BA-9967-AC9B522430F9}.Release|Any CPU.Build.0 = Release|Any CPU {F4ED1869-89DC-4A43-A2D7-0766533EB2BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F4ED1869-89DC-4A43-A2D7-0766533EB2BA}.Debug|Any CPU.Build.0 = Debug|Any CPU {F4ED1869-89DC-4A43-A2D7-0766533EB2BA}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -51,11 +25,6 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {935D33C5-62F1-40FE-8DB0-46B6E01342FB} = {B6C797F4-3545-48E4-AC52-6551B6CF4EEA} - {104CAC47-92E9-4634-A70E-17B3E697B1D1} = {B6C797F4-3545-48E4-AC52-6551B6CF4EEA} - {AED69D77-8C7B-41BA-9967-AC9B522430F9} = {B6C797F4-3545-48E4-AC52-6551B6CF4EEA} - EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4ED7F5D0-D7EC-491E-86FD-0215F210ADAD} EndGlobalSection diff --git a/ExtremeDumper/Dumper/AntiAntiDumper.cs b/ExtremeDumper/Dumper/AntiAntiDumper.cs deleted file mode 100644 index 70f6b7c..0000000 --- a/ExtremeDumper/Dumper/AntiAntiDumper.cs +++ /dev/null @@ -1,311 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using dnlib.DotNet; -using dnlib.IO; -using dnlib.PE; -using ExtremeDumper.AntiAntiDump; -using ExtremeDumper.AntiAntiDump.Serialization; -using Microsoft.Diagnostics.Runtime; -using NativeSharp; -using ImageLayout = dnlib.PE.ImageLayout; - -namespace ExtremeDumper.Dumper { - internal sealed unsafe class AntiAntiDumper : IDumper { - #region .net structs - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct IMAGE_DATA_DIRECTORY { - public static readonly uint UnmanagedSize = (uint)sizeof(IMAGE_DATA_DIRECTORY); - - public uint VirtualAddress; - public uint Size; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct IMAGE_COR20_HEADER { - public static readonly uint UnmanagedSize = (uint)sizeof(IMAGE_COR20_HEADER); - - public uint cb; - public ushort MajorRuntimeVersion; - public ushort MinorRuntimeVersion; - public IMAGE_DATA_DIRECTORY MetaData; - public uint Flags; - public uint EntryPointTokenOrRVA; - public IMAGE_DATA_DIRECTORY Resources; - public IMAGE_DATA_DIRECTORY StrongNameSignature; - public IMAGE_DATA_DIRECTORY CodeManagerTable; - public IMAGE_DATA_DIRECTORY VTableFixups; - public IMAGE_DATA_DIRECTORY ExportAddressTableJumps; - public IMAGE_DATA_DIRECTORY ManagedNativeHeader; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct STORAGESIGNATURE { - /// - /// 大小不包括pVersion的长度 - /// - public static readonly uint UnmanagedSize = (uint)sizeof(STORAGESIGNATURE) - 1; - - public uint lSignature; - public ushort iMajorVer; - public ushort iMinorVer; - public uint iExtraData; - public uint iVersionString; - /// - /// 由于C#语法问题不能写pVersion[0],实际长度由 决定 - /// - public fixed byte pVersion[1]; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct STORAGEHEADER { - public static readonly uint UnmanagedSize = (uint)sizeof(STORAGEHEADER); - - public byte fFlags; - public byte pad; - public ushort iStreams; - } - #endregion - - private readonly NativeProcess _process; - - private AntiAntiDumper(uint processId) { - _process = NativeProcess.Open(processId); - } - - public static IDumper Create(uint processId) { - return new AntiAntiDumper(processId); - } - - public bool DumpModule(IntPtr moduleHandle, ImageLayout imageLayout, string filePath) { - try { - NativeModule module; - ClrModule dacModule; - InjectionClrVersion clrVersion; - InjectionOptions injectionOptions; - MetadataInfoService metadataInfoService; - MetadataInfo metadataInfo; - byte[] peImageData; - - module = _process.UnsafeGetModule((void*)moduleHandle); - dacModule = TryGetDacModule(module); - if (dacModule is null) - return false; - switch (dacModule.Runtime.ClrInfo.Version.Major) { - case 2: - clrVersion = InjectionClrVersion.V2; - break; - case 4: - clrVersion = InjectionClrVersion.V4; - break; - default: - return false; - } - // 判断要dump的模块的CLR版本 - injectionOptions = new InjectionOptions { - PortName = Guid.NewGuid().ToString(), - ObjectName = Guid.NewGuid().ToString() - }; - if (!_process.InjectManaged(typeof(MetadataInfoService).Assembly.Location, typeof(Injection).FullName, "Main", XmlSerializer.Serialize(injectionOptions), clrVersion, out int result) || result != 0) - return false; - metadataInfoService = (MetadataInfoService)Activator.GetObject(typeof(MetadataInfoService), $"Ipc://{injectionOptions.PortName}/{injectionOptions.ObjectName}"); - // 注入DLL,通过.NET Remoting获取MetadataInfoService实例 - metadataInfo = XmlSerializer.Deserialize(metadataInfoService.GetMetadataInfo(moduleHandle)); - if (!metadataInfo.PEInfo.IsValid) - return false; - imageLayout = (ImageLayout)metadataInfo.PEInfo.ImageLayout; - try { - peImageData = DumpModule(module, imageLayout, metadataInfo, null); - // 尝试不使用文件中的节头 - } - catch { - peImageData = DumpModule(module, imageLayout, metadataInfo, dacModule.FileName); - // 如果出错,使用文件中的节头 - } - File.WriteAllBytes(filePath, peImageData); - return true; - } - catch { - return false; - } - } - - private static byte[] DumpModule(NativeModule module, ImageLayout imageLayout, MetadataInfo metadataInfo, string imagePath) { - byte[] peImageData; - - peImageData = PEImageHelper.DirectCopy(module, imageLayout, !(imagePath is null), imagePath); - if (imageLayout == ImageLayout.File) - // 统一为内存格式,方便修复 - FileLayoutToMemoryLayout(ref peImageData, metadataInfo); - FixDotNetHeaders(peImageData, metadataInfo); - // 修复.NET头 - peImageData = PEImageHelper.ConvertImageLayout(peImageData, ImageLayout.Memory, ImageLayout.File); - // 转换回文件格式用于保存 - return peImageData; - } - - private static void FileLayoutToMemoryLayout(ref byte[] peImageData, MetadataInfo metadataInfo) { - peImageData = PEImageHelper.ConvertImageLayout(peImageData, ImageLayout.File, ImageLayout.Memory); - using (PEImage peHeader = new PEImage(peImageData, ImageLayout.File, false)) { - // 用于转换RVA与FOA,必须指定imageLayout参数为ImageLayout.File - DotNetPEInfo peInfo; - - if (!(metadataInfo.TableStream is null)) - metadataInfo.TableStream.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.TableStream.Rva); - if (!(metadataInfo.StringHeap is null)) - metadataInfo.StringHeap.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.StringHeap.Rva); - if (!(metadataInfo.UserStringHeap is null)) - metadataInfo.UserStringHeap.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.UserStringHeap.Rva); - if (!(metadataInfo.GuidHeap is null)) - metadataInfo.GuidHeap.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.GuidHeap.Rva); - if (!(metadataInfo.BlobHeap is null)) - metadataInfo.BlobHeap.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.BlobHeap.Rva); - peInfo = metadataInfo.PEInfo; - peInfo.ImageLayout = MetadataLocator.ImageLayout.Memory; - peInfo.Cor20HeaderRva = (uint)peHeader.ToRVA((FileOffset)peInfo.Cor20HeaderRva); - peInfo.MetadataRva = (uint)peHeader.ToRVA((FileOffset)peInfo.MetadataRva); - } - } - - private static void FixDotNetHeaders(byte[] peImageData, MetadataInfo metadataInfo) { - DotNetPEInfo peInfo; - - peInfo = metadataInfo.PEInfo; - fixed (byte* p = peImageData) { - IMAGE_DATA_DIRECTORY* pNETDirectory; - IMAGE_COR20_HEADER* pCor20Header; - STORAGESIGNATURE* pStorageSignature; - byte[] versionString; - STORAGEHEADER* pStorageHeader; - uint* pStreamHeader; - - using (PEImage peHeader = new PEImage(peImageData, false)) - pNETDirectory = (IMAGE_DATA_DIRECTORY*)(p + (uint)peHeader.ImageNTHeaders.OptionalHeader.DataDirectories[14].StartOffset); - pNETDirectory->VirtualAddress = peInfo.Cor20HeaderRva; - pNETDirectory->Size = IMAGE_COR20_HEADER.UnmanagedSize; - // Set Data Directories - pCor20Header = (IMAGE_COR20_HEADER*)(p + peInfo.Cor20HeaderRva); - pCor20Header->cb = IMAGE_COR20_HEADER.UnmanagedSize; - pCor20Header->MajorRuntimeVersion = 0x2; - pCor20Header->MinorRuntimeVersion = 0x5; - pCor20Header->MetaData.VirtualAddress = peInfo.MetadataRva; - pCor20Header->MetaData.Size = peInfo.MetadataSize; - // Set .NET Directory - pStorageSignature = (STORAGESIGNATURE*)(p + peInfo.MetadataRva); - pStorageSignature->lSignature = 0x424A5342; - pStorageSignature->iMajorVer = 0x1; - pStorageSignature->iMinorVer = 0x1; - pStorageSignature->iExtraData = 0x0; - pStorageSignature->iVersionString = 0xC; - versionString = Encoding.ASCII.GetBytes("v4.0.30319"); - for (int i = 0; i < versionString.Length; i++) - pStorageSignature->pVersion[i] = versionString[i]; - // versionString仅仅占位用,程序集具体运行时版本用dnlib获取 - // Set StorageSignature - pStorageHeader = (STORAGEHEADER*)((byte*)pStorageSignature + STORAGESIGNATURE.UnmanagedSize + pStorageSignature->iVersionString); - pStorageHeader->fFlags = 0x0; - pStorageHeader->pad = 0x0; - pStorageHeader->iStreams = 0x5; - // Set StorageHeader - pStreamHeader = (uint*)((byte*)pStorageHeader + STORAGEHEADER.UnmanagedSize); - if (!(metadataInfo.TableStream is null)) { - *pStreamHeader = metadataInfo.TableStream.Rva; - *pStreamHeader -= peInfo.MetadataRva; - pStreamHeader++; - *pStreamHeader = metadataInfo.TableStream.Length; - pStreamHeader++; - *pStreamHeader = 0x00007E23; - // #~ 暂时不支持#-表流的程序集 - pStreamHeader++; - } - if (!(metadataInfo.StringHeap is null)) { - *pStreamHeader = metadataInfo.StringHeap.Rva; - *pStreamHeader -= peInfo.MetadataRva; - pStreamHeader++; - *pStreamHeader = metadataInfo.StringHeap.Length; - pStreamHeader++; - *pStreamHeader = 0x72745323; - pStreamHeader++; - *pStreamHeader = 0x73676E69; - pStreamHeader++; - *pStreamHeader = 0x00000000; - pStreamHeader++; - // #Strings - } - if (!(metadataInfo.UserStringHeap is null)) { - *pStreamHeader = metadataInfo.UserStringHeap.Rva; - *pStreamHeader -= peInfo.MetadataRva; - pStreamHeader++; - *pStreamHeader = metadataInfo.UserStringHeap.Length; - pStreamHeader++; - *pStreamHeader = 0x00535523; - pStreamHeader++; - // #US - } - if (!(metadataInfo.GuidHeap is null)) { - *pStreamHeader = metadataInfo.GuidHeap.Rva; - *pStreamHeader -= peInfo.MetadataRva; - pStreamHeader++; - *pStreamHeader = metadataInfo.GuidHeap.Length; - pStreamHeader++; - *pStreamHeader = 0x49554723; - pStreamHeader++; - *pStreamHeader = 0x00000044; - pStreamHeader++; - // #GUID - } - if (!(metadataInfo.BlobHeap is null)) { - *pStreamHeader = metadataInfo.BlobHeap.Rva; - *pStreamHeader -= peInfo.MetadataRva; - pStreamHeader++; - *pStreamHeader = metadataInfo.BlobHeap.Length; - pStreamHeader++; - *pStreamHeader = 0x6F6C4223; - pStreamHeader++; - *pStreamHeader = 0x00000062; - pStreamHeader++; - // #GUID - } - } - using (ModuleDefMD moduleDef = ModuleDefMD.Load(new PEImage(peImageData, ImageLayout.Memory, false))) - fixed (byte* p = peImageData) { - STORAGESIGNATURE* pStorageSignature; - byte[] versionString; - - pStorageSignature = (STORAGESIGNATURE*)(p + peInfo.MetadataRva); - switch (moduleDef.CorLibTypes.AssemblyRef.Version.Major) { - case 2: - versionString = Encoding.ASCII.GetBytes("v2.0.50727"); - break; - case 4: - versionString = Encoding.ASCII.GetBytes("v4.0.30319"); - break; - default: - throw new NotSupportedException(); - } - for (int i = 0; i < versionString.Length; i++) - pStorageSignature->pVersion[i] = versionString[i]; - } - } - - private static ClrModule TryGetDacModule(NativeModule module) { - try { - using (DataTarget dataTarget = DataTarget.AttachToProcess((int)module.Process.Id, 3000, AttachFlag.Passive)) - return dataTarget.ClrVersions.SelectMany(t => t.CreateRuntime().Modules).First(t => (void*)t.ImageBase == module.Handle); - } - catch { - return null; - } - } - - public int DumpProcess(string directoryPath) { - throw new NotSupportedException(); - } - - public void Dispose() { - _process.Dispose(); - } - } -} diff --git a/ExtremeDumper/Dumper/DumperFactory.cs b/ExtremeDumper/Dumper/DumperFactory.cs deleted file mode 100644 index 1c8e477..0000000 --- a/ExtremeDumper/Dumper/DumperFactory.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace ExtremeDumper.Dumper { - public enum DumperType { - Normal, - - AntiAntiDump - } - - public static class DumperFactory { - public static IDumper GetDumper(uint processId, DumperType dumperType) { - switch (dumperType) { - case DumperType.Normal: - return NormalDumper.Create(processId); - case DumperType.AntiAntiDump: - return AntiAntiDumper.Create(processId); - default: - throw new ArgumentOutOfRangeException(nameof(dumperType)); - } - } - } -} diff --git a/ExtremeDumper/Dumper/NormalDumper.cs b/ExtremeDumper/Dumper/NormalDumper.cs deleted file mode 100644 index c7ba554..0000000 --- a/ExtremeDumper/Dumper/NormalDumper.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; -using dnlib.DotNet; -using dnlib.PE; -using NativeSharp; - -namespace ExtremeDumper.Dumper { - internal sealed unsafe class NormalDumper : IDumper { - private static readonly char[] InvalidFileNameChars = Path.GetInvalidFileNameChars(); - - private readonly NativeProcess _process; - - private NormalDumper(uint processId) { - _process = NativeProcess.Open(processId, ProcessAccess.MemoryRead | ProcessAccess.QueryInformation); - } - - public static IDumper Create(uint processId) { - return new NormalDumper(processId); - } - - public bool DumpModule(IntPtr moduleHandle, ImageLayout imageLayout, string filePath) { - try { - byte[] peImageData; - - peImageData = PEImageHelper.DirectCopy(_process.UnsafeGetModule((void*)moduleHandle), imageLayout); - peImageData = PEImageHelper.ConvertImageLayout(peImageData, imageLayout, ImageLayout.File); - File.WriteAllBytes(filePath, peImageData); - return true; - } - catch { - return false; - } - } - - public int DumpProcess(string directoryPath) { - int count; - - count = 0; - foreach (PageInfo pageInfo in _process.EnumeratePageInfos()) { - ushort magic; - byte[] peHeaderData; - NativeModule module; - ImageLayout imageLayout; - byte[] peImageData; - string fileName; - string filePath; - - if ((ulong)pageInfo.Size > int.MaxValue) - continue; - if (!_process.TryReadUInt16(pageInfo.Address, out magic)) - continue; - if (magic != 0x5A4D) - // MZ - continue; - peHeaderData = new byte[(uint)pageInfo.Size]; - if (!_process.TryReadBytes(pageInfo.Address, peHeaderData)) - continue; - module = _process.UnsafeGetModule(pageInfo.Address); - imageLayout = GetProbableImageLayout(peHeaderData); - peImageData = DumpDotNetModule(module, imageLayout, out fileName); - if (peImageData is null) { - // 也许判断有误,尝试一下另一种格式 - if (imageLayout == ImageLayout.Memory) - peImageData = DumpDotNetModule(module, ImageLayout.File, out fileName); - else - peImageData = DumpDotNetModule(module, ImageLayout.Memory, out fileName); - } - if (peImageData is null) - continue; - filePath = Path.Combine(directoryPath, EnsureNoRepeatFileName(directoryPath, EnsureValidFileName(fileName))); - File.WriteAllBytes(filePath, peImageData); - count++; - } - return count; - } - - private static ImageLayout GetProbableImageLayout(byte[] firstPageData) { - try { - uint imageSize; - ImageLayout imageLayout; - - imageSize = PEImageHelper.GetImageSize(firstPageData, ImageLayout.File); - // 获取文件格式大小 - imageLayout = imageSize >= (uint)firstPageData.Length ? ImageLayout.Memory : ImageLayout.File; - // 如果文件格式大小大于页面大小,说明在内存中是内存格式的,反之为文件格式 - // 这种判断不准确,如果文件文件大小小于最小页面大小,判断会出错 - return imageLayout; - } - catch { - return ImageLayout.Memory; - } - } - - private static byte[] DumpDotNetModule(NativeModule module, ImageLayout imageLayout, out string fileName) { - try { - byte[] peImageData; - bool isDotNet; - - peImageData = PEImageHelper.DirectCopy(module, imageLayout); - peImageData = PEImageHelper.ConvertImageLayout(peImageData, imageLayout, ImageLayout.File); - using (PEImage peImage = new PEImage(peImageData, true)) { - // 确保为有效PE文件 - fileName = peImage.GetOriginalFilename() ?? ((IntPtr)module.Handle).ToString((ulong)module.Handle > uint.MaxValue ? "X16" : "X8"); - isDotNet = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14].VirtualAddress != 0; - if (isDotNet) - try { - using (ModuleDefMD moduleDef = ModuleDefMD.Load(peImage)) { - } - // 再次验证是否为.NET程序集 - } - catch { - isDotNet = false; - } - } - return isDotNet ? peImageData : null; - } - catch { - fileName = default; - return null; - } - } - - private static string EnsureValidFileName(string fileName) { - if (string.IsNullOrEmpty(fileName)) - return string.Empty; - - StringBuilder newFileName; - - newFileName = new StringBuilder(fileName.Length); - foreach (char chr in fileName) - if (!InvalidFileNameChars.Contains(chr)) - newFileName.Append(chr); - return newFileName.ToString(); - } - - private static string EnsureNoRepeatFileName(string directoryPath, string fileName) { - string filePath; - int count; - string fileNameWithoutExtension; - string extension; - - count = 1; - fileNameWithoutExtension = null; - extension = null; - while (File.Exists(filePath = Path.Combine(directoryPath, fileName))) { - if (fileNameWithoutExtension is null) { - fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); - extension = Path.GetExtension(fileName); - } - count++; - fileName = $"{fileNameWithoutExtension} ({count}){extension}"; - } - return filePath; - } - - public void Dispose() { - _process.Dispose(); - } - } -} diff --git a/ExtremeDumper/Dumper/PEImageHelper.cs b/ExtremeDumper/Dumper/PEImageHelper.cs deleted file mode 100644 index e29d6c3..0000000 --- a/ExtremeDumper/Dumper/PEImageHelper.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using dnlib.IO; -using dnlib.PE; -using NativeSharp; - -namespace ExtremeDumper.Dumper { - internal static unsafe class PEImageHelper { - /// - /// 直接从内存中复制模块,不执行格式转换操作 - /// - /// 模块 - /// 模块在内存中的格式 - /// - public static byte[] DirectCopy(NativeModule module, ImageLayout imageLayout) { - return DirectCopy(module, imageLayout, false, null); - } - - /// - /// 直接从内存中复制模块,不执行格式转换操作 - /// - /// 模块 - /// 模块在内存中的格式 - /// 是否使用文件中的节头 - /// 如果无法正常获取模块路径,可提供备选模块路径 - /// - public static byte[] DirectCopy(NativeModule module, ImageLayout imageLayout, bool useSectionHeadersInFile, string alternativeToImagePath) { - if (module is null) - throw new ArgumentNullException(nameof(module)); - if (useSectionHeadersInFile) - if (string.IsNullOrEmpty(alternativeToImagePath)) - alternativeToImagePath = null; - else { - if (!File.Exists(alternativeToImagePath)) - throw new FileNotFoundException(nameof(alternativeToImagePath)); - } - - NativeProcess process; - PageInfo firstPageInfo; - string imagePath; - byte[] peImageData; - uint imageSize; - - process = module.Process; - process.QuickDemand(ProcessAccess.MemoryRead | ProcessAccess.QueryInformation); - firstPageInfo = process.EnumeratePageInfos(module.Handle, module.Handle).First(); - if (useSectionHeadersInFile) { - imagePath = module.ImagePath; - if (string.IsNullOrEmpty(imagePath) || !File.Exists(imagePath)) - imagePath = alternativeToImagePath; - } - else - imagePath = default; - // 获取模块路径(如果需要使用文件中的节头) - if (useSectionHeadersInFile) - imageSize = GetImageSize(File.ReadAllBytes(imagePath), imageLayout); - else { - byte[] peHeaderData; - - peHeaderData = new byte[(uint)firstPageInfo.Size]; - process.ReadBytes(module.Handle, peHeaderData); - imageSize = GetImageSize(peHeaderData, imageLayout); - } - // 获取模块在内存中的大小 - peImageData = new byte[imageSize]; - switch (imageLayout) { - case ImageLayout.File: - if (!process.TryReadBytes(firstPageInfo.Address, peImageData, 0, imageSize)) - throw new InvalidOperationException(); - break; - case ImageLayout.Memory: - foreach (PageInfo pageInfo in process.EnumeratePageInfos(module.Handle, (byte*)module.Handle + imageSize)) { - uint offset; - - offset = (uint)((ulong)pageInfo.Address - (ulong)module.Handle); - process.TryReadBytes(pageInfo.Address, peImageData, offset, (uint)pageInfo.Size); - } - break; - default: - throw new NotSupportedException(); - } - // 转储 - if (useSectionHeadersInFile) - using (PEImage peHeader = new PEImage(imagePath, false)) { - int startOffset; - int endOffset; - byte[] sectionHeadersData; - - startOffset = (int)peHeader.ImageSectionHeaders.First().StartOffset; - endOffset = (int)peHeader.ImageSectionHeaders.Last().EndOffset; - sectionHeadersData = peHeader.CreateReader((FileOffset)startOffset).ReadBytes(endOffset - startOffset); - Buffer.BlockCopy(sectionHeadersData, 0, peImageData, startOffset, endOffset - startOffset); - } - // 替换节头(如果需要使用文件中的节头) - return peImageData; - } - - public static byte[] ConvertImageLayout(byte[] peImageData, ImageLayout fromImageLayout, ImageLayout toImageLayout) { - switch (fromImageLayout) { - case ImageLayout.File: - case ImageLayout.Memory: - break; - default: - throw new ArgumentOutOfRangeException(nameof(fromImageLayout)); - } - switch (toImageLayout) { - case ImageLayout.File: - case ImageLayout.Memory: - break; - default: - throw new ArgumentOutOfRangeException(nameof(toImageLayout)); - } - if (peImageData is null) - throw new ArgumentNullException(nameof(peImageData)); - - byte[] newPEImageData; - - if (fromImageLayout == toImageLayout) - return peImageData; - newPEImageData = new byte[GetImageSize(peImageData, toImageLayout)]; - using (PEImage peHeader = new PEImage(peImageData, false)) { - Buffer.BlockCopy(peImageData, 0, newPEImageData, 0, (int)peHeader.ImageSectionHeaders.Last().EndOffset); - // 复制PE头 - foreach (ImageSectionHeader sectionHeader in peHeader.ImageSectionHeaders) - switch (toImageLayout) { - case ImageLayout.File: - // ImageLayout.Memory -> ImageLayout.File - Buffer.BlockCopy(peImageData, (int)sectionHeader.VirtualAddress, newPEImageData, (int)sectionHeader.PointerToRawData, (int)sectionHeader.SizeOfRawData); - break; - case ImageLayout.Memory: - // ImageLayout.File -> ImageLayout.Memory - Buffer.BlockCopy(peImageData, (int)sectionHeader.PointerToRawData, newPEImageData, (int)sectionHeader.VirtualAddress, (int)sectionHeader.SizeOfRawData); - break; - default: - throw new NotSupportedException(); - } - } - return newPEImageData; - } - - public static uint GetImageSize(byte[] peHeaderData, ImageLayout imageLayout) { - if (peHeaderData is null) - throw new ArgumentNullException(nameof(peHeaderData)); - - using (PEImage peHeader = new PEImage(peHeaderData, false)) { - // PEImage构造器中的imageLayout参数无关紧要,因为只需要解析PEHeader - ImageSectionHeader lastSectionHeader; - uint alignment; - uint imageSize; - - lastSectionHeader = peHeader.ImageSectionHeaders.Last(); - switch (imageLayout) { - case ImageLayout.File: - alignment = peHeader.ImageNTHeaders.OptionalHeader.FileAlignment; - imageSize = lastSectionHeader.PointerToRawData + lastSectionHeader.SizeOfRawData; - break; - case ImageLayout.Memory: - alignment = peHeader.ImageNTHeaders.OptionalHeader.SectionAlignment; - imageSize = (uint)lastSectionHeader.VirtualAddress + lastSectionHeader.VirtualSize; - break; - default: - throw new NotSupportedException(); - } - if (imageSize % alignment != 0) - imageSize = imageSize - (imageSize % alignment) + alignment; - return imageSize; - } - } - } -} diff --git a/ExtremeDumper/Dumping/DumperFactory.cs b/ExtremeDumper/Dumping/DumperFactory.cs new file mode 100644 index 0000000..de2d6dd --- /dev/null +++ b/ExtremeDumper/Dumping/DumperFactory.cs @@ -0,0 +1,16 @@ +using System; + +namespace ExtremeDumper.Dumping { + public enum DumperType { + Normal + } + + public static class DumperFactory { + public static IDumper GetDumper(uint processId, DumperType dumperType) { + switch (dumperType) { + case DumperType.Normal: return NormalDumper.Create(processId); + default: throw new ArgumentOutOfRangeException(nameof(dumperType)); + } + } + } +} diff --git a/ExtremeDumper/Dumper/Extensions.cs b/ExtremeDumper/Dumping/Extensions.cs similarity index 87% rename from ExtremeDumper/Dumper/Extensions.cs rename to ExtremeDumper/Dumping/Extensions.cs index 6ff7e11..eeedb3a 100644 --- a/ExtremeDumper/Dumper/Extensions.cs +++ b/ExtremeDumper/Dumping/Extensions.cs @@ -3,19 +3,16 @@ using dnlib.PE; using dnlib.W32Resources; -namespace ExtremeDumper.Dumper { +namespace ExtremeDumper.Dumping { internal static unsafe class Extensions { public static string GetOriginalFilename(this IPEImage peImage) { if (peImage is null) throw new ArgumentNullException(nameof(peImage)); - ResourceData resourceData; - byte[] data; - - resourceData = peImage.Win32Resources.Find(new ResourceName(16), new ResourceName(1))?.Data?.FirstOrDefault(); + var resourceData = peImage.Win32Resources?.Find(new ResourceName(16), new ResourceName(1))?.Data?.FirstOrDefault(); if (resourceData is null) return null; - data = resourceData.CreateReader().ReadRemainingBytes(); + byte[] data = resourceData.CreateReader().ReadRemainingBytes(); fixed (byte* p = data) return new FileVersionInfo(p, data.Length).OriginalFilename; } diff --git a/ExtremeDumper/Dumper/IDumper.cs b/ExtremeDumper/Dumping/IDumper.cs similarity index 95% rename from ExtremeDumper/Dumper/IDumper.cs rename to ExtremeDumper/Dumping/IDumper.cs index 16871e6..30fa0c2 100644 --- a/ExtremeDumper/Dumper/IDumper.cs +++ b/ExtremeDumper/Dumping/IDumper.cs @@ -1,7 +1,7 @@ using System; using dnlib.PE; -namespace ExtremeDumper.Dumper { +namespace ExtremeDumper.Dumping { /// /// 转储器的接口类 /// diff --git a/ExtremeDumper/Dumping/NormalDumper.cs b/ExtremeDumper/Dumping/NormalDumper.cs new file mode 100644 index 0000000..28685f5 --- /dev/null +++ b/ExtremeDumper/Dumping/NormalDumper.cs @@ -0,0 +1,162 @@ +using System; +using System.IO; +using System.Linq; +using System.Runtime.ExceptionServices; +using System.Text; +using dnlib.DotNet; +using dnlib.PE; +using NativeSharp; + +namespace ExtremeDumper.Dumping { + internal sealed unsafe class NormalDumper : IDumper { + private static readonly char[] InvalidFileNameChars = Path.GetInvalidFileNameChars(); + + private readonly NativeProcess _process; + + private NormalDumper(uint processId) { + _process = NativeProcess.Open(processId, ProcessAccess.MemoryRead | ProcessAccess.QueryInformation); + } + + public static IDumper Create(uint processId) { + return new NormalDumper(processId); + } + + [HandleProcessCorruptedStateExceptions] + public bool DumpModule(IntPtr moduleHandle, ImageLayout imageLayout, string filePath) { + try { + byte[] peImage = PEImageDumper.Dump(_process, (void*)moduleHandle, ref imageLayout); + peImage = PEImageDumper.ConvertImageLayout(peImage, imageLayout, ImageLayout.File); + File.WriteAllBytes(filePath, peImage); + return true; + } + catch { + return false; + } + } + + public int DumpProcess(string directoryPath) { + int count = 0; + foreach (var pageInfo in _process.EnumeratePageInfos()) { + if ((ulong)pageInfo.Size > int.MaxValue) + continue; + byte[] page = new byte[(int)pageInfo.Size]; + if (!_process.TryReadBytes(pageInfo.Address, page)) + continue; + + for (int i = 0; i < page.Length; i++) { + fixed (byte* p = page) { + if (!MaybePEImage(p + i)) + continue; + } + + var imageLayout = i == 0 ? GetProbableImageLayout(page) : ImageLayout.File; + byte[] peImage = DumpDotNetModule(_process, (byte*)pageInfo.Address + i, imageLayout, out string fileName); + if (peImage is null && i == 0) { + // 也许判断有误,尝试一下另一种格式 + if (imageLayout == ImageLayout.Memory) + peImage = DumpDotNetModule(_process, (byte*)pageInfo.Address + i, ImageLayout.File, out fileName); + else + peImage = DumpDotNetModule(_process, (byte*)pageInfo.Address + i, ImageLayout.Memory, out fileName); + } + if (peImage is null) + continue; + + string filePath = Path.Combine(directoryPath, EnsureNoRepeatFileName(directoryPath, EnsureValidFileName(fileName))); + File.WriteAllBytes(filePath, peImage); + count++; + } + } + return count; + } + + [HandleProcessCorruptedStateExceptions] + private static bool MaybePEImage(byte* p) { + try { + if (*(ushort*)p != 0x5A4D) + return false; + ushort ntHeadersOffset = *(ushort*)(p + 0x3C); + p += ntHeadersOffset; + return *(uint*)p == 0x00004550; + } + catch { + return false; + } + } + + [HandleProcessCorruptedStateExceptions] + private static ImageLayout GetProbableImageLayout(byte[] firstPage) { + try { + uint imageSize = PEImageDumper.GetImageSize(firstPage, ImageLayout.File); + // 获取文件格式大小 + var imageLayout = imageSize >= (uint)firstPage.Length ? ImageLayout.Memory : ImageLayout.File; + // 如果文件格式大小大于页面大小,说明在内存中是内存格式的,反之为文件格式 + // 这种判断不准确,如果文件文件大小小于最小页面大小,判断会出错 + return imageLayout; + } + catch { + return ImageLayout.Memory; + } + } + + [HandleProcessCorruptedStateExceptions] + private static byte[] DumpDotNetModule(NativeProcess process, void* address, ImageLayout imageLayout, out string fileName) { + try { + byte[] data = PEImageDumper.Dump(process, address, ref imageLayout); + data = PEImageDumper.ConvertImageLayout(data, imageLayout, ImageLayout.File); + bool isDotNet; + using (var peImage = new PEImage(data, true)) { + // 确保为有效PE文件 + fileName = peImage.GetOriginalFilename() ?? ((IntPtr)address).ToString((ulong)address > uint.MaxValue ? "X16" : "X8"); + isDotNet = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14].VirtualAddress != 0; + if (isDotNet) { + try { + using (var moduleDef = ModuleDefMD.Load(peImage)) { + } + // 再次验证是否为.NET程序集 + } + catch { + isDotNet = false; + } + } + } + return isDotNet ? data : null; + } + catch { + fileName = default; + return null; + } + } + + private static string EnsureValidFileName(string fileName) { + if (string.IsNullOrEmpty(fileName)) + return string.Empty; + + var newFileName = new StringBuilder(fileName.Length); + foreach (char chr in fileName) { + if (!InvalidFileNameChars.Contains(chr)) + newFileName.Append(chr); + } + return newFileName.ToString(); + } + + private static string EnsureNoRepeatFileName(string directoryPath, string fileName) { + int count = 1; + string fileNameWithoutExtension = null; + string extension = null; + string filePath; + while (File.Exists(filePath = Path.Combine(directoryPath, fileName))) { + if (fileNameWithoutExtension is null) { + fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); + extension = Path.GetExtension(fileName); + } + count++; + fileName = $"{fileNameWithoutExtension} ({count}){extension}"; + } + return filePath; + } + + public void Dispose() { + _process.Dispose(); + } + } +} diff --git a/ExtremeDumper/Dumping/PEImageDumper.cs b/ExtremeDumper/Dumping/PEImageDumper.cs new file mode 100644 index 0000000..b26d5bd --- /dev/null +++ b/ExtremeDumper/Dumping/PEImageDumper.cs @@ -0,0 +1,147 @@ +using System; +using System.Linq; +using dnlib.PE; +using NativeSharp; + +namespace ExtremeDumper.Dumping { + public static unsafe class PEImageDumper { + /// + /// 直接从内存中复制模块,不执行格式转换操作 + /// + /// + /// + /// + /// + public static byte[] Dump(uint processId, void* address, ref ImageLayout imageLayout) { + if (processId == 0) + throw new ArgumentNullException(nameof(processId)); + if (address == null) + throw new ArgumentNullException(nameof(address)); + + using (var process = NativeProcess.Open(processId)) + return Dump(process, address, ref imageLayout); + } + + /// + /// 直接从内存中复制模块,不执行格式转换操作 + /// + /// + /// + /// + /// + public static byte[] Dump(NativeProcess process, void* address, ref ImageLayout imageLayout) { + var firstPageInfo = process.EnumeratePageInfos(address, address).First(); + bool atPageHeader = address == firstPageInfo.Address; + if (!atPageHeader) + imageLayout = ImageLayout.File; + byte[] peHeader = new byte[atPageHeader ? (int)firstPageInfo.Size : (int)((byte*)firstPageInfo.Address + (uint)firstPageInfo.Size - (byte*)address)]; + process.ReadBytes(address, peHeader); + uint imageSize = GetImageSize(peHeader, imageLayout); + // 获取模块在内存中的大小 + + byte[] peImage = new byte[imageSize]; + switch (imageLayout) { + case ImageLayout.File: + if (!process.TryReadBytes(address, peImage, 0, imageSize)) + throw new InvalidOperationException(); + break; + case ImageLayout.Memory: + foreach (var pageInfo in process.EnumeratePageInfos(address, (byte*)address + imageSize)) { + uint offset = (uint)((ulong)pageInfo.Address - (ulong)address); + process.TryReadBytes(pageInfo.Address, peImage, offset, (uint)pageInfo.Size); + } + break; + default: + throw new NotSupportedException(); + } + // 转储 + + return peImage; + } + + /// + /// 转换模块布局 + /// + /// + /// + /// + /// + public static byte[] ConvertImageLayout(byte[] peImage, ImageLayout fromImageLayout, ImageLayout toImageLayout) { + switch (fromImageLayout) { + case ImageLayout.File: + case ImageLayout.Memory: + break; + default: + throw new ArgumentOutOfRangeException(nameof(fromImageLayout)); + } + switch (toImageLayout) { + case ImageLayout.File: + case ImageLayout.Memory: + break; + default: + throw new ArgumentOutOfRangeException(nameof(toImageLayout)); + } + if (peImage is null) + throw new ArgumentNullException(nameof(peImage)); + + if (fromImageLayout == toImageLayout) + return peImage; + byte[] newPEImageData = new byte[GetImageSize(peImage, toImageLayout)]; + using (var peHeader = new PEImage(peImage, false)) { + Buffer.BlockCopy(peImage, 0, newPEImageData, 0, (int)peHeader.ImageSectionHeaders.Last().EndOffset); + // 复制PE头 + foreach (var sectionHeader in peHeader.ImageSectionHeaders) { + switch (toImageLayout) { + case ImageLayout.File: + // ImageLayout.Memory -> ImageLayout.File + Buffer.BlockCopy(peImage, (int)sectionHeader.VirtualAddress, newPEImageData, (int)sectionHeader.PointerToRawData, (int)sectionHeader.SizeOfRawData); + break; + case ImageLayout.Memory: + // ImageLayout.File -> ImageLayout.Memory + Buffer.BlockCopy(peImage, (int)sectionHeader.PointerToRawData, newPEImageData, (int)sectionHeader.VirtualAddress, (int)sectionHeader.SizeOfRawData); + break; + default: + throw new NotSupportedException(); + } + } + } + return newPEImageData; + } + + /// + /// 获取模块大小 + /// + /// + /// + /// + public static uint GetImageSize(byte[] peHeader, ImageLayout imageLayout) { + if (peHeader is null) + throw new ArgumentNullException(nameof(peHeader)); + + using (var peImage = new PEImage(peHeader, false)) + return GetImageSize(peImage, imageLayout); + // PEImage构造器中的imageLayout参数无关紧要,因为只需要解析PEHeader + } + + public static uint GetImageSize(PEImage peHeader, ImageLayout imageLayout) { + var lastSectionHeader = peHeader.ImageSectionHeaders.Last(); + uint alignment; + uint imageSize; + switch (imageLayout) { + case ImageLayout.File: + alignment = peHeader.ImageNTHeaders.OptionalHeader.FileAlignment; + imageSize = lastSectionHeader.PointerToRawData + lastSectionHeader.SizeOfRawData; + break; + case ImageLayout.Memory: + alignment = peHeader.ImageNTHeaders.OptionalHeader.SectionAlignment; + imageSize = (uint)lastSectionHeader.VirtualAddress + lastSectionHeader.VirtualSize; + break; + default: + throw new NotSupportedException(); + } + if (imageSize % alignment != 0) + imageSize = imageSize - (imageSize % alignment) + alignment; + return imageSize; + } + } +} diff --git a/ExtremeDumper/ExtremeDumper.csproj b/ExtremeDumper/ExtremeDumper.csproj index 85d83a3..24e9f88 100644 --- a/ExtremeDumper/ExtremeDumper.csproj +++ b/ExtremeDumper/ExtremeDumper.csproj @@ -1,162 +1,25 @@ - - - - - Debug - AnyCPU - {BA1D5A3E-330E-4D82-BFF5-58B6CF52726C} - WinExe - ExtremeDumper - ExtremeDumper - v4.0 - 512 - - - Forms\Resources\Icon.ico - - - true - ..\bin\Debug\ - TRACE;DEBUG - true - IDE0001;IDE1006 - full - AnyCPU - 7.3 - prompt - - - ..\bin\Release\ - TRACE - true - true - IDE0001;IDE1006 - pdbonly - AnyCPU - 7.3 - prompt - - - - - - - - - - - - - - - Form - - - AboutForm.cs - - - - - Form - - - FunctionsForm.cs - - - Form - - - InjectingForm.cs - - - - - - Form - - - ModulesForm.cs - - - - Form - - - ProcessesForm.cs - - - True - True - Resources.resx - - - - - - AboutForm.cs - - - AboutForm.cs - - - FunctionsForm.cs - - - FunctionsForm.cs - - - InjectingForm.cs - - - InjectingForm.cs - - - ProcessesForm.cs - Designer - - - ProcessesForm.cs - Designer - - - ModulesForm.cs - - - ModulesForm.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - - - - - - - {dffab16f-40be-46b2-aa4a-0fd49c1cccaa} - ExtremeDumper.AntiAntiDump - - - {935d33c5-62f1-40fe-8db0-46b6e01342fb} - Microsoft.Diagnostics.Runtime.v2 - - - {104cac47-92e9-4634-a70e-17b3e697b1d1} - dnlib - - - {AED69D77-8C7B-41BA-9967-AC9B522430F9} - MetadataLocator - - - - - 3.0.0 - - - - \ No newline at end of file + + + true + + + + + + + + + + True + True + Resources.resx + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/ExtremeDumper/FodyWeavers.xml b/ExtremeDumper/FodyWeavers.xml new file mode 100644 index 0000000..073b6c8 --- /dev/null +++ b/ExtremeDumper/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + diff --git a/ExtremeDumper/FodyWeavers.xsd b/ExtremeDumper/FodyWeavers.xsd new file mode 100644 index 0000000..44a5374 --- /dev/null +++ b/ExtremeDumper/FodyWeavers.xsd @@ -0,0 +1,111 @@ + + + + + + + + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with line breaks. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with line breaks. + + + + + The order of preloaded assemblies, delimited with line breaks. + + + + + + This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. + + + + + Controls if .pdbs for reference assemblies are also embedded. + + + + + Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. + + + + + As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. + + + + + Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. + + + + + Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with |. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with |. + + + + + The order of preloaded assemblies, delimited with |. + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/ExtremeDumper/Forms/AboutForm.Designer.cs b/ExtremeDumper/Forms/AboutForm.Designer.cs deleted file mode 100644 index 0012611..0000000 --- a/ExtremeDumper/Forms/AboutForm.Designer.cs +++ /dev/null @@ -1,121 +0,0 @@ -namespace ExtremeDumper.Forms -{ - partial class AboutForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm)); - this.picIcon = new System.Windows.Forms.PictureBox(); - this.lblTextAuthor = new System.Windows.Forms.Label(); - this.lblTextProductName = new System.Windows.Forms.Label(); - this.lblAuthor = new System.Windows.Forms.Label(); - this.lblVersion = new System.Windows.Forms.Label(); - this.lblTextThanks = new System.Windows.Forms.Label(); - this.lblThanks = new System.Windows.Forms.Label(); - this.llblGithub = new System.Windows.Forms.LinkLabel(); - ((System.ComponentModel.ISupportInitialize)(this.picIcon)).BeginInit(); - this.SuspendLayout(); - // - // picIcon - // - resources.ApplyResources(this.picIcon, "picIcon"); - this.picIcon.Image = global::ExtremeDumper.Forms.Resources.Avatar; - this.picIcon.Name = "picIcon"; - this.picIcon.TabStop = false; - // - // lblTextAuthor - // - resources.ApplyResources(this.lblTextAuthor, "lblTextAuthor"); - this.lblTextAuthor.Name = "lblTextAuthor"; - // - // lblTextProductName - // - resources.ApplyResources(this.lblTextProductName, "lblTextProductName"); - this.lblTextProductName.Name = "lblTextProductName"; - // - // lblAuthor - // - resources.ApplyResources(this.lblAuthor, "lblAuthor"); - this.lblAuthor.Name = "lblAuthor"; - // - // lblVersion - // - resources.ApplyResources(this.lblVersion, "lblVersion"); - this.lblVersion.Name = "lblVersion"; - // - // lblTextThanks - // - resources.ApplyResources(this.lblTextThanks, "lblTextThanks"); - this.lblTextThanks.Name = "lblTextThanks"; - // - // lblThanks - // - resources.ApplyResources(this.lblThanks, "lblThanks"); - this.lblThanks.Name = "lblThanks"; - // - // llblGithub - // - resources.ApplyResources(this.llblGithub, "llblGithub"); - this.llblGithub.Name = "llblGithub"; - this.llblGithub.TabStop = true; - this.llblGithub.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lkbGithub_LinkClicked); - // - // AboutForm - // - resources.ApplyResources(this, "$this"); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.llblGithub); - this.Controls.Add(this.lblThanks); - this.Controls.Add(this.lblTextThanks); - this.Controls.Add(this.lblVersion); - this.Controls.Add(this.lblAuthor); - this.Controls.Add(this.lblTextProductName); - this.Controls.Add(this.lblTextAuthor); - this.Controls.Add(this.picIcon); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "AboutForm"; - this.ShowInTaskbar = false; - ((System.ComponentModel.ISupportInitialize)(this.picIcon)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.PictureBox picIcon; - private System.Windows.Forms.Label lblTextAuthor; - private System.Windows.Forms.Label lblTextProductName; - private System.Windows.Forms.Label lblAuthor; - private System.Windows.Forms.Label lblVersion; - private System.Windows.Forms.Label lblTextThanks; - private System.Windows.Forms.Label lblThanks; - private System.Windows.Forms.LinkLabel llblGithub; - } -} \ No newline at end of file diff --git a/ExtremeDumper/Forms/AboutForm.cs b/ExtremeDumper/Forms/AboutForm.cs deleted file mode 100644 index 534ea70..0000000 --- a/ExtremeDumper/Forms/AboutForm.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Diagnostics; -using System.Windows.Forms; - -namespace ExtremeDumper.Forms { - internal partial class AboutForm : Form { - public AboutForm() { - InitializeComponent(); - Text = $"About {Application.ProductName}"; - lblTextProductName.Text = Application.ProductName; - lblVersion.Text += $" {Application.ProductVersion}"; - } - - private void lkbGithub_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { - Process.Start("https://github.com/wwh1004/ExtremeDumper"); - } - } -} diff --git a/ExtremeDumper/Forms/AboutForm.resx b/ExtremeDumper/Forms/AboutForm.resx deleted file mode 100644 index 2fe8384..0000000 --- a/ExtremeDumper/Forms/AboutForm.resx +++ /dev/null @@ -1,393 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - 微软雅黑, 13pt - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - picIcon - - - 262, 126 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - lblTextThanks - - - 7 - - - AboutForm - - - 263, 213 - - - 178, 51 - - - 176, 34 - - - 0 - - - 262, 9 - - - 0 - - - $this - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - 1 - - - lblTextProductName - - - 263, 91 - - - True - - - 256, 256 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 1 - - - lblThanks - - - 2 - - - 5 - - - $this - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - CenterParent - - - True - - - 微软雅黑, 9pt - - - 4 - - - $this - - - lblAuthor - - - $this - - - 52, 17 - - - 46, 24 - - - 7, 17 - - - 263, 33 - - - 6 - - - $this - - - 3 - - - 46, 24 - - - $this - - - 0, 0 - - - lblTextAuthor - - - System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 61, 17 - - - lblVersion - - - llblGithub - - - 微软雅黑, 13pt - - - 7 - - - $this - - - 4 - - - 262, 67 - - - $this - - - 5 - - - 2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 452, 256 - - - True - - - 263, 150 - - - 3 - - - True - - - 6 - - - 微软雅黑, 13pt - - - 0, 24 - - - True - - - True - - - True - - - en-US - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - wwh1004 - - - Author - - - Thanks - - - 0xd4d - dnlib & dndbg -CodeCracker - MegaDumper -ClrMD - Microsoft - - - Version - - - https://github.com/wwh1004 -/ExtremeDumper - - \ No newline at end of file diff --git a/ExtremeDumper/Forms/AboutForm.zh-CN.resx b/ExtremeDumper/Forms/AboutForm.zh-CN.resx deleted file mode 100644 index bcf6a5e..0000000 --- a/ExtremeDumper/Forms/AboutForm.zh-CN.resx +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - wwh1004 - - - 作者 - - - 感谢 - - - 0xd4d - dnlib & dndbg -CodeCracker - MegaDumper -ClrMD - Microsoft - - - 版本号 - - - https://github.com/wwh1004 -/ExtremeDumper - - \ No newline at end of file diff --git a/ExtremeDumper/Forms/DumperTypeWrapper.cs b/ExtremeDumper/Forms/DumperTypeWrapper.cs index aac57e5..6c8ae03 100644 --- a/ExtremeDumper/Forms/DumperTypeWrapper.cs +++ b/ExtremeDumper/Forms/DumperTypeWrapper.cs @@ -1,4 +1,4 @@ -using ExtremeDumper.Dumper; +using ExtremeDumper.Dumping; namespace ExtremeDumper.Forms { internal class DumperTypeWrapper { diff --git a/ExtremeDumper/Forms/FunctionsForm.cs b/ExtremeDumper/Forms/FunctionsForm.cs index d309e05..545e603 100644 --- a/ExtremeDumper/Forms/FunctionsForm.cs +++ b/ExtremeDumper/Forms/FunctionsForm.cs @@ -40,10 +40,8 @@ private void mnuRefreshFunctionList_Click(object sender, EventArgs e) { private void RefreshFunctionList() { lvwFunctions.Items.Clear(); - foreach (ExportFunctionInfo functionInfo in _module.EnumerateFunctionInfos()) { - ListViewItem listViewItem; - - listViewItem = new ListViewItem(functionInfo.Name); + foreach (var functionInfo in _module.EnumerateFunctionInfos()) { + var listViewItem = new ListViewItem(functionInfo.Name); listViewItem.SubItems.Add("0x" + ((IntPtr)functionInfo.Address).ToString(Cache.Is64BitProcess ? "X16" : "X8")); listViewItem.SubItems.Add(functionInfo.Ordinal.ToString()); lvwFunctions.Items.Add(listViewItem); diff --git a/ExtremeDumper/Forms/InjectingForm.cs b/ExtremeDumper/Forms/InjectingForm.cs index d41c1c5..fdf2651 100644 --- a/ExtremeDumper/Forms/InjectingForm.cs +++ b/ExtremeDumper/Forms/InjectingForm.cs @@ -20,7 +20,7 @@ public InjectingForm(uint processId) { _process = NativeProcess.Open(processId); if (_process == NativeProcess.InvalidProcess) throw new InvalidOperationException(); - Text = $"Injector - {_process.Name}(ID={_process.Id.ToString()})"; + Text = $"Injector - {_process.Name}(ID={_process.Id})"; } #region Events @@ -54,31 +54,26 @@ private void tbArgument_TextChanged(object sender, EventArgs e) { } private void btInject_Click(object sender, EventArgs e) { - string typeName; - if (!File.Exists(_assemblyPath)) return; if (cmbEntryPoint.SelectedItem is null) return; - typeName = _entryPoint.FullName.Substring(_entryPoint.FullName.IndexOf(' ') + 1); + + string typeName = _entryPoint.FullName.Substring(_entryPoint.FullName.IndexOf(' ') + 1); typeName = typeName.Substring(0, typeName.IndexOf(':')); if (chkWaitReturn.Checked) { btInject.Enabled = false; Text += _resources.GetString("StrWaiting"); new Thread(() => { - int ret; - - if (_process.InjectManaged(_assemblyPath, typeName, _entryPoint.Name, _argument, out ret)) - Invoke((Action)(() => MessageBoxStub.Show($"{_resources.GetString("StrInjectSuccessfully")}\n{_resources.GetString("StrReturnValue")} {ret.ToString()}", MessageBoxIcon.Information))); + if (_process.InjectManaged(_assemblyPath, typeName, _entryPoint.Name, _argument, out int ret)) + Invoke((Action)(() => MessageBoxStub.Show($"{_resources.GetString("StrInjectSuccessfully")}\n{_resources.GetString("StrReturnValue")} {ret}", MessageBoxIcon.Information))); else Invoke((Action)(() => MessageBoxStub.Show(_resources.GetString("StrFailToInject"), MessageBoxIcon.Error))); Invoke((Action)(() => { btInject.Enabled = true; Text = Text.Substring(0, Text.Length - 6); })); - }) { - IsBackground = true - }.Start(); + }) { IsBackground = true }.Start(); } else { if (_process.InjectManaged(_assemblyPath, typeName, _entryPoint.Name, _argument)) @@ -90,8 +85,6 @@ private void btInject_Click(object sender, EventArgs e) { #endregion private void LoadAssembly() { - MethodSig methodSig; - try { _manifestModule = ModuleDefMD.Load(_assemblyPath); } @@ -101,19 +94,22 @@ private void LoadAssembly() { return; } cmbEntryPoint.Items.Clear(); - foreach (TypeDef typeDef in _manifestModule.GetTypes()) - foreach (MethodDef methodDef in typeDef.Methods) { + foreach (var typeDef in _manifestModule.GetTypes()) { + foreach (var methodDef in typeDef.Methods) { if (!methodDef.IsStatic) continue; if (methodDef.IsGetter || methodDef.IsSetter) continue; - methodSig = (MethodSig)methodDef.Signature; + + var methodSig = (MethodSig)methodDef.Signature; if (methodSig.Params.Count != 1 || methodSig.Params[0].FullName != "System.String") continue; if (methodSig.RetType.FullName != "System.Int32") continue; + cmbEntryPoint.Items.Add(methodDef); } + } if (cmbEntryPoint.Items.Count == 1) cmbEntryPoint.SelectedIndex = 0; } diff --git a/ExtremeDumper/Forms/ListViewExtesion.cs b/ExtremeDumper/Forms/ListViewExtesion.cs index 2ec15a0..70b1cc9 100644 --- a/ExtremeDumper/Forms/ListViewExtesion.cs +++ b/ExtremeDumper/Forms/ListViewExtesion.cs @@ -9,23 +9,20 @@ public static void AutoResizeColumns(this ListView listView, bool onlyLastColumn if (listView is null) throw new ArgumentNullException(nameof(listView)); - SCROLLBARINFO scrollBarInfo; - int sumWidths; - int[] minWidths; - - scrollBarInfo = SCROLLBARINFO.Default; + var scrollBarInfo = SCROLLBARINFO.Default; GetScrollBarInfo(listView.Handle, OBJID_VSCROLL, ref scrollBarInfo); - sumWidths = scrollBarInfo.dxyLineButton; + int sumWidths = scrollBarInfo.dxyLineButton; if (onlyLastColumn) { foreach (ColumnHeader columnHeader in listView.Columns) sumWidths += columnHeader.Width; listView.Columns[listView.Columns.Count - 1].Width += listView.Width - sumWidths - 4; } else { - minWidths = new int[listView.Columns.Count]; - using (Graphics g = listView.CreateGraphics()) + int[] minWidths = new int[listView.Columns.Count]; + using (var g = listView.CreateGraphics()) { for (int i = 0; i < minWidths.Length; i++) minWidths[i] = (int)g.MeasureString(listView.Columns[i].Text, listView.Font).Width + 10; + } listView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); for (int i = 0; i < minWidths.Length; i++) { if (listView.Columns[i].Width < minWidths[i]) diff --git a/ExtremeDumper/Forms/ListViewItemSorter.cs b/ExtremeDumper/Forms/ListViewItemSorter.cs index 27bb60d..69e5711 100644 --- a/ExtremeDumper/Forms/ListViewItemSorter.cs +++ b/ExtremeDumper/Forms/ListViewItemSorter.cs @@ -96,10 +96,7 @@ private int Compare(string x, string y) { } private int IntegerComparer(string x, string y, Parser parser) where T : IComparable { - T xParsed; - T yParsed; - - if (parser(x, NumberStyles.Integer, null, out xParsed) && parser(y, NumberStyles.Integer, null, out yParsed)) + if (parser(x, NumberStyles.Integer, null, out var xParsed) && parser(y, NumberStyles.Integer, null, out var yParsed)) return xParsed.CompareTo(yParsed); else if (parser(AllowHexLeading ? CleanHexLeading(x) : x, NumberStyles.HexNumber, null, out xParsed) && parser(AllowHexLeading ? CleanHexLeading(y) : y, NumberStyles.HexNumber, null, out yParsed)) return xParsed.CompareTo(yParsed); @@ -118,6 +115,7 @@ private static string CleanHexLeading(string value) { public void Dispose() { if (_isDisposed) return; + _listView.ColumnClick -= ListView_ColumnClick; _columnTypes = null; _isDisposed = true; diff --git a/ExtremeDumper/Forms/ModulesForm.cs b/ExtremeDumper/Forms/ModulesForm.cs index 6f43bf5..dc3745a 100644 --- a/ExtremeDumper/Forms/ModulesForm.cs +++ b/ExtremeDumper/Forms/ModulesForm.cs @@ -8,7 +8,7 @@ using System.Resources; using System.Text; using System.Windows.Forms; -using ExtremeDumper.Dumper; +using ExtremeDumper.Dumping; using Microsoft.Diagnostics.Runtime; using NativeSharp; using static ExtremeDumper.Forms.NativeMethods; @@ -29,16 +29,9 @@ public ModulesForm(uint processId, string processName, bool isDotNetProcess, Dum throw new InvalidOperationException(); _isDotNetProcess = isDotNetProcess; _dumperType = dumperType; - Text = $"{_resources.GetString("StrModules")} {processName}(ID={processId.ToString()})"; + Text = $"{_resources.GetString("StrModules")} {processName}(ID={processId})"; typeof(ListView).InvokeMember("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, lvwModules, new object[] { true }); - lvwModules.ListViewItemSorter = new ListViewItemSorter(lvwModules, new List { - TypeCode.String, - TypeCode.String, - TypeCode.String, - TypeCode.UInt64, - TypeCode.Int32, - TypeCode.String - }) { + lvwModules.ListViewItemSorter = new ListViewItemSorter(lvwModules, new List { TypeCode.String, TypeCode.String, TypeCode.String, TypeCode.UInt64, TypeCode.Int32, TypeCode.String }) { AllowHexLeading = true }; RefreshModuleList(); @@ -53,21 +46,17 @@ private void mnuDumpModule_Click(object sender, EventArgs e) { if (lvwModules.SelectedIndices.Count == 0) return; - string filePath; - string directoryPath; - IntPtr moduleHandle; - - filePath = PathInsertPostfix(EnsureValidFileName(lvwModules.GetFirstSelectedSubItem(chModuleName.Index).Text), ".dump"); - if (filePath.EndsWith(".dump", StringComparison.Ordinal)) - filePath += ".dll"; + string filePath = EnsureValidFileName(lvwModules.GetFirstSelectedSubItem(chModuleName.Index).Text); + if (filePath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && filePath.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) + filePath = PathInsertPostfix(filePath, ".dump"); + else + filePath += ".dump.dll"; sfdlgDumped.FileName = filePath; - directoryPath = lvwModules.GetFirstSelectedSubItem(chModulePath.Index).Text; - if (directoryPath != "InMemory" && Directory.Exists(directoryPath)) - sfdlgDumped.InitialDirectory = directoryPath; + sfdlgDumped.InitialDirectory = Path.GetDirectoryName(_process.GetMainModule().ImagePath); if (sfdlgDumped.ShowDialog() != DialogResult.OK) return; - moduleHandle = (IntPtr)ulong.Parse(lvwModules.GetFirstSelectedSubItem(chModuleHandle.Index).Text.Substring(2), NumberStyles.HexNumber, null); - DumpModule(moduleHandle, directoryPath == "InMemory" ? ImageLayout.File : ImageLayout.Memory, sfdlgDumped.FileName); + var moduleHandle = (IntPtr)ulong.Parse(lvwModules.GetFirstSelectedSubItem(chModuleHandle.Index).Text.Substring(2), NumberStyles.HexNumber, null); + DumpModule(moduleHandle, lvwModules.GetFirstSelectedSubItem(chModulePath.Index).Text == "InMemory" ? ImageLayout.File : ImageLayout.Memory, sfdlgDumped.FileName); } private void mnuRefreshModuleList_Click(object sender, EventArgs e) { @@ -78,11 +67,7 @@ private void mnuViewFunctions_Click(object sender, EventArgs e) { if (lvwModules.SelectedIndices.Count == 0) return; - FunctionsForm functionsForm; - -#pragma warning disable IDE0067 - functionsForm = new FunctionsForm(_process.UnsafeGetModule((void*)ulong.Parse(lvwModules.GetFirstSelectedSubItem(chModuleHandle.Index).Text.Substring(2), NumberStyles.HexNumber, null))); -#pragma warning restore IDE0067 + var functionsForm = new FunctionsForm(_process.UnsafeGetModule((void*)ulong.Parse(lvwModules.GetFirstSelectedSubItem(chModuleHandle.Index).Text.Substring(2), NumberStyles.HexNumber, null))); functionsForm.Show(); } @@ -94,24 +79,18 @@ private void mnuGotoLocation_Click(object sender, EventArgs e) { if (lvwModules.SelectedIndices.Count == 0) return; - string filePath; - - filePath = lvwModules.GetFirstSelectedSubItem(chModulePath.Index).Text; + string filePath = lvwModules.GetFirstSelectedSubItem(chModulePath.Index).Text; if (filePath != "InMemory") Process.Start("explorer.exe", @"/select, " + filePath); } #endregion private void RefreshModuleList() { - IntPtr snapshotHandle; - MODULEENTRY32 moduleEntry32; - ListViewItem listViewItem; - DataTarget dataTarget; - lvwModules.Items.Clear(); + ListViewItem listViewItem; if (!mnuOnlyDotNetModule.Checked) { - moduleEntry32 = MODULEENTRY32.Default; - snapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, _process.Id); + var moduleEntry32 = MODULEENTRY32.Default; + var snapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, _process.Id); if (snapshotHandle == INVALID_HANDLE_VALUE) return; if (!Module32First(snapshotHandle, ref moduleEntry32)) @@ -132,38 +111,41 @@ private void RefreshModuleList() { lvwModules.Items.Add(listViewItem); } while (Module32Next(snapshotHandle, ref moduleEntry32)); } - if (_isDotNetProcess) + if (_isDotNetProcess) { try { - using (dataTarget = DataTarget.AttachToProcess((int)_process.Id, 10000, AttachFlag.Passive)) - foreach (ClrInfo clrInfo in dataTarget.ClrVersions) - foreach (ClrAppDomain clrAppDomain in clrInfo.CreateRuntime().AppDomains) - foreach (ClrModule clrModule in clrAppDomain.Modules) { - try { - string moduleName; - - moduleName = clrModule.Name ?? "EmptyName"; - moduleName = clrModule.IsDynamic ? moduleName.Split(',')[0] : Path.GetFileName(moduleName); - listViewItem = new ListViewItem(moduleName); - // Name - listViewItem.SubItems.Add(clrAppDomain.Name); - // Domain Name - listViewItem.SubItems.Add(clrInfo.Version.ToString()); - // CLR Version - listViewItem.SubItems.Add("0x" + clrModule.ImageBase.ToString(Cache.Is64BitProcess ? "X16" : "X8")); - // BaseAddress - listViewItem.SubItems.Add("0x" + clrModule.Size.ToString("X8")); - // Size - listViewItem.SubItems.Add(clrModule.IsDynamic ? "InMemory" : clrModule.FileName); - // Path - listViewItem.BackColor = Cache.DotNetColor; - lvwModules.Items.Add(listViewItem); - } - catch { - } - } + using (var dataTarget = DataTarget.AttachToProcess((int)_process.Id, 1000, AttachFlag.Passive)) { + foreach (var clrModule in dataTarget.ClrVersions.Select(t => t.CreateRuntime()).SelectMany(t => t.AppDomains).SelectMany(t => t.Modules)) { + string name = clrModule.Name; + bool inMemory; + if (!string.IsNullOrEmpty(name)) { + inMemory = name.Contains(","); + } + else { + name = "EmptyName"; + inMemory = true; + } + string moduleName = !inMemory ? Path.GetFileName(name) : name.Split(',')[0]; + listViewItem = new ListViewItem(moduleName); + // Name + listViewItem.SubItems.Add(string.Join(", ", clrModule.AppDomains.Select(t => t.Name))); + // Domain Name + listViewItem.SubItems.Add(clrModule.Runtime.ClrInfo.Version.ToString()); + // CLR Version + listViewItem.SubItems.Add("0x" + clrModule.ImageBase.ToString(Cache.Is64BitProcess ? "X16" : "X8")); + // BaseAddress + listViewItem.SubItems.Add("0x" + clrModule.Size.ToString("X8")); + // Size + listViewItem.SubItems.Add(!inMemory ? name : "InMemory"); + // Path + listViewItem.BackColor = Cache.DotNetColor; + lvwModules.Items.Add(listViewItem); + } + } } catch { + MessageBoxStub.Show(_resources.GetString("StrFailToGetDotNetModules"), MessageBoxIcon.Error); } + } lvwModules.AutoResizeColumns(false); } @@ -171,19 +153,17 @@ private static string EnsureValidFileName(string fileName) { if (string.IsNullOrEmpty(fileName)) return string.Empty; - StringBuilder newFileName; - - newFileName = new StringBuilder(fileName.Length); - foreach (char chr in fileName) + var newFileName = new StringBuilder(fileName.Length); + foreach (char chr in fileName) { if (!InvalidFileNameChars.Contains(chr)) newFileName.Append(chr); + } return newFileName.ToString(); } private void DumpModule(IntPtr moduleHandle, ImageLayout imageLayout, string filePath) { bool result; - - using (IDumper dumper = DumperFactory.GetDumper(_process.Id, _dumperType.Value)) + using (var dumper = DumperFactory.GetDumper(_process.Id, _dumperType.Value)) result = dumper.DumpModule(moduleHandle, imageLayout, filePath); MessageBoxStub.Show(result ? $"{_resources.GetString("StrDumpModuleSuccessfully")}{Environment.NewLine}{filePath}" : _resources.GetString("StrFailToDumpModule"), result ? MessageBoxIcon.Information : MessageBoxIcon.Error); } diff --git a/ExtremeDumper/Forms/ModulesForm.resx b/ExtremeDumper/Forms/ModulesForm.resx index 2fd27b4..3d950a8 100644 --- a/ExtremeDumper/Forms/ModulesForm.resx +++ b/ExtremeDumper/Forms/ModulesForm.resx @@ -201,7 +201,7 @@ System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 微软雅黑, 9pt + Microsoft YaHei, 9pt 181, 6 @@ -354,4 +354,7 @@ Modules + + Fail to get .NET modules + \ No newline at end of file diff --git a/ExtremeDumper/Forms/ModulesForm.zh-CN.resx b/ExtremeDumper/Forms/ModulesForm.zh-CN.resx index 94acb41..fe8f27c 100644 --- a/ExtremeDumper/Forms/ModulesForm.zh-CN.resx +++ b/ExtremeDumper/Forms/ModulesForm.zh-CN.resx @@ -159,6 +159,9 @@ 失败! + + 获取.NET模块列表失败 + 模块列表 diff --git a/ExtremeDumper/Forms/ProcessesForm.Designer.cs b/ExtremeDumper/Forms/ProcessesForm.Designer.cs index ee2e333..14e3083 100644 --- a/ExtremeDumper/Forms/ProcessesForm.Designer.cs +++ b/ExtremeDumper/Forms/ProcessesForm.Designer.cs @@ -49,8 +49,6 @@ private void InitializeComponent() this.mnuDebugPrivilege = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.mnuDumperType = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuHelp = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem(); this.fbdlgDumped = new System.Windows.Forms.FolderBrowserDialog(); this.mnuProcessContext.SuspendLayout(); this.mnuMain.SuspendLayout(); @@ -66,6 +64,7 @@ private void InitializeComponent() this.chProcessPath}); this.lvwProcesses.ContextMenuStrip = this.mnuProcessContext; this.lvwProcesses.FullRowSelect = true; + this.lvwProcesses.HideSelection = false; this.lvwProcesses.Name = "lvwProcesses"; this.lvwProcesses.Sorting = System.Windows.Forms.SortOrder.Ascending; this.lvwProcesses.UseCompatibleStateImageBehavior = false; @@ -157,8 +156,7 @@ private void InitializeComponent() // resources.ApplyResources(this.mnuMain, "mnuMain"); this.mnuMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuOptions, - this.mnuHelp}); + this.mnuOptions}); this.mnuMain.Name = "mnuMain"; // // mnuOptions @@ -186,19 +184,6 @@ private void InitializeComponent() resources.ApplyResources(this.mnuDumperType, "mnuDumperType"); this.mnuDumperType.Name = "mnuDumperType"; // - // mnuHelp - // - resources.ApplyResources(this.mnuHelp, "mnuHelp"); - this.mnuHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuAbout}); - this.mnuHelp.Name = "mnuHelp"; - // - // mnuAbout - // - resources.ApplyResources(this.mnuAbout, "mnuAbout"); - this.mnuAbout.Name = "mnuAbout"; - this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click); - // // fbdlgDumped // resources.ApplyResources(this.fbdlgDumped, "fbdlgDumped"); @@ -225,8 +210,6 @@ private void InitializeComponent() private System.Windows.Forms.ListView lvwProcesses; private System.Windows.Forms.MenuStrip mnuMain; private System.Windows.Forms.ToolStripMenuItem mnuOptions; - private System.Windows.Forms.ToolStripMenuItem mnuHelp; - private System.Windows.Forms.ToolStripMenuItem mnuAbout; private System.Windows.Forms.ToolStripMenuItem mnuDebugPrivilege; private System.Windows.Forms.ToolStripMenuItem mnuDumperType; private System.Windows.Forms.ColumnHeader chProcessName; diff --git a/ExtremeDumper/Forms/ProcessesForm.cs b/ExtremeDumper/Forms/ProcessesForm.cs index 08a9685..acb97c7 100644 --- a/ExtremeDumper/Forms/ProcessesForm.cs +++ b/ExtremeDumper/Forms/ProcessesForm.cs @@ -6,14 +6,13 @@ using System.Resources; using System.Security.Principal; using System.Windows.Forms; -using ExtremeDumper.Dumper; +using ExtremeDumper.Dumping; using NativeSharp; using static ExtremeDumper.Forms.NativeMethods; namespace ExtremeDumper.Forms { internal partial class ProcessesForm : Form { private static readonly bool _isAdministrator = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); - private static readonly AboutForm _aboutForm = new AboutForm(); private readonly DumperTypeWrapper _dumperType = new DumperTypeWrapper(); private readonly ResourceManager _resources = new ResourceManager(typeof(ProcessesForm)); private static bool _hasSeDebugPrivilege; @@ -27,12 +26,9 @@ public ProcessesForm() { TypeCode.Int32, TypeCode.String }); - for (DumperType dumperType = DumperType.Normal; dumperType <= DumperType.AntiAntiDump; dumperType++) { - ToolStripMenuItem item; - DumperType currentDumperType; - - item = new ToolStripMenuItem(dumperType.ToString()); - currentDumperType = dumperType; + for (var dumperType = DumperType.Normal; dumperType <= DumperType.Normal; dumperType++) { + var item = new ToolStripMenuItem(dumperType.ToString()); + var currentDumperType = dumperType; item.Click += (object sender, EventArgs e) => SwitchDumperType(currentDumperType); mnuDumperType.DropDownItems.Add(item); } @@ -62,10 +58,6 @@ private void mnuDebugPrivilege_Click(object sender, EventArgs e) { } } - private void mnuAbout_Click(object sender, EventArgs e) { - _aboutForm.ShowDialog(); - } - private void lvwProcesses_Resize(object sender, EventArgs e) { lvwProcesses.AutoResizeColumns(true); } @@ -74,26 +66,24 @@ private void mnuDumpProcess_Click(object sender, EventArgs e) { if (lvwProcesses.SelectedIndices.Count == 0) return; + uint processId = uint.Parse(lvwProcesses.GetFirstSelectedSubItem(chProcessId.Index).Text); + using (var process = NativeProcess.Open(processId)) + fbdlgDumped.SelectedPath = Path.GetDirectoryName(process.ImagePath); if (fbdlgDumped.ShowDialog() != DialogResult.OK) return; - DumpProcess(uint.Parse(lvwProcesses.GetFirstSelectedSubItem(chProcessId.Index).Text), Path.Combine(fbdlgDumped.SelectedPath, "Dumps")); + DumpProcess(processId, Path.Combine(fbdlgDumped.SelectedPath, "Dumps")); } private void mnuViewModules_Click(object sender, EventArgs e) { if (lvwProcesses.SelectedIndices.Count == 0) return; - ListViewItem.ListViewSubItem processNameItem; - - processNameItem = lvwProcesses.GetFirstSelectedSubItem(chProcessName.Index); - if (Environment.Is64BitProcess && processNameItem.BackColor == Cache.DotNetColor && processNameItem.Text.EndsWith(_resources.GetString("Str32Bit"), StringComparison.Ordinal)) + var processNameItem = lvwProcesses.GetFirstSelectedSubItem(chProcessName.Index); + if (Environment.Is64BitProcess && processNameItem.BackColor == Cache.DotNetColor && processNameItem.Text.EndsWith(_resources.GetString("Str32Bit"), StringComparison.Ordinal)) { MessageBoxStub.Show(_resources.GetString("StrViewModulesSwitchTo32Bit"), MessageBoxIcon.Error); + } else { - ModulesForm modulesForm; - -#pragma warning disable IDE0067 - modulesForm = new ModulesForm(uint.Parse(lvwProcesses.GetFirstSelectedSubItem(chProcessId.Index).Text), processNameItem.Text, processNameItem.BackColor == Cache.DotNetColor, _dumperType); -#pragma warning restore IDE0067 + var modulesForm = new ModulesForm(uint.Parse(lvwProcesses.GetFirstSelectedSubItem(chProcessId.Index).Text), processNameItem.Text, processNameItem.BackColor == Cache.DotNetColor, _dumperType); modulesForm.Show(); } } @@ -110,11 +100,7 @@ private void mnuInjectDll_Click(object sender, EventArgs e) { if (lvwProcesses.SelectedIndices.Count == 0) return; - InjectingForm injectingForm; - -#pragma warning disable IDE0067 - injectingForm = new InjectingForm(uint.Parse(lvwProcesses.GetFirstSelectedSubItem(chProcessId.Index).Text)); -#pragma warning restore IDE0067 + var injectingForm = new InjectingForm(uint.Parse(lvwProcesses.GetFirstSelectedSubItem(chProcessId.Index).Text)); injectingForm.Show(); } @@ -127,49 +113,44 @@ private void mnuGotoLocation_Click(object sender, EventArgs e) { #endregion private void SwitchDumperType(DumperType dumperType) { - string name; - - name = dumperType.ToString(); + string name = dumperType.ToString(); foreach (ToolStripMenuItem item in mnuDumperType.DropDownItems) item.Checked = item.Text == name; _dumperType.Value = dumperType; } private void RefreshProcessList() { - uint[] processIds; - IntPtr snapshotHandle; - MODULEENTRY32 moduleEntry32; - ListViewItem listViewItem; - string t; - bool isDotNetProcess; - bool is64; - lvwProcesses.Items.Clear(); - processIds = NativeProcess.GetAllProcessIds(); + uint[] processIds = NativeProcess.GetAllProcessIds(); if (processIds is null) return; - moduleEntry32 = MODULEENTRY32.Default; + + var moduleEntry = MODULEENTRY32.Default; foreach (uint processId in processIds) { if (processId == 0) continue; - snapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId); + var snapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId); if (snapshotHandle == INVALID_HANDLE_VALUE) continue; - if (!Module32First(snapshotHandle, ref moduleEntry32)) + if (!Module32First(snapshotHandle, ref moduleEntry)) continue; - listViewItem = new ListViewItem(moduleEntry32.szModule); + + var listViewItem = new ListViewItem(moduleEntry.szModule); listViewItem.SubItems.Add(processId.ToString()); - listViewItem.SubItems.Add(moduleEntry32.szExePath); - isDotNetProcess = false; - while (Module32Next(snapshotHandle, ref moduleEntry32)) - if ((t = moduleEntry32.szModule.ToUpperInvariant()) == "MSCOREE.DLL" || t == "MSCORWKS.DLL" || t == "MSCORJIT.DLL" || t == "CLR.DLL" || t == "CLRJIT.DLL") { + listViewItem.SubItems.Add(moduleEntry.szExePath); + bool isDotNetProcess = false; + bool is64; + while (Module32Next(snapshotHandle, ref moduleEntry)) { + string t; + if ((t = moduleEntry.szModule.ToUpperInvariant()) == "MSCOREE.DLL" || t == "MSCORWKS.DLL" || t == "CLR.DLL" || t == "CORECLR.DLL") { listViewItem.BackColor = Cache.DotNetColor; isDotNetProcess = true; - if (Cache.Is64BitProcess && Is64BitPE(moduleEntry32.szExePath, out is64) && !is64) + if (Cache.Is64BitProcess && Is64BitPE(moduleEntry.szExePath, out is64) && !is64) listViewItem.Text += _resources.GetString("Str32Bit"); break; } - if (Cache.Is64BitProcess && !isDotNetProcess && Is64BitPE(listViewItem.SubItems[2].Text, out is64) && !is64) + } + if (!isDotNetProcess && Cache.Is64BitProcess && Is64BitPE(listViewItem.SubItems[2].Text, out is64) && !is64) listViewItem.Text += _resources.GetString("Str32Bit"); if (!mnuOnlyDotNetProcess.Checked || isDotNetProcess) lvwProcesses.Items.Add(listViewItem); @@ -178,18 +159,13 @@ private void RefreshProcessList() { } private static bool Is64BitPE(string filePath, out bool is64) { - FileStream fileStream; - BinaryReader binaryReader; - uint peOffset; - ushort machine; - try { - using (fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - using (binaryReader = new BinaryReader(fileStream)) { - binaryReader.BaseStream.Position = 0x3C; - peOffset = binaryReader.ReadUInt32(); - binaryReader.BaseStream.Position = peOffset + 0x4; - machine = binaryReader.ReadUInt16(); + using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (var reader = new BinaryReader(stream)) { + reader.BaseStream.Position = 0x3C; + uint peOffset = reader.ReadUInt32(); + reader.BaseStream.Position = peOffset + 0x4; + ushort machine = reader.ReadUInt16(); if (machine != 0x14C && machine != 0x8664) throw new InvalidDataException(); is64 = machine == 0x8664; @@ -205,8 +181,8 @@ private static bool Is64BitPE(string filePath, out bool is64) { private void DumpProcess(uint processId, string directoryPath) { if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); - using (IDumper dumper = DumperFactory.GetDumper(processId, _dumperType.Value)) - MessageBoxStub.Show($"{dumper.DumpProcess(directoryPath).ToString()} {_resources.GetString("StrDumpFilesSuccess")}{Environment.NewLine}{directoryPath}", MessageBoxIcon.Information); + using (var dumper = DumperFactory.GetDumper(processId, _dumperType.Value)) + MessageBoxStub.Show($"{dumper.DumpProcess(directoryPath)} {_resources.GetString("StrDumpFilesSuccess")}{Environment.NewLine}{directoryPath}", MessageBoxIcon.Information); } } } diff --git a/ExtremeDumper/Forms/ProcessesForm.resx b/ExtremeDumper/Forms/ProcessesForm.resx index a39b886..834ab07 100644 --- a/ExtremeDumper/Forms/ProcessesForm.resx +++ b/ExtremeDumper/Forms/ProcessesForm.resx @@ -121,9 +121,6 @@ 184, 22 - - 157, 22 - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -151,17 +148,21 @@ toolStripSeparator3 + + 933, 637 + 184, 22 - - mnuDumpProcess + + System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.ListView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - mnuAbout + + + 1 (32 Bit) @@ -184,25 +185,24 @@ View Modules - - System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 7, 17 - - - 0 + + 157, 22 + + + mnuRefreshProcessList mnuGotoLocation + + Images have been dumped to: + mnuOptions - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - mnuViewModules @@ -231,20 +231,23 @@ chProcessName + + Path + + + mnuProcessContext + + + ProcessesForm + 100, 22 - - 933, 27 - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - toolStripSeparator1 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 7, 3, 0, 3 CenterScreen @@ -253,20 +256,11 @@ Goto Location - 微软雅黑, 9pt - - - 184, 22 + Microsoft YaHei, 9pt lvwProcesses - - Help - - - System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Name @@ -303,35 +297,29 @@ mnuOnlyDotNetProcess - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 mnuMain + + 44, 21 + 184, 22 - - About + + mnuDumpProcess System.Windows.Forms.FolderBrowserDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - toolStripSeparator2 - 184, 22 - - 157, 22 + + System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -339,15 +327,15 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ProcessesForm - - - $this + + 184, 22 DumperType + + Success + PID @@ -357,29 +345,26 @@ 2 - - 44, 21 - Enable Debug Privilege 160, 6 - - mnuProcessContext + + $this System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 7, 3, 0, 3 + + toolStripSeparator1 - - mnuRefreshProcessList + + 0 - - Images have been dumped to: + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 @@ -390,26 +375,23 @@ 163, 22 - - 1 + + toolStripSeparator2 Options - - 933, 637 - - - Path + + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Success + + 933, 27 - - System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - mnuHelp + + 157, 22 181, 6 diff --git a/ExtremeDumper/Forms/ProcessesForm.zh-CN.resx b/ExtremeDumper/Forms/ProcessesForm.zh-CN.resx index ef50235..9cfef25 100644 --- a/ExtremeDumper/Forms/ProcessesForm.zh-CN.resx +++ b/ExtremeDumper/Forms/ProcessesForm.zh-CN.resx @@ -129,9 +129,6 @@ 选择转储文件保存位置 - - 关于 - 提升Debug权限 @@ -144,9 +141,6 @@ 打开文件所在的位置 - - 帮助 - 注入DLL diff --git a/ExtremeDumper/Forms/Resources.Designer.cs b/ExtremeDumper/Forms/Resources.Designer.cs index 9af5bb6..3a890f6 100644 --- a/ExtremeDumper/Forms/Resources.Designer.cs +++ b/ExtremeDumper/Forms/Resources.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -13,13 +13,13 @@ namespace ExtremeDumper.Forms { /// - /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// A strongly-typed resource class, for looking up localized strings, etc. /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -33,7 +33,7 @@ internal Resources() { } /// - /// 返回此类使用的缓存的 ResourceManager 实例。 + /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { @@ -47,8 +47,8 @@ internal Resources() { } /// - /// 使用此强类型资源类,为所有资源查找 - /// 重写当前线程的 CurrentUICulture 属性。 + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { @@ -61,17 +61,7 @@ internal Resources() { } /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 - /// - internal static System.Drawing.Bitmap Avatar { - get { - object obj = ResourceManager.GetObject("Avatar", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// 查找类似于 (图标) 的 System.Drawing.Icon 类型的本地化资源。 + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// internal static System.Drawing.Icon Icon { get { diff --git a/ExtremeDumper/Forms/Resources.resx b/ExtremeDumper/Forms/Resources.resx index 75e00d7..8efe2e9 100644 --- a/ExtremeDumper/Forms/Resources.resx +++ b/ExtremeDumper/Forms/Resources.resx @@ -118,10 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Resources\Avatar.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - Resources\Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\images\extremedumper.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/ExtremeDumper/Forms/Resources/Avatar.png b/ExtremeDumper/Forms/Resources/Avatar.png deleted file mode 100644 index 32b3b22..0000000 Binary files a/ExtremeDumper/Forms/Resources/Avatar.png and /dev/null differ diff --git a/ExtremeDumper/GlobalExceptionCatcher.cs b/ExtremeDumper/GlobalExceptionCatcher.cs index 511257a..574257d 100644 --- a/ExtremeDumper/GlobalExceptionCatcher.cs +++ b/ExtremeDumper/GlobalExceptionCatcher.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Text; using System.Windows.Forms; using ExtremeDumper.Forms; @@ -22,22 +23,24 @@ public static void Catch() { } private static void ShowDetailException(Exception exception) { - StringBuilder sb; - - sb = new StringBuilder(); + var sb = new StringBuilder(); DumpException(exception, sb); MessageBoxStub.Show(sb.ToString(), MessageBoxIcon.Error); } private static void DumpException(Exception exception, StringBuilder sb) { - sb.AppendLine("Type: " + Environment.NewLine + exception.GetType().FullName); - sb.AppendLine("Message: " + Environment.NewLine + exception.Message); - sb.AppendLine("Source: " + Environment.NewLine + exception.Source); - sb.AppendLine("StackTrace: " + Environment.NewLine + exception.StackTrace); - sb.AppendLine("TargetSite: " + Environment.NewLine + exception.TargetSite.ToString()); + sb.AppendLine($"Type: {Environment.NewLine}{exception.GetType().FullName}"); + sb.AppendLine($"Message: {Environment.NewLine}{exception.Message}"); + sb.AppendLine($"Source: {Environment.NewLine}{exception.Source}"); + sb.AppendLine($"StackTrace: {Environment.NewLine}{exception.StackTrace}"); + sb.AppendLine($"TargetSite: {Environment.NewLine}{exception.TargetSite}"); sb.AppendLine("----------------------------------------"); - if (exception.InnerException != null) + if (!(exception.InnerException is null)) DumpException(exception.InnerException, sb); + if (exception is ReflectionTypeLoadException reflectionTypeLoadException) { + foreach (var loaderException in reflectionTypeLoadException.LoaderExceptions) + DumpException(loaderException, sb); + } } } } diff --git a/ExtremeDumper/Forms/Resources/Icon.ico b/ExtremeDumper/Images/ExtremeDumper.ico similarity index 100% rename from ExtremeDumper/Forms/Resources/Icon.ico rename to ExtremeDumper/Images/ExtremeDumper.ico diff --git a/ExtremeDumper/Program.cs b/ExtremeDumper/Program.cs index a7b798d..ff52540 100644 --- a/ExtremeDumper/Program.cs +++ b/ExtremeDumper/Program.cs @@ -1,13 +1,12 @@ using System; using System.Windows.Forms; using ExtremeDumper.Forms; -using Microsoft.Diagnostics.Runtime.Utilities; namespace ExtremeDumper { public static class Program { [STAThread] public static void Main() { - SymbolLocator._NT_SYMBOL_PATH = " "; + Environment.SetEnvironmentVariable("_NT_SYMBOL_PATH", string.Empty); // 禁止在线搜索PDB文件 GlobalExceptionCatcher.Catch(); Application.EnableVisualStyles(); diff --git a/ExtremeDumper/Properties/AssemblyInfo.cs b/ExtremeDumper/Properties/AssemblyInfo.cs deleted file mode 100644 index 9b53a9c..0000000 --- a/ExtremeDumper/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Reflection; - -[assembly: AssemblyTitle("ExtremeDumper")] -[assembly: AssemblyDescription(".NET Assemblies Dumper")] -[assembly: AssemblyProduct("ExtremeDumper")] -[assembly: AssemblyCopyright("Copyright © 2018-2019 Wwh")] -[assembly: AssemblyVersion("2.9.3.5")] -[assembly: AssemblyFileVersion("2.9.3.5")] diff --git a/Libraries/MetadataLocator b/Libraries/MetadataLocator deleted file mode 160000 index e001a72..0000000 --- a/Libraries/MetadataLocator +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e001a72d761e7611df505da5c42ad22e99ddf8a3 diff --git a/Libraries/clrmd b/Libraries/clrmd deleted file mode 160000 index 8dc2a2e..0000000 --- a/Libraries/clrmd +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8dc2a2e8c48d106e26bb78b167f9b1abad8f1f66 diff --git a/Libraries/dnlib b/Libraries/dnlib deleted file mode 160000 index b5b4ef4..0000000 --- a/Libraries/dnlib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b5b4ef40bdbd6f22096182456eb85a896704fffb diff --git a/appveyor.yml b/appveyor.yml index 800eae6..7896542 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,8 +2,6 @@ version: '{build}' image: Visual Studio 2019 configuration: Release platform: Any CPU -install: -- cmd: git submodule update --init --recursive before_build: - cmd: appveyor-retry nuget restore build: