Skip to content

Commit

Permalink
Merge pull request #156 from Washi1337/development
Browse files Browse the repository at this point in the history
4.5.0
  • Loading branch information
Washi1337 authored Mar 29, 2021
2 parents 6edfe92 + 55c81cd commit 04b1b79
Show file tree
Hide file tree
Showing 154 changed files with 7,061 additions and 3,484 deletions.
78 changes: 78 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@

[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4

# Microsoft .NET properties
csharp_new_line_before_members_in_object_initializers = false
csharp_preferred_modifier_order = public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion
csharp_style_var_elsewhere = true:suggestion
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
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
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion

# ReSharper properties
resharper_autodetect_indent_settings = true
resharper_csharp_wrap_before_binary_opsign = true
resharper_csharp_wrap_before_first_type_parameter_constraint = true
resharper_keep_existing_embedded_arrangement = false
resharper_keep_existing_switch_expression_arrangement = false
resharper_max_array_initializer_elements_on_line = 20
resharper_max_enum_members_on_line = 1
resharper_max_initializer_elements_on_line = 1
resharper_place_abstract_accessorholder_on_single_line = false
resharper_place_attribute_on_same_line = false
resharper_place_constructor_initializer_on_same_line = false
resharper_place_simple_embedded_statement_on_same_line = false
resharper_place_simple_initializer_on_single_line = false
resharper_show_autodetect_configure_formatting_tip = false
resharper_use_indent_from_vs = false
resharper_wrap_array_initializer_style = chop_if_long

# ReSharper inspection severities
resharper_arrange_redundant_parentheses_highlighting = hint
resharper_arrange_this_qualifier_highlighting = hint
resharper_arrange_type_member_modifiers_highlighting = hint
resharper_arrange_type_modifiers_highlighting = hint
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = hint
resharper_inconsistent_naming_highlighting = hint
resharper_introduce_optional_parameters_global_highlighting = none
resharper_loop_can_be_converted_to_query_highlighting = none
resharper_redundant_base_qualifier_highlighting = warning
resharper_shift_expression_real_shift_count_is_zero_highlighting = hint
resharper_shift_expression_result_equals_zero_highlighting = hint
resharper_shift_expression_zero_left_operand_highlighting = hint
resharper_suggest_var_or_type_built_in_types_highlighting = hint
resharper_suggest_var_or_type_elsewhere_highlighting = hint
resharper_suggest_var_or_type_simple_types_highlighting = hint
resharper_unused_member_global_highlighting = hint
resharper_web_config_module_not_resolved_highlighting = warning
resharper_web_config_type_not_resolved_highlighting = warning
resharper_web_config_wrong_module_highlighting = warning

[{*.bash,*.sh,*.zsh}]
indent_style = space
indent_size = 2

[{*.yaml,*.yml}]
indent_style = space
indent_size = 2

[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,fs,fsi,fsscript,fsx,hlsl,hlsli,hlslinc,master,ml,mli,nuspec,paml,razor,resw,resx,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
indent_size = 4
tab_width = 4
50 changes: 33 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
AsmResolver Coding Style and Licensing
======================================

If you make any changes to AsmResolver, you are agreeing to the license conditions as specified in [LICENSE.md](LICENSE.md).

Aims
----
## Aims

This guide is for developers who wish to contribute to the AsmResolver codebase. It will detail how to properly style and format code to fit this project.

Following this guide and formatting your code as detailed will likely get your pull request merged much faster than if you don't (assuming the written code has no mistakes in itself).

General
-------
If you make any changes to AsmResolver, you are agreeing to the license conditions as specified in [LICENSE.md](LICENSE.md).


## General Workflow

The AsmResolver project generally follows the principles of [Git Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow), with a few variations. Below a summary:

- Prefer to create a branch based on `development`.
- Do not branch from `master` unless it is a serious bug and requires a hotfix. `master` is supposed to be always in sync with the nuget feed.
- Prefix your branch accordingly, depending on what kind of change you are trying to make.
- For new features, use `feature/name-of-feature`.
- For issues and/or bug fixes, use `issue/name-of-issue-or-bug`.
- Push your changes on this branch.
- Make sure you are following the coding style guidelines as described in this document below.
- Open a [Pull Request](https://github.com/Washi1337/AsmResolver/pulls), setting the `development` branch as a base branch to merge into.
- Wait for your pull request to be reviewed and accepted.
- Pull requests into `development` will only be accepted if all unit tests succeed and follow the guidelines as described in this document.


## C# Coding Style

The general idea behind the coding style that is adopted in the AsmResolver project follows a few key points:

Expand All @@ -23,8 +38,8 @@ Furthermore:
- Try to limit the number of characters on one line to 120 characters.
- Avoid preprocessor directives or `#region`s

C# Coding Style
---------------
For editors that support EditorConfig, there is an `.editorconfig` file for you to use in the root directory of the repository.


### General naming conventions

Expand Down Expand Up @@ -187,17 +202,17 @@ Do:
```csharp
int x = 123;
string y = "Hello, world!";
byte[] z = new byte[10];

var array = new byte[10];
var instance = new MyClass(...);
```

Don't:
```csharp
var x = 123;
var y = "Hello, world!";
var array = new byte[10];

byte[] array = new byte[10];
MyClass instance = new MyClass(...);
```

Expand Down Expand Up @@ -251,7 +266,7 @@ this.SomeMethod();

### Ternary experssions

Always place the arms of a ternary expression on separate lines:
Prefer to place the arms of a ternary expression on separate lines:

Do:
```csharp
Expand All @@ -271,7 +286,7 @@ Prefer `for` loops over `foreach` when heap allocated enumerators can be avoided

Do:
```csharp
IList<T> items = ...;
var items = assembly.Modules;
for (int i = 0; i < items.Count; i++)
{
// Use items[i]
Expand All @@ -280,28 +295,29 @@ for (int i = 0; i < items.Count; i++)

Don't:
```csharp
IList<T> items = ...;
var items = assembly.Modules;
foreach (var item in items) // IList<T>.GetEnumerator() returns a heap allocated enumerator
{
// Use item
}
```

### Usage of LINQ
### Usage of LINQ and method chains

Using Linq is acceptable, but prefer the method syntax over the query syntax. When multiple method calls are chained together, prefer to put them on separate lines:
Using LINQ is acceptable, but prefer the method syntax over the query syntax. When multiple method calls are chained together, prefer to put them on separate lines:

Do:
```csharp
var allClasses = assembly.Modules
var allClassMethods = assembly.Modules
.SelectMany(m => m.GetAllTypes())
.Where(t => t.IsClass)
.SelectMany(t => t.Methods)
.ToArray();
```

Don't:
```csharp
var allClasses = assembly.Modules.SelectMany(m => m.GetAllTypes()).Where(t => t.IsClass).ToArray();
var allClasses = assembly.Modules.SelectMany(m => m.GetAllTypes()).Where(t => t.IsClass).SelectMany(t => t.Methods).ToArray();
```

### XML documentation
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<RepositoryUrl>https://github.com/Washi1337/AsmResolver</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<LangVersion>8</LangVersion>
<Version>4.4.0</Version>
<Version>4.5.0</Version>
</PropertyGroup>

</Project>
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ AsmResolver

[![Master branch build status](https://img.shields.io/appveyor/ci/Washi1337/AsmResolver/master.svg)](https://ci.appveyor.com/project/Washi1337/asmresolver/branch/master) [![Nuget feed](https://img.shields.io/nuget/v/AsmResolver.svg)](https://www.nuget.org/packages/AsmResolver/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Documentation Status](https://readthedocs.org/projects/asmresolver/badge/?version=latest)](https://asmresolver.readthedocs.io/en/latest/?badge=latest)

AsmResolver is a PE inspection library allowing .NET programmers to read, modify and write executable files. This includes .NET as well as native native images. The library exposes high-level representations of the PE, while still allowing the user to access low-level structures.

AsmResolver is a PE inspection library allowing .NET programmers to read, modify and write executable files. This includes .NET as well as native images. The library exposes high-level representations of the PE, while still allowing the user to access low-level structures.

AsmResolver is released under the MIT license.


Binaries
-----------
--------
Get the latest stable build from the [nuget feed](https://www.nuget.org/packages/AsmResolver/), or download the bleeding edge build from [appveyor](https://ci.appveyor.com/project/Washi1337/asmresolver/build/artifacts).

| Branch | Build status |
Expand All @@ -19,14 +19,17 @@ Get the latest stable build from the [nuget feed](https://www.nuget.org/packages

Alternatively, you can build the project yourself using MSBuild or an IDE that works with MSBuild (such as Visual Studio and JetBrains Rider), assuming you have the .NET Core toolchain installed. If you want to compile the test libraries as well, make sure to also restore all nuget packages.


Documentation
-------------
Check out the [wiki](https://asmresolver.readthedocs.org/) for guides and information on how to use the library!


Contributing
------------
See [CONTRIBUTING.md](CONTRIBUTING.md).


Found a bug or have questions?
------------------------------
Please use the [issue tracker](https://github.com/Washi1337/AsmResolver/issues). Try to be as descriptive as possible.
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
- master

image: Visual Studio 2019
version: 4.3.0-master-build.{build}
version: 4.5.0-master-build.{build}
configuration: Release

skip_commits:
Expand Down Expand Up @@ -33,7 +33,7 @@
- development

image: Visual Studio 2019
version: 4.4.0-dev-build.{build}
version: 4.5.0-dev-build.{build}
configuration: Release

skip_commits:
Expand Down
45 changes: 43 additions & 2 deletions docs/dotnet/advanced-pe-image-building.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,48 @@ While this is easy, and would probably work for most .NET module processing, it
module.Write(@"C:\Path\To\Output\Binary.exe", imageBuilder);
This article explores various features about the ``ManagedPEImageBuilder`` class that can be configured.
Alternatively, it is possible to call the ``CreateImage`` method directly. This allows for inspecting all build artifacts, as well as post processing of the constructed PE image before it is written to the disk.

.. code-block:: csharp
var imageBuilder = new ManagedPEImageBuilder();
/* Configuration of imageBuilder here... */
// Construct image.
var result = imageBuilder.CreateImage(module);
var image = result.ConstructedImage;
/* Post processing of image happens here... */
// Write image to the disk.
var fileBuilder = new ManagedPEFileBuilder();
var file = fileBuilder.CreateFile(image);
file.Write(@"C:\Path\To\Output\Binary.exe");
This article explores various features about the ``ManagedPEImageBuilder`` class.


Token mappings
--------------

Upon constructing a new PE image for a module, members defined in the module might be re-ordered. This can make post-processing of the PE image difficult, as metadata members cannot be looked up by their original metadata token anymore. The ``PEImageBuildResult`` object returned by ``CreateImage`` defines a property called ``TokenMapping``. This object maps all members that were included in the construction of the PE image to the newly assigned metadata tokens, allowing for new metadata rows to be looked up easily and efficiently.

.. code-block:: csharp
var mainMethod = module.ManagedEntrypointMethod;
// Build PE image.
var result = imageBuilder.CreateImage(module);
// Look up the new metadata row assigned to the main method.
var newToken = result.TokenMapping[mainMethod];
var mainMethodRow = result.ConstructedImage.DotNetDirectory.Metadata
.GetStream<TablesStream>()
.GetTable<MethodDefinitionRow>()
.GetByRid(newToken.Rid);
Preserving raw metadata structure
---------------------------------
Expand Down Expand Up @@ -105,7 +146,7 @@ After writing the module to an output stream, use the ``StrongNameSigner`` class
Image Builder Diagnostics
-------------------------

.NET modules that contain invalid metadata and/or method bodies might cause problems upon serializing it to a PE image or file. To inspect all errors that occurred during the construction of a PE image, it is possible to call the ``CreateImage`` method of the image builder directly. This method returns an instance of the ``PEImageBuildResult`` class, which defines a property called ``DiagnosticBag``. This is a collection that contains all the problems that occurred during the process:
.NET modules that contain invalid metadata and/or method bodies might cause problems upon serializing it to a PE image or file. To inspect all errors that occurred during the construction of a PE image, call the ``CreateImage`` method directly and get the value of the ``DiagnosticBag`` property. This is a collection that contains all the problems that occurred during the process:

.. code-block:: csharp
Expand Down
9 changes: 9 additions & 0 deletions docs/dotnet/managed-method-bodies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ Alternatively, when using the ``Add`` or ``Insert`` overloads, it is possible to
The ``switch`` operation uses a ``IList<ICilLabel>`` instead.

.. note::

When a branching instruction contains a ``null`` label or a label that references an instruction that is not present in the method body, AsmResolver will by default report an exception upon serializing the code stream. This can be disabled by setting ``VerifyLabelsOnBuild`` to ``false``.


Finding instructions by offset
------------------------------
Expand Down Expand Up @@ -245,6 +249,11 @@ Exception handlers are regions in the method body that are protected from except
Depending on the value of ``HandlerType``, either ``FilterStart`` or ``ExceptionType``, or neither has a value.
.. note::
Similar to branch instructions, when an exception handler contains a ``null`` label or a label that references an instruction that is not present in the method body, AsmResolver will report an exception upon serializing the code stream. This can be disabled by setting ``VerifyLabelsOnBuild`` to ``false``.
Maximum stack depth
-------------------
Expand Down
12 changes: 4 additions & 8 deletions docs/dotnet/token-allocation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,18 @@ Metadata Token Allocation

A lot of models in a .NET module are assigned a unique metadata token. This token can be accessed through the ``IMetadataMember.MetadataToken`` property. The exception to this rule is newly created metadata members. These newly created members are assigned the zero token (a token with RID = 0). Upon building a module, these tokens will be replaced with their actual tokens.

Some usecase of AsmResolver will depend on the knowledge of tokens of newly created members prior to serializing the module. Therefore, AsmResolver provides the ``TokenAllocator`` class, which allows for assigning new tokens to members pre-emptively. If a module is then written to the disk with the ``MetadataFlags.PreserveTableIndices`` flags set (see Advanced PE Image Building for more information on how that is done), this token will be preserved in the final image.
Custom Token Allocation
-----------------------

Getting the allocator
---------------------
Some usecase of AsmResolver will depend on the knowledge of tokens of newly created members prior to serializing the module. Therefore, AsmResolver provides the ``TokenAllocator`` class, which allows for assigning new tokens to members pre-emptively. If a module is then written to the disk with the ``MetadataFlags.PreserveTableIndices`` flags set (see Advanced PE Image Building for more information on how that is done), this token will be preserved in the final image.

The token allocator for a particular module can be accessed through the ``ModuleDefinition.TokenAllocator`` property:

.. code-block:: csharp
var allocator = module.TokenAllocator;
Assigning new tokens
--------------------

Assigning tokens to newly created members can be done by using the ``AssignNextAvailableToken`` method:
Using the allocator, it is possible to assign metadata tokens to newly created members. This is done using the ``AssignNextAvailableToken`` method:

.. code-block:: csharp
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
AsmResolver
===========

This is the documentation of the AsmResolver project. AsmResolver is a set of libraries allowing .NET programmers to read, modify and write executable files. This includes .NET as well as native native images. The library exposes high-level representations of the PE, while still allowing the user to access low-level structures.
This is the documentation of the AsmResolver project. AsmResolver is a set of libraries allowing .NET programmers to read, modify and write executable files. This includes .NET as well as native images. The library exposes high-level representations of the PE, while still allowing the user to access low-level structures.

Table of Contents:
------------------
Expand Down
6 changes: 6 additions & 0 deletions src/AsmResolver.DotNet/AsmResolver.DotNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<NoWarn>1701;1702;NU5105</NoWarn>
<LangVersion>9</LangVersion>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
Expand All @@ -21,4 +22,9 @@
<ProjectReference Include="..\AsmResolver.PE\AsmResolver.PE.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Text.Json" Version="5.0.0" />
<PackageReference Include="Xunit.SkippableFact" Version="1.4.13" />
</ItemGroup>

</Project>
Loading

0 comments on commit 04b1b79

Please sign in to comment.