datolite


Namedatolite JSON
Version 1.0.6 PyPI version JSON
download
home_pageNone
SummaryComplete Binary Patcher
upload_time2024-08-01 22:24:39
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords binary reverse engineering c patching pe elf disassembly binary analysis
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Datolite

> **A modular binary patcher**

---

## Patch File Structure (.dpt)

```r
BASE HIDDEN_OFFSET START:END (FILLER?)

00 01 02 03 04 05 06 07 08
```

(Single patch file)

**EVERY VALUE IN THE FILE IS HEXADECIMAL**

```r
BASE HIDDEN_OFFSET START:END (FILLER?)

01 02 03 04 05 06 07 08

---

BASE HIDDEN_OFFSET START:END (FILLER?)

09 0A 0B 0C 0D 0E 0F 10
```

(Multi patch file)

```r
BASE HIDDEN_OFFSET START:END (FILLER?)

$ data/message.txt

```

(Including file content as bytes)

```r
BASE HIDDEN_OFFSET START:END (FILLER?)

09 0A 0B 0C 0D 0E 0F 10
>> mov rax, 0x10
```

(Instruction encoding at patch time, the architecutre is detected from the source file)

```r
BASE HIDDEN_OFFSET START:END (FILLER?)

c=> testing/test.c:main
```

(Compilation, disassembly and encoding of a C file at patch-time, format `path:function`)

#### ! SPACES AND DASHES ARE IMPORTANT AS THERE ISN'T A LEXER SO THE PARSING IS DONE WITH REGEX!

---

### Explaination

**BASE** = _Virtual Offset, `0x100000` by convention_

**HIDDEN_OFFSET** = _Win32/64 executables have a `0xC00` offset from base_

**START** = _Start address of the VIRTUAL memory region to map (gather via disassembler)_

**END** = _End address of the VIRTUAL memory region to map (gather via disassembler)_

**FILLER** = _Optional value that is going to be put to fill the region, `0x90` is the default as it is NOP instruction_

**(In case of instructions the end is always the address of the instruction after the region)**

---

## Root Config File (.dls)

When patching an executable without scripting the process you have to use `root.dls`

**Just JSON without comments**

```json
{
  "executable": "testing/test",
  "output": "patched_test",
  "patches": ["testing/stringPatch.dpt"]
}
```

**(Output is optional, if not set it will be `path/patched.filename`)**

## Working with C

So when using the C compilation feature you'll have problems with referencing executable functions.
To solve this issue you just have to define this macro:

```c
#define DECLARE(ADDRESS, RET_TYPE, NAME, ...) \
    typedef RET_TYPE (*NAME##_t)(__VA_ARGS__); \
    static const NAME##_t NAME = (NAME##_t)(ADDRESS);

#define RELATIVE(offset) ({ \
    void* _current_address; \
    void* _target_address = (void*)(&not_present_in_code); \
    __asm__ volatile ( \
        "lea (%%rip), %0" \
        : "=r" (_current_address) \
    ); \
    (char*)_target_address - (char*)_current_address + (offset); \
})

#define RELCALL(offset) ({ \
    void (*func)(); \
    void* _target_address = RELATIVE(offset); \
    func = (void (*)())(_target_address); \
    func(); \
})

```

**Then you can use it like this:**

```c
DECLARE(0x12345678, void, exploit_function)
DECLARE(0x87654321, int, add, int, int)

int patch_fn() {
  add(1,2);
  exploit_function();
  return 0;
}
```

### DECLARE WILL NOT WORK WITH PIE, KASLR AND SIMILIAR MITIGATIONS. USE RELATIVE INSTEAD

```c
int patch_fn() {
  int placeholder=0;
  RELCALL(+0x10);
  return 0;
}
```

This will call any instruction at `instruction_after_placeholder + 0x10`

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "datolite",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "binary, reverse engineering, C, patching, PE, ELF, disassembly, binary analysis",
    "author": null,
    "author_email": "utcq <utcq@waifu.club>",
    "download_url": "https://files.pythonhosted.org/packages/eb/63/fe3f75bcd3f4122110b0de9bca2a5b1be6cdf373937b161c7cc533b418ab/datolite-1.0.6.tar.gz",
    "platform": null,
    "description": "# Datolite\n\n> **A modular binary patcher**\n\n---\n\n## Patch File Structure (.dpt)\n\n```r\nBASE HIDDEN_OFFSET START:END (FILLER?)\n\n00 01 02 03 04 05 06 07 08\n```\n\n(Single patch file)\n\n**EVERY VALUE IN THE FILE IS HEXADECIMAL**\n\n```r\nBASE HIDDEN_OFFSET START:END (FILLER?)\n\n01 02 03 04 05 06 07 08\n\n---\n\nBASE HIDDEN_OFFSET START:END (FILLER?)\n\n09 0A 0B 0C 0D 0E 0F 10\n```\n\n(Multi patch file)\n\n```r\nBASE HIDDEN_OFFSET START:END (FILLER?)\n\n$ data/message.txt\n\n```\n\n(Including file content as bytes)\n\n```r\nBASE HIDDEN_OFFSET START:END (FILLER?)\n\n09 0A 0B 0C 0D 0E 0F 10\n>> mov rax, 0x10\n```\n\n(Instruction encoding at patch time, the architecutre is detected from the source file)\n\n```r\nBASE HIDDEN_OFFSET START:END (FILLER?)\n\nc=> testing/test.c:main\n```\n\n(Compilation, disassembly and encoding of a C file at patch-time, format `path:function`)\n\n#### ! SPACES AND DASHES ARE IMPORTANT AS THERE ISN'T A LEXER SO THE PARSING IS DONE WITH REGEX!\n\n---\n\n### Explaination\n\n**BASE** = _Virtual Offset, `0x100000` by convention_\n\n**HIDDEN_OFFSET** = _Win32/64 executables have a `0xC00` offset from base_\n\n**START** = _Start address of the VIRTUAL memory region to map (gather via disassembler)_\n\n**END** = _End address of the VIRTUAL memory region to map (gather via disassembler)_\n\n**FILLER** = _Optional value that is going to be put to fill the region, `0x90` is the default as it is NOP instruction_\n\n**(In case of instructions the end is always the address of the instruction after the region)**\n\n---\n\n## Root Config File (.dls)\n\nWhen patching an executable without scripting the process you have to use `root.dls`\n\n**Just JSON without comments**\n\n```json\n{\n  \"executable\": \"testing/test\",\n  \"output\": \"patched_test\",\n  \"patches\": [\"testing/stringPatch.dpt\"]\n}\n```\n\n**(Output is optional, if not set it will be `path/patched.filename`)**\n\n## Working with C\n\nSo when using the C compilation feature you'll have problems with referencing executable functions.\nTo solve this issue you just have to define this macro:\n\n```c\n#define DECLARE(ADDRESS, RET_TYPE, NAME, ...) \\\n    typedef RET_TYPE (*NAME##_t)(__VA_ARGS__); \\\n    static const NAME##_t NAME = (NAME##_t)(ADDRESS);\n\n#define RELATIVE(offset) ({ \\\n    void* _current_address; \\\n    void* _target_address = (void*)(&not_present_in_code); \\\n    __asm__ volatile ( \\\n        \"lea (%%rip), %0\" \\\n        : \"=r\" (_current_address) \\\n    ); \\\n    (char*)_target_address - (char*)_current_address + (offset); \\\n})\n\n#define RELCALL(offset) ({ \\\n    void (*func)(); \\\n    void* _target_address = RELATIVE(offset); \\\n    func = (void (*)())(_target_address); \\\n    func(); \\\n})\n\n```\n\n**Then you can use it like this:**\n\n```c\nDECLARE(0x12345678, void, exploit_function)\nDECLARE(0x87654321, int, add, int, int)\n\nint patch_fn() {\n  add(1,2);\n  exploit_function();\n  return 0;\n}\n```\n\n### DECLARE WILL NOT WORK WITH PIE, KASLR AND SIMILIAR MITIGATIONS. USE RELATIVE INSTEAD\n\n```c\nint patch_fn() {\n  int placeholder=0;\n  RELCALL(+0x10);\n  return 0;\n}\n```\n\nThis will call any instruction at `instruction_after_placeholder + 0x10`\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Complete Binary Patcher",
    "version": "1.0.6",
    "project_urls": {
        "Homepage": "https://gitlab.com/utcq/datolite"
    },
    "split_keywords": [
        "binary",
        " reverse engineering",
        " c",
        " patching",
        " pe",
        " elf",
        " disassembly",
        " binary analysis"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6eb4462d5593eabac0d0324d54eb8e53577dcd6c6d1ceb01001feb8bd801a4fa",
                "md5": "6cc13f5ce9fe4d7e423a1a421ac11296",
                "sha256": "dbb075367eace24e6b7683f875f51a2d1989130e83df8fb8aba82e4a78668fd4"
            },
            "downloads": -1,
            "filename": "datolite-1.0.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6cc13f5ce9fe4d7e423a1a421ac11296",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 9621,
            "upload_time": "2024-08-01T22:24:37",
            "upload_time_iso_8601": "2024-08-01T22:24:37.502297Z",
            "url": "https://files.pythonhosted.org/packages/6e/b4/462d5593eabac0d0324d54eb8e53577dcd6c6d1ceb01001feb8bd801a4fa/datolite-1.0.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "eb63fe3f75bcd3f4122110b0de9bca2a5b1be6cdf373937b161c7cc533b418ab",
                "md5": "b4776d001c5f3ef393ce1190f5f80059",
                "sha256": "471af38011268a863996c2a26813ae7aefd8f90a707aa32bd96da93f784d7834"
            },
            "downloads": -1,
            "filename": "datolite-1.0.6.tar.gz",
            "has_sig": false,
            "md5_digest": "b4776d001c5f3ef393ce1190f5f80059",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 9330,
            "upload_time": "2024-08-01T22:24:39",
            "upload_time_iso_8601": "2024-08-01T22:24:39.417201Z",
            "url": "https://files.pythonhosted.org/packages/eb/63/fe3f75bcd3f4122110b0de9bca2a5b1be6cdf373937b161c7cc533b418ab/datolite-1.0.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-01 22:24:39",
    "github": false,
    "gitlab": true,
    "bitbucket": false,
    "codeberg": false,
    "gitlab_user": "utcq",
    "gitlab_project": "datolite",
    "lcname": "datolite"
}
        
Elapsed time: 0.69552s