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: