diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92cd8a7..1599b3c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,9 +57,10 @@ jobs: run: | python3 -m pip install --upgrade pip python3 -m pip install setuptools - - name: Build pydis + - name: Build pybddisasm run: | - cd pydis + sudo make install + cd pybddisasm python3 setup.py build cd .. diff --git a/README.md b/README.md index 21d7d6c..a31cd16 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ emulate raw binary files, and see their output. Note that this simple emulator s 5. disasmtool_lix - like disasmtool, but for Linux. -6. pydis - this is the Python binding for the bddisasm project. You will need Python 3 for this. +6. pybddisasm - this is the Python binding for the bddisasm project. You will need Python 3 for this. ## Objectives diff --git a/pybddisasm/LICENSE b/pybddisasm/LICENSE new file mode 100644 index 0000000..7652714 --- /dev/null +++ b/pybddisasm/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Bitdefender + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/pybddisasm/MANIFEST.in b/pybddisasm/MANIFEST.in new file mode 100644 index 0000000..fa60c52 --- /dev/null +++ b/pybddisasm/MANIFEST.in @@ -0,0 +1,6 @@ +# Include the README +include *.md + +# Include the license file +include LICENSE + diff --git a/pydis/README.md b/pybddisasm/README.md similarity index 60% rename from pydis/README.md rename to pybddisasm/README.md index 46ed99f..04c532f 100644 --- a/pydis/README.md +++ b/pybddisasm/README.md @@ -11,11 +11,18 @@ python3 setup.py install ## Usage -Use it by importing the pydis.disasm module: +Use it by importing the pybddisasm.disasm module: ```python -from pydis.disasm import * +from pybddisasm.bddisasm import * instr = nd_decode_ex2(buff, arch, arch, arch, vendor, current_rip) ``` +## Pip + +Use pip to install the package: + +```bash +pip install pybddisasm +``` diff --git a/pydis/_pydis/_pydis.c b/pybddisasm/_pybddisasm/_pybddisasm.c similarity index 87% rename from pydis/_pydis/_pydis.c rename to pybddisasm/_pybddisasm/_pybddisasm.c index bc7ade7..3e91162 100644 --- a/pydis/_pydis/_pydis.c +++ b/pybddisasm/_pybddisasm/_pybddisasm.c @@ -4,15 +4,16 @@ */ #define _SIGNAL_H #include -#include "pydis.h" +#include +#include "pybddisasm.h" static char module_docstring[] = "This module provides an interface for bddisasm."; -static char pydis_decode_ex_docstring[] = "Disasemble at the provided address."; -static char pydis_decode_ex2_docstring[] = "Disasemble at the provided address."; -static char pydis_decode_docstring[] = "Disasemble at the provided address."; -static char pydis_to_text_docstring[] = "Disasemble at the provided address and give back only the text."; +static char pybddisasm_decode_ex_docstring[] = "Disasemble at the provided address."; +static char pybddisasm_decode_ex2_docstring[] = "Disasemble at the provided address."; +static char pybddisasm_decode_docstring[] = "Disasemble at the provided address."; +static char pybddisasm_to_text_docstring[] = "Disasemble at the provided address and give back only the text."; static char *OperandTypeToString(ND_OPERAND_TYPE Type) @@ -128,7 +129,7 @@ static char *RoundingModeToString(ND_ROUNDING RoundingMode) } -static PyObject *_pydis_build_rex(ND_REX *rex) +static PyObject *_pybddisasm_build_rex(ND_REX *rex) { return Py_BuildValue("{s,B, s,B, s,B, s,B, s,B}", "Rex", rex->Rex, @@ -139,7 +140,7 @@ static PyObject *_pydis_build_rex(ND_REX *rex) } -static PyObject *_pydis_build_modrm(ND_MODRM *modrm) +static PyObject *_pybddisasm_build_modrm(ND_MODRM *modrm) { return Py_BuildValue("{s,B, s,B, s,B, s,B}", "ModRm", modrm->ModRm, @@ -149,7 +150,7 @@ static PyObject *_pydis_build_modrm(ND_MODRM *modrm) } -static PyObject *_pydis_build_sib(ND_SIB *sib) +static PyObject *_pybddisasm_build_sib(ND_SIB *sib) { return Py_BuildValue("{s,B, s,B, s,B, s,B}", "Sib", sib->Sib, @@ -159,7 +160,7 @@ static PyObject *_pydis_build_sib(ND_SIB *sib) } -static PyObject *_pydis_build_drex(ND_DREX *drex) +static PyObject *_pybddisasm_build_drex(ND_DREX *drex) { return Py_BuildValue("{s,B, s,B, s,B, s,B, s,B, s,B, s,B}", "Drex", drex->Drex, @@ -172,7 +173,7 @@ static PyObject *_pydis_build_drex(ND_DREX *drex) } -static PyObject *_pydis_build_op_access(ND_OPERAND_ACCESS *access) +static PyObject *_pybddisasm_build_op_access(ND_OPERAND_ACCESS *access) { return Py_BuildValue("{s,B, s,B, s,B, s,B, s,B}", "Access", access->Access, @@ -183,7 +184,7 @@ static PyObject *_pydis_build_op_access(ND_OPERAND_ACCESS *access) } -static PyObject *_pydis_build_op_flags(ND_OPERAND_FLAGS *flags) +static PyObject *_pybddisasm_build_op_flags(ND_OPERAND_FLAGS *flags) { return Py_BuildValue("{s,B, s,B, s,B, s,B}", "Flags", flags->Flags, @@ -193,7 +194,7 @@ static PyObject *_pydis_build_op_flags(ND_OPERAND_FLAGS *flags) } -static PyObject *_pydis_build_op_reg(ND_OPDESC_REGISTER *reg) +static PyObject *_pybddisasm_build_op_reg(ND_OPDESC_REGISTER *reg) { return Py_BuildValue("{s,s, s,B, s,I, s,I}", "Type", RegTypeToString(reg->Type), @@ -203,7 +204,7 @@ static PyObject *_pydis_build_op_reg(ND_OPDESC_REGISTER *reg) } -static PyObject *_pydis_build_op_memory(ND_OPDESC_MEMORY *mem) +static PyObject *_pybddisasm_build_op_memory(ND_OPDESC_MEMORY *mem) { PyObject *nd_vsib = Py_BuildValue("{s,B, s,B, s,B}", "IndexSize", mem->Vsib.IndexSize, @@ -277,19 +278,19 @@ static PyObject *_pydis_build_op_memory(ND_OPDESC_MEMORY *mem) } -static PyObject *_pydis_build_op_immediate(ND_OPDESC_IMMEDIATE *imm) +static PyObject *_pybddisasm_build_op_immediate(ND_OPDESC_IMMEDIATE *imm) { return Py_BuildValue("{s,K}", "Imm", imm->Imm); } -static PyObject *_pydis_build_op_rel_offset(ND_OPDESC_RELOFFSET *rel_offset) +static PyObject *_pybddisasm_build_op_rel_offset(ND_OPDESC_RELOFFSET *rel_offset) { return Py_BuildValue("{s,K}", "Rel", rel_offset->Rel); } -static PyObject *_pydis_build_op_address(ND_OPDESC_ADDRESS *address) +static PyObject *_pybddisasm_build_op_address(ND_OPDESC_ADDRESS *address) { return Py_BuildValue("{s,H, s,K}", "BaseSeg", address->BaseSeg, @@ -297,44 +298,44 @@ static PyObject *_pydis_build_op_address(ND_OPDESC_ADDRESS *address) } -static PyObject *_pydis_build_op_const(ND_OPDESC_CONSTANT *constant) +static PyObject *_pybddisasm_build_op_const(ND_OPDESC_CONSTANT *constant) { return Py_BuildValue("{s,K}", "Const", constant->Const); } -static PyObject *_pydis_build_operand(ND_OPERAND *operand) +static PyObject *_pybddisasm_build_operand(ND_OPERAND *operand) { - PyObject *nd_access = _pydis_build_op_access(&operand->Access); - PyObject *nd_flags = _pydis_build_op_flags(&operand->Flags); + PyObject *nd_access = _pybddisasm_build_op_access(&operand->Access); + PyObject *nd_flags = _pybddisasm_build_op_flags(&operand->Flags); PyObject *nd_operand = NULL; switch (operand->Type) { case ND_OP_REG: - nd_operand = _pydis_build_op_reg(&operand->Info.Register); + nd_operand = _pybddisasm_build_op_reg(&operand->Info.Register); break; case ND_OP_MEM: - nd_operand = _pydis_build_op_memory(&operand->Info.Memory); + nd_operand = _pybddisasm_build_op_memory(&operand->Info.Memory); break; case ND_OP_IMM: - nd_operand = _pydis_build_op_immediate(&operand->Info.Immediate); + nd_operand = _pybddisasm_build_op_immediate(&operand->Info.Immediate); break; case ND_OP_OFFS: - nd_operand = _pydis_build_op_rel_offset(&operand->Info.RelativeOffset); + nd_operand = _pybddisasm_build_op_rel_offset(&operand->Info.RelativeOffset); break; case ND_OP_ADDR: - nd_operand = _pydis_build_op_address(&operand->Info.Address); + nd_operand = _pybddisasm_build_op_address(&operand->Info.Address); break; case ND_OP_CONST: - nd_operand = _pydis_build_op_const(&operand->Info.Constant); + nd_operand = _pybddisasm_build_op_const(&operand->Info.Constant); break; case ND_OP_BANK: nd_operand = Py_BuildValue("{}"); break; default: - PyErr_SetString(PyExc_RuntimeError, "invalid operand type... Talk with @csirb to update pydis..."); + PyErr_SetString(PyExc_RuntimeError, "invalid operand type..."); Py_RETURN_NONE; } @@ -363,9 +364,9 @@ static PyObject *_pydis_build_operand(ND_OPERAND *operand) } -static PyObject *_pydis_build_operands(ND_OPERAND *operands, size_t count) +static PyObject *_pybddisasm_build_operands(ND_OPERAND *operands, size_t count) { - char op_str_format[400] = {'[', 0}; + char op_str_format[1024] = {'[', 0}; size_t last = 1; PyObject *nd_operands[ND_MAX_OPERAND] = {0}; @@ -380,7 +381,7 @@ static PyObject *_pydis_build_operands(ND_OPERAND *operands, size_t count) op_str_format[last++] = 'O'; - nd_operands[op] = _pydis_build_operand(&operands[op]); + nd_operands[op] = _pybddisasm_build_operand(&operands[op]); } op_str_format[last] = ']'; @@ -406,7 +407,7 @@ static PyObject *_pydis_build_operands(ND_OPERAND *operands, size_t count) } -static PyObject *_pydis_build_exs(INSTRUX *instr) +static PyObject *_pybddisasm_build_exs(INSTRUX *instr) { return Py_BuildValue("{" "s,B," // w @@ -443,7 +444,7 @@ static PyObject *_pydis_build_exs(INSTRUX *instr) } -static PyObject *_pydis_build_address(INSTRUX *instr) +static PyObject *_pybddisasm_build_address(INSTRUX *instr) { return Py_BuildValue("{s,I, s,H}", "Ip", instr->Address.Ip, @@ -451,7 +452,7 @@ static PyObject *_pydis_build_address(INSTRUX *instr) } -static PyObject *_pydis_build_cpuid_flag(ND_CPUID_FLAG *cpuid_flag) +static PyObject *_pybddisasm_build_cpuid_flag(ND_CPUID_FLAG *cpuid_flag) { return Py_BuildValue("{" "s,K," // Flag @@ -468,7 +469,7 @@ static PyObject *_pydis_build_cpuid_flag(ND_CPUID_FLAG *cpuid_flag) } -static PyObject *_pydis_build_flags_access(INSTRUX *instr) +static PyObject *_pybddisasm_build_flags_access(INSTRUX *instr) { return Py_BuildValue("{" "s,B," // RegAccess @@ -487,7 +488,7 @@ static PyObject *_pydis_build_flags_access(INSTRUX *instr) } -static PyObject *_pydis_build_valid_modes(ND_VALID_MODES *valid_modes) +static PyObject *_pybddisasm_build_valid_modes(ND_VALID_MODES *valid_modes) { return Py_BuildValue("{" "s,H," // Raw @@ -535,7 +536,7 @@ static PyObject *_pydis_build_valid_modes(ND_VALID_MODES *valid_modes) } -static PyObject *_pydis_build_valid_prefixes(ND_VALID_PREFIXES *valid_prefixes) +static PyObject *_pybddisasm_build_valid_prefixes(ND_VALID_PREFIXES *valid_prefixes) { return Py_BuildValue("{" "s,H," // Raw @@ -565,7 +566,7 @@ static PyObject *_pydis_build_valid_prefixes(ND_VALID_PREFIXES *valid_prefixes) } -static PyObject *_pydis_build_valid_decorators(ND_VALID_DECORATORS *valid_deorators) +static PyObject *_pybddisasm_build_valid_decorators(ND_VALID_DECORATORS *valid_deorators) { return Py_BuildValue("{" "s,H," // Raw @@ -585,27 +586,27 @@ static PyObject *_pydis_build_valid_decorators(ND_VALID_DECORATORS *valid_deorat } -static PyObject *_pydis_build_instr_dict(INSTRUX *instr, uint64_t rip) +static PyObject *_pybddisasm_build_instr_dict(INSTRUX *instr, uint64_t rip) { - PyObject *nd_rex = _pydis_build_rex(&instr->Rex); + PyObject *nd_rex = _pybddisasm_build_rex(&instr->Rex); - PyObject *nd_modrm = _pydis_build_modrm(&instr->ModRm); + PyObject *nd_modrm = _pybddisasm_build_modrm(&instr->ModRm); - PyObject *nd_sib = _pydis_build_sib(&instr->Sib); + PyObject *nd_sib = _pybddisasm_build_sib(&instr->Sib); - PyObject *nd_drex = _pydis_build_drex(&instr->Drex); + PyObject *nd_drex = _pybddisasm_build_drex(&instr->Drex); - PyObject *nd_op_array = _pydis_build_operands(instr->Operands, instr->OperandsCount); + PyObject *nd_op_array = _pybddisasm_build_operands(instr->Operands, instr->OperandsCount); - PyObject *nd_exs = _pydis_build_exs(instr); + PyObject *nd_exs = _pybddisasm_build_exs(instr); - PyObject *nd_address = _pydis_build_address(instr); + PyObject *nd_address = _pybddisasm_build_address(instr); - PyObject *nd_cpuid_flag = _pydis_build_cpuid_flag(&instr->CpuidFlag); + PyObject *nd_cpuid_flag = _pybddisasm_build_cpuid_flag(&instr->CpuidFlag); - PyObject *nd_valid_modes = _pydis_build_valid_modes(&instr->ValidModes); - PyObject *nd_valid_prefixes = _pydis_build_valid_prefixes(&instr->ValidPrefixes); - PyObject *nd_valid_decorators = _pydis_build_valid_decorators(&instr->ValidDecorators); + PyObject *nd_valid_modes = _pybddisasm_build_valid_modes(&instr->ValidModes); + PyObject *nd_valid_prefixes = _pybddisasm_build_valid_prefixes(&instr->ValidPrefixes); + PyObject *nd_valid_decorators = _pybddisasm_build_valid_decorators(&instr->ValidDecorators); char instr_text[ND_MIN_BUF_SIZE] = {0}; NDSTATUS status = nd_to_text(instr, rip, sizeof(instr_text), instr_text); @@ -614,7 +615,7 @@ static PyObject *_pydis_build_instr_dict(INSTRUX *instr, uint64_t rip) strcpy(instr_text, ""); } - PyObject *nd_flags_access = _pydis_build_flags_access(instr); + PyObject *nd_flags_access = _pybddisasm_build_flags_access(instr); PyObject *p = Py_BuildValue("{" "s,B," // DefCode @@ -906,7 +907,7 @@ static PyObject *_pydis_build_instr_dict(INSTRUX *instr, uint64_t rip) } -static uint8_t _pydis_py_code_to_disasm(uint8_t code) +static uint8_t _pybddisasm_py_code_to_disasm(uint8_t code) { if (16 == code) { @@ -926,7 +927,7 @@ static uint8_t _pydis_py_code_to_disasm(uint8_t code) } -static uint8_t _pydis_py_data_to_disasm(uint8_t data) +static uint8_t _pybddisasm_py_data_to_disasm(uint8_t data) { if (16 == data) { @@ -946,7 +947,7 @@ static uint8_t _pydis_py_data_to_disasm(uint8_t data) } -static uint8_t _pydis_py_stack_to_disasm(uint8_t stack) +static uint8_t _pybddisasm_py_stack_to_disasm(uint8_t stack) { if (16 == stack) { @@ -966,7 +967,7 @@ static uint8_t _pydis_py_stack_to_disasm(uint8_t stack) } -static PyObject *pydis_decode_ex(PyObject *self, PyObject *args) +static PyObject *pybddisasm_decode_ex(PyObject *self, PyObject *args) { char *buf = NULL; Py_ssize_t bufsize = 0; @@ -981,8 +982,8 @@ static PyObject *pydis_decode_ex(PyObject *self, PyObject *args) Py_RETURN_NONE; } - code = _pydis_py_code_to_disasm(code); - data = _pydis_py_data_to_disasm(data); + code = _pybddisasm_py_code_to_disasm(code); + data = _pybddisasm_py_data_to_disasm(data); if (PyErr_Occurred()) { @@ -997,11 +998,11 @@ static PyObject *pydis_decode_ex(PyObject *self, PyObject *args) Py_RETURN_NONE; } - return _pydis_build_instr_dict(&instr, rip); + return _pybddisasm_build_instr_dict(&instr, rip); } -static PyObject *pydis_decode_ex2(PyObject *self, PyObject *args) +static PyObject *pybddisasm_decode_ex2(PyObject *self, PyObject *args) { char *buf = NULL; char *str_vend = NULL; @@ -1043,9 +1044,9 @@ static PyObject *pydis_decode_ex2(PyObject *self, PyObject *args) Py_RETURN_NONE; } - code = _pydis_py_code_to_disasm(code); - data = _pydis_py_data_to_disasm(data); - stack = _pydis_py_stack_to_disasm(stack); + code = _pybddisasm_py_code_to_disasm(code); + data = _pybddisasm_py_data_to_disasm(data); + stack = _pybddisasm_py_stack_to_disasm(stack); if (PyErr_Occurred()) { @@ -1060,11 +1061,11 @@ static PyObject *pydis_decode_ex2(PyObject *self, PyObject *args) Py_RETURN_NONE; } - return _pydis_build_instr_dict(&instr, rip); + return _pybddisasm_build_instr_dict(&instr, rip); } -static PyObject *pydis_to_text(PyObject *self, PyObject *args) +static PyObject *pybddisasm_to_text(PyObject *self, PyObject *args) { char *buf = NULL; Py_ssize_t bufsize = 0; @@ -1079,8 +1080,8 @@ static PyObject *pydis_to_text(PyObject *self, PyObject *args) Py_RETURN_NONE; } - code = _pydis_py_code_to_disasm(code); - data = _pydis_py_data_to_disasm(data); + code = _pybddisasm_py_code_to_disasm(code); + data = _pybddisasm_py_data_to_disasm(data); if (PyErr_Occurred()) { @@ -1108,24 +1109,26 @@ static PyObject *pydis_to_text(PyObject *self, PyObject *args) static PyMethodDef module_methods[] = { - {"nd_decode_ex", pydis_decode_ex, METH_VARARGS, pydis_decode_ex_docstring}, - {"nd_decode_ex2", pydis_decode_ex2, METH_VARARGS, pydis_decode_ex2_docstring}, - {"nd_decode", pydis_decode_ex, METH_VARARGS, pydis_decode_docstring}, - {"nd_to_text", pydis_to_text, METH_VARARGS, pydis_to_text_docstring}, + {"nd_decode_ex", pybddisasm_decode_ex, METH_VARARGS, pybddisasm_decode_ex_docstring}, + {"nd_decode_ex2", pybddisasm_decode_ex2, METH_VARARGS, pybddisasm_decode_ex2_docstring}, + {"nd_decode", pybddisasm_decode_ex, METH_VARARGS, pybddisasm_decode_docstring}, + {"nd_to_text", pybddisasm_to_text, METH_VARARGS, pybddisasm_to_text_docstring}, {NULL, NULL, 0, NULL} }; -static struct PyModuleDef PyDis = +static struct PyModuleDef pybddisasm = { PyModuleDef_HEAD_INIT, - "pydis", // name of module + "pybddisasm", // name of module module_docstring, -1, // size of per-interpreter state of the module, or -1 if the module keeps state in global variables module_methods }; -PyMODINIT_FUNC PyInit__pydis(void) +PyMODINIT_FUNC PyInit__pybddisasm(void) { - return PyModule_Create(&PyDis); + static_assert(sizeof(INSTRUX) == LIBRARY_INSTRUX_SIZE, "The size of INSTRUX is not compatible with pybddisasm!"); + + return PyModule_Create(&pybddisasm); } diff --git a/pydis/_pydis/pydis.c b/pybddisasm/_pybddisasm/pybddisasm.c similarity index 97% rename from pydis/_pydis/pydis.c rename to pybddisasm/_pybddisasm/pybddisasm.c index 46e0cf6..e76efef 100644 --- a/pydis/_pydis/pydis.c +++ b/pybddisasm/_pybddisasm/pybddisasm.c @@ -2,7 +2,7 @@ * Copyright (c) 2020 Bitdefender * SPDX-License-Identifier: Apache-2.0 */ -#include "pydis.h" +#include "pybddisasm.h" #include diff --git a/pydis/_pydis/pydis.h b/pybddisasm/_pybddisasm/pybddisasm.h similarity index 86% rename from pydis/_pydis/pydis.h rename to pybddisasm/_pybddisasm/pybddisasm.h index e10c380..c28141e 100644 --- a/pydis/_pydis/pydis.h +++ b/pybddisasm/_pybddisasm/pybddisasm.h @@ -2,8 +2,8 @@ * Copyright (c) 2020 Bitdefender * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _PYDIS_H_ -#define _PYDIS_H_ +#ifndef _PYBDDISASM_H_ +#define _PYBDDISASM_H_ #include #include @@ -17,4 +17,4 @@ int nd_decode_ex2(INSTRUX *instrux, void *code, size_t size, int def_code, int d int nd_to_text(INSTRUX *instrux, size_t rip, size_t bufsize, char *buf); -#endif // _PYDIS_H_ +#endif // _PYBDDISASM_H_ diff --git a/pybddisasm/pybddisasm/__init__.py b/pybddisasm/pybddisasm/__init__.py new file mode 100644 index 0000000..0a59b28 --- /dev/null +++ b/pybddisasm/pybddisasm/__init__.py @@ -0,0 +1,7 @@ +# +# Copyright (c) 2020 Bitdefender +# SPDX-License-Identifier: Apache-2.0 +# +from pybddisasm.bddisasm import NdInstruction, nd_decode, nd_decode_ex, nd_decode_ex2, nd_to_text + +from pybddisasm.helpers import disassemble_file, disassemble_hexstring, print_instruction diff --git a/pydis/pydis/__main__.py b/pybddisasm/pybddisasm/__main__.py similarity index 83% rename from pydis/pydis/__main__.py rename to pybddisasm/pybddisasm/__main__.py index 080dbd2..8bbc5c4 100644 --- a/pydis/pydis/__main__.py +++ b/pybddisasm/pybddisasm/__main__.py @@ -4,7 +4,7 @@ # """Early initialization and main entry point.""" -from pydis.core import main +from pybddisasm.core import main if __name__ == "__main__": main() diff --git a/pydis/pydis/app.py b/pybddisasm/pybddisasm/app.py similarity index 88% rename from pydis/pydis/app.py rename to pybddisasm/pybddisasm/app.py index e14e798..bf363a2 100644 --- a/pydis/pydis/app.py +++ b/pybddisasm/pybddisasm/app.py @@ -2,8 +2,8 @@ # Copyright (c) 2020 Bitdefender # SPDX-License-Identifier: Apache-2.0 # -from pydis.disasm import * -from pydis.helpers import * +from pybddisasm.bddisasm import * +from pybddisasm.helpers import * def run(args): diff --git a/pydis/pydis/disasm.py b/pybddisasm/pybddisasm/bddisasm.py similarity index 82% rename from pydis/pydis/disasm.py rename to pybddisasm/pybddisasm/bddisasm.py index 92f20ce..13b8bca 100644 --- a/pydis/pydis/disasm.py +++ b/pybddisasm/pybddisasm/bddisasm.py @@ -4,7 +4,7 @@ # """Interface for disassembling code.""" -import _pydis +import _pybddisasm class NdInstruction(dict): """Magic wrapper around a dictionary, that makes all the keys available @@ -34,14 +34,14 @@ def nd_to_text(code, arch_code_size, arch_data_size=0, rip=0): if not arch_data_size: arch_data_size = arch_code_size - return _pydis.nd_to_text(code, arch_code_size, arch_data_size, rip) + return _pybddisasm.nd_to_text(code, arch_code_size, arch_data_size, rip) def nd_decode(code, arch_code_size, arch_data_size=0, rip=0): if not arch_data_size: arch_data_size = arch_code_size - instruction = _pydis.nd_decode_ex(code, arch_code_size, arch_data_size, rip) + instruction = _pybddisasm.nd_decode_ex(code, arch_code_size, arch_data_size, rip) if not instruction: return None @@ -53,7 +53,7 @@ def nd_decode_ex(code, arch_code_size, arch_data_size=0, rip=0): if not arch_data_size: arch_data_size = arch_code_size - instruction = _pydis.nd_decode_ex(code, arch_code_size, arch_data_size, rip) + instruction = _pybddisasm.nd_decode_ex(code, arch_code_size, arch_data_size, rip) if not instruction: return None @@ -61,8 +61,8 @@ def nd_decode_ex(code, arch_code_size, arch_data_size=0, rip=0): return NdInstruction(instruction) -def nd_decode_ex2(code, arch_code_size, arch_data_size, arch_stack_size, vendor, rip=0): - instruction = _pydis.nd_decode_ex2(code, arch_code_size, arch_data_size, +def nd_decode_ex2(code, arch_code_size, arch_data_size, arch_stack_size, vendor='intel', rip=0): + instruction = _pybddisasm.nd_decode_ex2(code, arch_code_size, arch_data_size, arch_stack_size, vendor, rip) if not instruction: diff --git a/pydis/pydis/core.py b/pybddisasm/pybddisasm/core.py similarity index 94% rename from pydis/pydis/core.py rename to pybddisasm/pybddisasm/core.py index ff92e98..0d57793 100644 --- a/pydis/pydis/core.py +++ b/pybddisasm/pybddisasm/core.py @@ -6,7 +6,7 @@ import sys import argparse -import pydis +import pybddisasm def _auto_int(x): @@ -15,7 +15,7 @@ def _auto_int(x): def _get_argparser(): """Get the argpase parser.""" - parser = argparse.ArgumentParser(prog='pydis') + parser = argparse.ArgumentParser(prog='pybddisasm') parser.add_argument('-b', '--arch', choices=[16, 32, 64], default=64, type=int) @@ -48,5 +48,5 @@ def main(): parser.print_usage() return 1 - from pydis import app + from pybddisasm import app app.run(args) diff --git a/pydis/pydis/helpers.py b/pybddisasm/pybddisasm/helpers.py similarity index 99% rename from pydis/pydis/helpers.py rename to pybddisasm/pybddisasm/helpers.py index 32b0164..7812f44 100644 --- a/pydis/pydis/helpers.py +++ b/pybddisasm/pybddisasm/helpers.py @@ -5,7 +5,7 @@ import os import sys -from pydis.disasm import * +from pybddisasm.bddisasm import * try: from termcolor import colored diff --git a/pybddisasm/setup.cfg b/pybddisasm/setup.cfg new file mode 100644 index 0000000..8183238 --- /dev/null +++ b/pybddisasm/setup.cfg @@ -0,0 +1,2 @@ +[metadata] +license_files = LICENSE diff --git a/pybddisasm/setup.py b/pybddisasm/setup.py new file mode 100644 index 0000000..69d9d5c --- /dev/null +++ b/pybddisasm/setup.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# +# Copyright (c) 2020 Bitdefender +# SPDX-License-Identifier: Apache-2.0 +# + +import os +import sys +import re + +from setuptools import find_packages, setup, Command, Extension, Distribution +from codecs import open + +VERSION = (0, 1, 2) +LIBRARY_VERSION = (1, 28, 0) +LIBRARY_INSTRUX_SIZE = 856 + +packages = ['pybddisasm'] +requires = ['setuptools'] +here = os.path.abspath(os.path.dirname(__file__)) + +def _check_library_version(): + version_header = '../inc/version.h' + with open(version_header, 'r') as file: + data = file.read() + + major = re.search(r'(?<=\bDISASM_VERSION_MAJOR).*(\d+)', data) + if not major: + print('error: Major version not found!') + sys.exit(1) + + minor = re.search(r'(?<=\bDISASM_VERSION_MINOR).*(\d+)', data) + if not minor: + print('error: Minor version not found!') + sys.exit(1) + + revision = re.search(r'(?<=\bDISASM_VERSION_REVISION).*(\d+)', data) + if not revision: + print('error: Revision version not found!') + sys.exit(1) + + major = major.group(0).strip() + minor = minor.group(0).strip() + revision = revision.group(0).strip() + + if int(major) != LIBRARY_VERSION[0] or int(minor) != LIBRARY_VERSION[1] or int(revision) != LIBRARY_VERSION[2]: + print('error: The version of the library is not compatible with the pybddisasm!') + print('error: Library : %s.%s.%s - pybddisasm : %d.%d.%d' % (major, minor, revision, LIBRARY_VERSION[0], + LIBRARY_VERSION[1], LIBRARY_VERSION[2])) + sys.exit(1) + +_check_library_version() + +with open('README.md', 'r', 'utf-8') as f: + readme = f.read() + +class BinaryDistribution(Distribution): + def has_ext_modules(arg): + return True + + def is_pure(self): + return False + +setup( + name="pybddisasm", + version='.'.join(map(str, VERSION)), + author="Bitdefender", + description="The Bitdefender disassembler Python wrapper", + long_description = readme, + long_description_content_type = "text/markdown", + url = "https://github.com/bitdefender/bddisasm", + packages=packages, + license="Apache Software License", + package_data={'': ['LICENSE', 'NOTICE'], 'pybddisasm': ['*.pem']}, + package_dir={'pybddisasm': 'pybddisasm'}, + platforms = ["Windows", "Linux"], + include_package_data=True, + python_requires=">=3.4", + setup_requires=['wheel'], + install_requires=requires, + zip_safe=False, + classifiers=[ + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: OS Independent', + ], + ext_modules = [Extension("_pybddisasm", + sources = ["_pybddisasm/_pybddisasm.c", "_pybddisasm/pybddisasm.c"], + define_macros = [('AMD64', None), ('Py_LIMITED_API', None), ('LIBRARY_INSTRUX_SIZE', LIBRARY_INSTRUX_SIZE)], + include_dirs = ['../inc'], + libraries = ['bddisasm'], + library_dirs = ['/usr/local/lib', '../bin/x64/Release'], + py_limited_api=True)], + distclass=BinaryDistribution +) diff --git a/pydis/pydis/__init__.py b/pydis/pydis/__init__.py deleted file mode 100644 index d494aa2..0000000 --- a/pydis/pydis/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright (c) 2020 Bitdefender -# SPDX-License-Identifier: Apache-2.0 -# -from pydis.disasm import NdInstruction, nd_decode, nd_decode_ex, nd_decode_ex2, nd_to_text - -from pydis.helpers import disassemble_file, disassemble_hexstring, print_instruction diff --git a/pydis/pydis/__version__.py b/pydis/pydis/__version__.py deleted file mode 100644 index 5d82b77..0000000 --- a/pydis/pydis/__version__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2020 Bitdefender -# SPDX-License-Identifier: Apache-2.0 -# -VERSION = (0, 0, 1) - -__title__ = 'pydis' -__description__ = 'Python Disassembler' -__version__ = '.'.join(map(str, VERSION)) diff --git a/pydis/setup.py b/pydis/setup.py deleted file mode 100644 index d14e72b..0000000 --- a/pydis/setup.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (c) 2020 Bitdefender -# SPDX-License-Identifier: Apache-2.0 -# - -import os - -from codecs import open - -from setuptools import find_packages, setup, Command, Extension - -here = os.path.abspath(os.path.dirname(__file__)) - -packages = ['pydis'] - -requires = [ - "setuptools" -] - -about = {} -with open(os.path.join(here, 'pydis', '__version__.py'), 'r', 'utf-8') as f: - exec(f.read(), about) - -with open('README.md', 'r', 'utf-8') as f: - readme = f.read() - -setup( - name=about['__title__'], - version=about['__version__'], - packages=packages, - package_data={'': ['LICENSE', 'NOTICE'], 'pydis': ['*.pem']}, - package_dir={'pydis': 'pydis'}, - include_package_data=True, - python_requires=">=3.4", - setup_requires=['wheel'], - install_requires=requires, - zip_safe=False, - classifiers=[ - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: Implementation :: CPython', - 'Programming Language :: Python :: Implementation :: PyPy' - ], - ext_modules = [Extension("_pydis", - sources = ["_pydis/_pydis.c", "_pydis/pydis.c"], - define_macros = [('AMD64', None), ('PYDIS_BUILD', None)], - include_dirs = ['../inc'], - libraries = ['bddisasm'], - library_dirs = ['../bin/x64/Release'])] -)