# 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*)(¬_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*)(¬_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"
}