dncil


Namedncil JSON
Version 1.0.2 PyPI version JSON
download
home_pagehttps://www.github.com/mandiant/dncil
SummaryThe FLARE team's open-source library to disassemble Common Intermediate Language (CIL) instructions.
upload_time2022-12-12 19:09:29
maintainer
docs_urlNone
authorMike Hunhoff
requires_python>=3.7
license
keywords .net dotnet cil il disassembly flare
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![dncil](./.github/dncil.png)

[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/dncil)](https://pypi.org/project/dncil)
[![Last release](https://img.shields.io/github/v/release/mandiant/dncil)](https://github.com/mandiant/dncil/releases)
[![CI](https://github.com/mandiant/dncil/actions/workflows/tests.yml/badge.svg)](https://github.com/mandiant/dncil/actions/workflows/tests.yml)
[![Downloads](https://pepy.tech/badge/dncil)](https://pepy.tech/project/dncil)
[![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE.txt)

`dncil` is a Common Intermediate Language (`CIL`) disassembly library written in Python that supports parsing the header, instructions, and exception handlers of `.NET` managed methods. Parsed data is exposed through an object-oriented API to help you quickly develop `CIL` analysis tools using `dncil`.

Why `Python`? Existing libraries that support `CIL` disassembly, like [`dnLib`](https://github.com/0xd4d/dnlib), are written in `C#`. To leverage these tools, you must build `C#` applications which requires `C#` development experience. Using `dncil`, a pure `Python` alternative, you:

1. Do not need `C#` experience to analyze `CIL` programmatically.
2. Can quickly develop and test your `CIL` analysis tools.
3. Can easily integrate your `CIL` analysis tools with existing `Python` projects.

## Example

The example script [`print_cil_from_dn_file.py`](scripts/print_cil_from_dn_file.py) uses `dncil` together with `.NET` analysis library [`dnfile`](https://github.com/malwarefrank/dnfile) to disassemble the managed methods found in a `.NET` executable. Let's see what it can do.

First, we compile the following `C#` source code:

```C#
using System;	

public class HelloWorld
{
    public static void Main(string[] args)
    {
        Console.WriteLine ("Hello World!");
    }
}
```

Compilation results in a `PE` executable containing `.NET` metadata which informs the `Common Language Runtime` (`CLR`) how to execute our code. We use `dnfile` to parse this metadata which gives us the offset of our managed method `Main`. We then use `dncil` to disassemble and display the `CIL` instructions stored at this location.

Let's see the above in action:

```
$ python scripts/print_cil_from_dn_file.py hello-world.exe 

Method: Main
0000    00                  nop            
0001    72 01 00 00 70      ldstr          "Hello World!"
0006    28 04 00 00 0a      call           System.Console::WriteLine
000B    00                  nop            
000C    2a                  ret            
```

Our method `Main` is represented by the [`CilMethodBody`](dncil/cil/body/__init__.py) class. This class holds data that includes the header, `CIL` instructions, and exception handlers of a given managed method. It also exposes various helper functions:

```Python
>  main_method_body.flags
SmallFormat  :  false
TinyFormat   :  false
FatFormat    :  false
TinyFormat1  :  true
MoreSects    :  false
InitLocals   :  false
CompressedIL :  false
>  main_method_body.size
14
>  hexdump.hexdump(main_method_body.get_bytes())
00000000: 36 00 72 01 00 00 70 28  04 00 00 0A 00 2A        6.r...p(.....*
>  hexdump.hexdump(main_method_body.get_header_bytes())
00000000: 36                                                6
>  hexdump.hexdump(main_method_body.get_instruction_bytes())
00000000: 00 72 01 00 00 70 28 04  00 00 0A 00 2A           .r...p(.....*
```

Each `CIL` instruction found in our managed method `Main` is represented by the [`Instruction`](dncil/cil/instruction.py) class. This class holds data that includes the offset, mnemonic, opcode, and operand of a given `CIL` instruction. It also exposes various helper functions:

```Python
>  len(main_method_body.instructions)
5
>  insn = main_method_body.instructions[1]
>  insn.offset
1
>  insn.mnemonic
'ldstr'
>  insn.operand
token(0x70000001)
>  insn.is_ldstr()
True
>  insn.size
5
>  hexdump.hexdump(insn.get_bytes())
00000000: 72 01 00 00 70                                    r...p
>  hexdump.hexdump(insn.get_opcode_bytes())
00000000: 72                                                r
>  hexdump.hexdump(insn.get_operand_bytes())
00000000: 01 00 00 70                                       ...p
```

## Installing

To install `dncil` use `pip` to fetch the `dncil` module:

```
$ pip install dncil
```

To execute the example scripts be sure to install [`dnfile`](https://github.com/malwarefrank/dnfile). Alternatively, install `dncil` with the development dependencies as described in the `Development` section below.

See [print_cil_from_bytes.py](scripts/print_cil_from_bytes.py) for a quick example of using `dncil`to print the `CIL` instructions found in a byte stream containing a `.NET` managed method.

## Development

If you'd like to review and modify `dncil` source code, you'll need to download it from GitHub and install it locally. 

Use the following command to install `dncil` locally with development dependencies:

```
$ pip install /local/path/to/src[dev]
```

You'll need `dncil`'s development dependencies to run tests and linting as described below.

### Testing

Use the following command to run tests:

```
$ pytest /local/path/to/src/tests
```

### Linting

Use the following commands to identify format errors:

```
$ black -l 120 -c /local/path/to/src
$ isort --profile black --length-sort --line-width 120 -c /local/path/to/src
$ mypy --config-file /local/path/to/src/.github/mypy/mypy.ini /local/path/to/src/dncil/ /local/path/to/src/scripts/ /local/path/to/src/tests/
```

## Credits

`dncil` is based on the `CIL` parsing code found in [`dnLib`](https://github.com/0xd4d/dnlib).



            

Raw data

            {
    "_id": null,
    "home_page": "https://www.github.com/mandiant/dncil",
    "name": "dncil",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": ".net dotnet cil il disassembly FLARE",
    "author": "Mike Hunhoff",
    "author_email": "michael.hunhoff@mandiant.com",
    "download_url": "https://files.pythonhosted.org/packages/53/79/498fc2e7e7e132bb7930a28cd075f3b3e77de3b4be5f38a9340a866f9802/dncil-1.0.2.tar.gz",
    "platform": null,
    "description": "![dncil](./.github/dncil.png)\n\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/dncil)](https://pypi.org/project/dncil)\n[![Last release](https://img.shields.io/github/v/release/mandiant/dncil)](https://github.com/mandiant/dncil/releases)\n[![CI](https://github.com/mandiant/dncil/actions/workflows/tests.yml/badge.svg)](https://github.com/mandiant/dncil/actions/workflows/tests.yml)\n[![Downloads](https://pepy.tech/badge/dncil)](https://pepy.tech/project/dncil)\n[![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE.txt)\n\n`dncil` is a Common Intermediate Language (`CIL`) disassembly library written in Python that supports parsing the header, instructions, and exception handlers of `.NET` managed methods. Parsed data is exposed through an object-oriented API to help you quickly develop `CIL` analysis tools using `dncil`.\n\nWhy `Python`? Existing libraries that support `CIL` disassembly, like [`dnLib`](https://github.com/0xd4d/dnlib), are written in `C#`. To leverage these tools, you must build `C#` applications which requires `C#` development experience. Using `dncil`, a pure `Python` alternative, you:\n\n1. Do not need `C#` experience to analyze `CIL` programmatically.\n2. Can quickly develop and test your `CIL` analysis tools.\n3. Can easily integrate your `CIL` analysis tools with existing `Python` projects.\n\n## Example\n\nThe example script [`print_cil_from_dn_file.py`](scripts/print_cil_from_dn_file.py) uses `dncil` together with `.NET` analysis library [`dnfile`](https://github.com/malwarefrank/dnfile) to disassemble the managed methods found in a `.NET` executable. Let's see what it can do.\n\nFirst, we compile the following `C#` source code:\n\n```C#\nusing System;\t\n\npublic class HelloWorld\n{\n    public static void Main(string[] args)\n    {\n        Console.WriteLine (\"Hello World!\");\n    }\n}\n```\n\nCompilation results in a `PE` executable containing `.NET` metadata which informs the `Common Language Runtime` (`CLR`) how to execute our code. We use `dnfile` to parse this metadata which gives us the offset of our managed method `Main`. We then use `dncil` to disassemble and display the `CIL` instructions stored at this location.\n\nLet's see the above in action:\n\n```\n$ python scripts/print_cil_from_dn_file.py hello-world.exe \n\nMethod: Main\n0000    00                  nop            \n0001    72 01 00 00 70      ldstr          \"Hello World!\"\n0006    28 04 00 00 0a      call           System.Console::WriteLine\n000B    00                  nop            \n000C    2a                  ret            \n```\n\nOur method `Main` is represented by the [`CilMethodBody`](dncil/cil/body/__init__.py) class. This class holds data that includes the header, `CIL` instructions, and exception handlers of a given managed method. It also exposes various helper functions:\n\n```Python\n>  main_method_body.flags\nSmallFormat  :  false\nTinyFormat   :  false\nFatFormat    :  false\nTinyFormat1  :  true\nMoreSects    :  false\nInitLocals   :  false\nCompressedIL :  false\n>  main_method_body.size\n14\n>  hexdump.hexdump(main_method_body.get_bytes())\n00000000: 36 00 72 01 00 00 70 28  04 00 00 0A 00 2A        6.r...p(.....*\n>  hexdump.hexdump(main_method_body.get_header_bytes())\n00000000: 36                                                6\n>  hexdump.hexdump(main_method_body.get_instruction_bytes())\n00000000: 00 72 01 00 00 70 28 04  00 00 0A 00 2A           .r...p(.....*\n```\n\nEach `CIL` instruction found in our managed method `Main` is represented by the [`Instruction`](dncil/cil/instruction.py) class. This class holds data that includes the offset, mnemonic, opcode, and operand of a given `CIL` instruction. It also exposes various helper functions:\n\n```Python\n>  len(main_method_body.instructions)\n5\n>  insn = main_method_body.instructions[1]\n>  insn.offset\n1\n>  insn.mnemonic\n'ldstr'\n>  insn.operand\ntoken(0x70000001)\n>  insn.is_ldstr()\nTrue\n>  insn.size\n5\n>  hexdump.hexdump(insn.get_bytes())\n00000000: 72 01 00 00 70                                    r...p\n>  hexdump.hexdump(insn.get_opcode_bytes())\n00000000: 72                                                r\n>  hexdump.hexdump(insn.get_operand_bytes())\n00000000: 01 00 00 70                                       ...p\n```\n\n## Installing\n\nTo install `dncil` use `pip` to fetch the `dncil` module:\n\n```\n$ pip install dncil\n```\n\nTo execute the example scripts be sure to install [`dnfile`](https://github.com/malwarefrank/dnfile). Alternatively, install `dncil` with the development dependencies as described in the `Development` section below.\n\nSee [print_cil_from_bytes.py](scripts/print_cil_from_bytes.py) for a quick example of using `dncil`to print the `CIL` instructions found in a byte stream containing a `.NET` managed method.\n\n## Development\n\nIf you'd like to review and modify `dncil` source code, you'll need to download it from GitHub and install it locally. \n\nUse the following command to install `dncil` locally with development dependencies:\n\n```\n$ pip install /local/path/to/src[dev]\n```\n\nYou'll need `dncil`'s development dependencies to run tests and linting as described below.\n\n### Testing\n\nUse the following command to run tests:\n\n```\n$ pytest /local/path/to/src/tests\n```\n\n### Linting\n\nUse the following commands to identify format errors:\n\n```\n$ black -l 120 -c /local/path/to/src\n$ isort --profile black --length-sort --line-width 120 -c /local/path/to/src\n$ mypy --config-file /local/path/to/src/.github/mypy/mypy.ini /local/path/to/src/dncil/ /local/path/to/src/scripts/ /local/path/to/src/tests/\n```\n\n## Credits\n\n`dncil` is based on the `CIL` parsing code found in [`dnLib`](https://github.com/0xd4d/dnlib).\n\n\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "The FLARE team's open-source library to disassemble Common Intermediate Language (CIL) instructions.",
    "version": "1.0.2",
    "split_keywords": [
        ".net",
        "dotnet",
        "cil",
        "il",
        "disassembly",
        "flare"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "4d614f4cf521c9ad86f871ddbe9b4e6b",
                "sha256": "69d389e9b850fa9afa2e37ca252b01476379991eee88fd33ab76f924d36dd68d"
            },
            "downloads": -1,
            "filename": "dncil-1.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "4d614f4cf521c9ad86f871ddbe9b4e6b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 27010,
            "upload_time": "2022-12-12T19:09:27",
            "upload_time_iso_8601": "2022-12-12T19:09:27.582794Z",
            "url": "https://files.pythonhosted.org/packages/5b/2d/f6e3fa0832ce1d934a851757058235c9ec5741cff0129cfcf205a9359489/dncil-1.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "393f458a96ec17aee0b497ff9ab5ffbe",
                "sha256": "1557675c2d1351d3260509881cff0383309f81cda4944ed2c3f5cc352953aa15"
            },
            "downloads": -1,
            "filename": "dncil-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "393f458a96ec17aee0b497ff9ab5ffbe",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 19318,
            "upload_time": "2022-12-12T19:09:29",
            "upload_time_iso_8601": "2022-12-12T19:09:29.322462Z",
            "url": "https://files.pythonhosted.org/packages/53/79/498fc2e7e7e132bb7930a28cd075f3b3e77de3b4be5f38a9340a866f9802/dncil-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-12-12 19:09:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "mandiant",
    "github_project": "dncil",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "dncil"
}
        
Elapsed time: 0.01710s