### Install pybcj using pip Source: https://github.com/miurahr/pybcj/blob/main/README.rst Install the pybcj package using the standard Python package installer. ```bash pip install pybcj ``` -------------------------------- ### Install pybcj using conda Source: https://github.com/miurahr/pybcj/blob/main/README.rst Install the pybcj package from the conda-forge channel using the conda package manager. ```bash conda install -c conda-forge pybcj ``` -------------------------------- ### CMake: Create Virtual Environment Source: https://github.com/miurahr/pybcj/blob/main/CMakeLists.txt Defines a custom CMake target 'venv.stamp' to create a Python virtual environment and install dependencies from requirements.txt. This ensures a consistent testing environment. ```cmake file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/requirements.txt "\nhypothesis\npytest>=6.0\n") if (WIN32) set(PIP_COMMAND ${VENV_PATH}/Scripts/pip.exe) else() set(PIP_COMMAND ${VENV_PATH}/bin/pip) endif() add_custom_target( venv.stamp BYPRODUCTS venv.stamp COMMAND ${Python_EXECUTABLE} -m venv ${VENV_PATH} COMMAND ${PIP_COMMAND} install -r ${CMAKE_BINARY_DIR}/requirements.txt COMMAND ${CMAKE_COMMAND} -E touch venv.stamp) ``` -------------------------------- ### Encode x86/x86_64 Binary Data with BCJEncoder Source: https://context7.com/miurahr/pybcj/llms.txt Applies the BCJ filter to x86/x86_64 machine code. Use this to transform relative branch addresses into absolute ones for better LZMA compression. Call flush() to get remaining data. ```python import bcj import hashlib # Read executable binary data with open("executable.bin", "rb") as f: binary_data = f.read() # Create encoder and process data at once encoder = bcj.BCJEncoder() encoded_data = encoder.encode(binary_data) encoded_data += encoder.flush() # Verify the encoding print(f"Original size: {len(binary_data)}") print(f"Encoded size: {len(encoded_data)}") print(f"SHA256: {hashlib.sha256(encoded_data).hexdigest()}") # Chunked encoding for large files BLOCKSIZE = 8192 encoder = bcj.BCJEncoder() output = bytearray() with open("large_executable.bin", "rb") as f: while True: chunk = f.read(BLOCKSIZE) if not chunk: break output += encoder.encode(chunk) output += encoder.flush() ``` -------------------------------- ### CMakeLists.txt: Project Configuration Source: https://github.com/miurahr/pybcj/blob/main/CMakeLists.txt Sets up the C++ standard, Python version, and virtual environment path for the Pybcj project. Configures build options for Python extension modules. ```cmake cmake_minimum_required(VERSION 3.19) project(pybcj C CXX) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) # TARGET PYTHON version set(PY_VERSION 3.12) set(Python_FIND_IMPLEMENTATIONS CPython) set(VENV_PATH "${CMAKE_BINARY_DIR}/venv") set(DEBUG_BUILD ON) # ################################################################################################## # Configuration for python-ext set(Python_FIND_STRATEGY VERSION) find_package(Python ${PY_VERSION}.0...${PY_VERSION}.99 COMPONENTS Interpreter Development) set(PY_EXT_FILE _bcj) set(PY_EXT_DIR src/bcj) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/get_ext.py "import sysconfig\nprint(sysconfig.get_config_var('EXT_SUFFIX'))\n") execute_process( COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/get_ext.py OUTPUT_VARIABLE PY_EXT_EXT OUTPUT_STRIP_TRAILING_WHITESPACE) set(PY_EXT ${PY_EXT_DIR}/${PY_EXT_FILE}.${PY_EXT_EXT}) set(PY_CFFI ${PY_CFFI_DIR}/PY_CFFI_FILE}.${PY_EXT_EXT}) # bulid ext by setup.py if (WIN32) if(DEBUG_BUILD) set(BUILD_EXT_PYTHON ${VENV_PATH}/Scripts/python_d.exe) else() set(BUILD_EXT_PYTHON ${VENV_PATH}/Scripts/python.exe) endif() set(BUILD_EXT_OPTION) else() set(BUILD_EXT_PYTHON ${VENV_PATH}/bin/python) set(BUILD_EXT_OPTION --warning-as-error) endif() set(pybcj_sources src/ext/Bra.c src/ext/Bra86.c src/ext/BraIA64.c) set(pybcj_ext_src src/ext/_bcjmodule.c) add_custom_target( generate_ext BYPRODUCTS ${PY_EXT} COMMAND ${BUILD_EXT_PYTHON} setup.py build_ext ${BUILD_EXT_OPTION} --inplace WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS venv.stamp SOURCES ${pybcj_sources} ${pybcj_ext_src}) add_library(_pybcj_ext MODULE ${pybcj_sources} ${pybcj_ext_src}) target_include_directories(_pybcj_ext PRIVATE ${Python_INCLUDE_DIRS} src/ext) target_link_libraries(_pybcj_ext PRIVATE ${Python_LIBRARIES}) # ################################################################################################## # create virtualenv file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/requirements.txt "\nhypothesis\npytest>=6.0\n") if (WIN32) set(PIP_COMMAND ${VENV_PATH}/Scripts/pip.exe) else() set(PIP_COMMAND ${VENV_PATH}/bin/pip) endif() add_custom_target( venv.stamp BYPRODUCTS venv.stamp COMMAND ${Python_EXECUTABLE} -m venv ${VENV_PATH} COMMAND ${PIP_COMMAND} install -r ${CMAKE_BINARY_DIR}/requirements.txt COMMAND ${CMAKE_COMMAND} -E touch venv.stamp) set(SRC_PATH "${CMAKE_SOURCE_DIR}/src") set(VPKG_PATH_A "${VENV_PATH}/lib/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages/") set(VPKG_PATH_B "${VENV_PATH}/Lib/site-packages/") set(VPKG_PATH_C "${CMAKE_BINARY_DIR}") # ################################################################################################## # For pytest file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/pytest_runner.cpp "\n#include \n#include \n#include \nint main(int argc, char **argv) {\n std::string args;\n if ( argc > 1) {\n args.append(\"[\");\n for (int i = 1; i < argc; i++) {\n if (i > 2)\n args.append(\",\");\n args.append(\"\\\"");\n args.append(argv[i]);\n args.append(\"\\\"");\n }\n args.append(\"]\");\n }\n std::filesystem::path src_path = \"${SRC_PATH}\";\n std::filesystem::path vsite_path_a = \"${VPKG_PATH_A}\";\n std::filesystem::path vsite_path_b = \"${VPKG_PATH_B}\";\n std::filesystem::path vsite_path_c = \"${VPKG_PATH_C}\";\n std::string pycode =\n \"import sys\\n\"\n \"sys.path.append('\\ ``` -------------------------------- ### Complete Encode-Decode Pipeline with LZMA and pybcj Source: https://context7.com/miurahr/pybcj/llms.txt Demonstrates a full compression pipeline using pybcj for BCJ filtering followed by LZMA compression, and the corresponding decompression process. Requires 'myapp.exe' to exist. ```python import bcj import lzma import os def compress_executable(input_path, output_path): """Compress an executable using BCJ + LZMA pipeline.""" with open(input_path, "rb") as f: original = f.read() # Step 1: Apply BCJ filter encoder = bcj.BCJEncoder() bcj_filtered = encoder.encode(original) bcj_filtered += encoder.flush() # Step 2: Compress with LZMA compressed = lzma.compress(bcj_filtered, preset=9) # Save compressed data with size header with open(output_path, "wb") as f: f.write(len(bcj_filtered).to_bytes(8, 'little')) f.write(compressed) ratio = len(compressed) / len(original) * 100 print(f"Compressed: {len(original)} -> {len(compressed)} bytes ({ratio:.1f}%)") return compressed def decompress_executable(input_path, output_path): """Decompress a BCJ + LZMA compressed executable.""" with open(input_path, "rb") as f: bcj_size = int.from_bytes(f.read(8), 'little') compressed = f.read() # Step 1: Decompress LZMA bcj_filtered = lzma.decompress(compressed) # Step 2: Reverse BCJ filter decoder = bcj.BCJDecoder(bcj_size) original = decoder.decode(bcj_filtered) with open(output_path, "wb") as f: f.write(original) print(f"Decompressed: {len(compressed)} -> {len(original)} bytes") return original # Usage compress_executable("myapp.exe", "myapp.exe.bcjlzma") decompress_executable("myapp.exe.bcjlzma", "myapp_restored.exe") ``` -------------------------------- ### Encode and Decode PowerPC Binary with pybcj Source: https://context7.com/miurahr/pybcj/llms.txt Demonstrates encoding and decoding of a PowerPC binary using pybcj. Requires the binary file to be present. ```python import bcj import hashlib # Encode PowerPC binary with open("lib/powerpc64le-linux-gnu/liblzma.so.0", "rb") as f: ppc_binary = f.read() encoder = bcj.PPCEncoder() encoded = encoder.encode(ppc_binary) encoded += encoder.flush() print(f"PPC binary encoded: {len(ppc_binary)} -> {len(encoded)} bytes") print(f"SHA256: {hashlib.sha256(encoded).hexdigest()}") # Decode PowerPC binary decoder = bcj.PPCDecoder(len(encoded)) decoded = decoder.decode(encoded) assert decoded == ppc_binary, "PPC round-trip failed!" ``` -------------------------------- ### Encode and Decode IA64 Binary with pybcj Source: https://context7.com/miurahr/pybcj/llms.txt Illustrates encoding and decoding of an IA64 binary using pybcj. Make sure 'ia64_binary.bin' is available. ```python import bcj # Encode IA64 binary with open("ia64_binary.bin", "rb") as f: ia64_data = f.read() encoder = bcj.IA64Encoder() encoded = encoder.encode(ia64_data) encoded += encoder.flush() # Decode IA64 binary decoder = bcj.IA64Decoder(len(encoded)) decoded = decoder.decode(encoded) print(f"IA64: {len(ia64_data)} bytes, round-trip: {decoded == ia64_data}") ``` -------------------------------- ### Encode and Decode SPARC Binary with pybcj Source: https://context7.com/miurahr/pybcj/llms.txt Shows how to encode and decode a SPARC binary using pybcj. Ensure 'sparc_binary.bin' exists. ```python import bcj # Encode SPARC binary with open("sparc_binary.bin", "rb") as f: sparc_data = f.read() encoder = bcj.SparcEncoder() encoded = encoder.encode(sparc_data) encoded += encoder.flush() # Decode SPARC binary decoder = bcj.SparcDecoder(len(encoded)) decoded = decoder.decode(encoded) print(f"SPARC: {len(sparc_data)} bytes, round-trip: {decoded == sparc_data}") ``` -------------------------------- ### Encode and Decode ARM Thumb Binaries with ARMTEncoder/ARMTDecoder Source: https://context7.com/miurahr/pybcj/llms.txt Handles BCJ filtering for ARM Thumb instruction set binaries. Uses a different transformation algorithm than standard ARM due to 16-bit compressed instructions. Verifies round-trip integrity. ```python import bcj # Encode ARM Thumb binary with open("thumb_binary.bin", "rb") as f: thumb_data = f.read() encoder = bcj.ARMTEncoder() encoded = encoder.encode(thumb_data) encoded += encoder.flush() # Decode ARM Thumb binary decoder = bcj.ARMTDecoder(len(encoded)) decoded = decoder.decode(encoded) print(f"ARM Thumb: {len(thumb_data)} bytes processed") assert decoded == thumb_data, "Round-trip verification failed" ``` -------------------------------- ### ARMTEncoder / ARMTDecoder - ARM Thumb Mode Filter Source: https://context7.com/miurahr/pybcj/llms.txt Handles BCJ filtering for ARM Thumb instruction set binaries. Thumb uses 16-bit compressed instructions and requires a different transformation algorithm. ```APIDOC ## ARMTEncoder / ARMTDecoder - ARM Thumb Mode Filter ### Description Handles BCJ filtering for ARM Thumb instruction set binaries. ARM Thumb uses 16-bit compressed instructions and requires a different transformation algorithm than standard ARM. ### Method `ARMTEncoder.encode(data: bytes) -> bytes` `ARMTEncoder.flush() -> bytes` `ARMTDecoder.__init__(total_size: int)` `ARMTDecoder.decode(data: bytes) -> bytes` ### Parameters #### Request Body (for encode method) - **data** (bytes) - Required - The ARM Thumb binary data to encode. #### Path Parameters (for ARMTDecoder constructor) - **total_size** (int) - Required - The total size of the encoded ARM Thumb data. #### Request Body (for decode method) - **data** (bytes) - Required - The BCJ-encoded ARM Thumb data to decode. ### Request Example (Encoding) ```python import bcj with open("thumb_binary.bin", "rb") as f: thumb_data = f.read() encoder = bcj.ARMTEncoder() encoded = encoder.encode(thumb_data) encoded += encoder.flush() ``` ### Response Example (Encoding) ```json { "encoded_data": "base64_encoded_binary_string" } ``` ### Request Example (Decoding) ```python import bcj encoded_data = b'your_encoded_thumb_data' total_size = len(encoded_data) decoder = bcj.ARMTDecoder(total_size) decoded = decoder.decode(encoded_data) ``` ### Response Example (Decoding) ```json { "decoded_data": "base64_encoded_binary_string" } ``` ``` -------------------------------- ### Encode and Decode PowerPC Binaries with PPCEncoder/PPCDecoder Source: https://context7.com/miurahr/pybcj/llms.txt Implements BCJ filtering for PowerPC (PPC) architecture binaries, including PowerPC64. Transforms branch instructions in big-endian PPC machine code. ```python import bcj import hashlib ``` -------------------------------- ### PPCEncoder / PPCDecoder - PowerPC Architecture Filter Source: https://context7.com/miurahr/pybcj/llms.txt Implements BCJ filtering for PowerPC (PPC) architecture binaries, including PowerPC64. These filters transform branch instructions in big-endian PPC machine code. ```APIDOC ## PPCEncoder / PPCDecoder - PowerPC Architecture Filter ### Description Implements BCJ filtering for PowerPC (PPC) architecture binaries, including PowerPC64. These filters transform branch instructions in big-endian PPC machine code. ### Method `PPCEncoder.encode(data: bytes) -> bytes` `PPCEncoder.flush() -> bytes` `PPCDecoder.__init__(total_size: int)` `PPCDecoder.decode(data: bytes) -> bytes` ### Parameters #### Request Body (for encode method) - **data** (bytes) - Required - The PowerPC binary data to encode. #### Path Parameters (for PPCDecoder constructor) - **total_size** (int) - Required - The total size of the encoded PowerPC data. #### Request Body (for decode method) - **data** (bytes) - Required - The BCJ-encoded PowerPC data to decode. ### Request Example (Encoding) ```python import bcj with open("ppc_binary.bin", "rb") as f: ppc_binary = f.read() encoder = bcj.PPCEncoder() encoded = encoder.encode(ppc_binary) encoded += encoder.flush() ``` ### Response Example (Encoding) ```json { "encoded_data": "base64_encoded_binary_string" } ``` ### Request Example (Decoding) ```python import bcj encoded_data = b'your_encoded_ppc_data' total_size = len(encoded_data) decoder = bcj.PPCDecoder(total_size) decoded = decoder.decode(encoded_data) ``` ### Response Example (Decoding) ```json { "decoded_data": "base64_encoded_binary_string" } ``` ``` -------------------------------- ### Encode and Decode ARM Binaries with ARMEncoder/ARMDecoder Source: https://context7.com/miurahr/pybcj/llms.txt Applies BCJ filtering for ARM architecture binaries (including ARM64/AArch64). Useful for compressing ARM executables and shared libraries. Verifies round-trip integrity. ```python import bcj import hashlib # Encode ARM binary with open("liblzma.so.0", "rb") as f: arm_binary = f.read() encoder = bcj.ARMEncoder() encoded = encoder.encode(arm_binary) encoded += encoder.flush() print(f"ARM binary encoded: {len(arm_binary)} -> {len(encoded)} bytes") print(f"SHA256: {hashlib.sha256(encoded).hexdigest()}") # Decode ARM binary decoder = bcj.ARMDecoder(len(encoded)) decoded = decoder.decode(encoded) # Verify round-trip assert decoded == arm_binary, "Round-trip failed!" print("ARM encode/decode round-trip successful") ``` -------------------------------- ### ARMEncoder / ARMDecoder - ARM Architecture Filter Source: https://context7.com/miurahr/pybcj/llms.txt Applies BCJ filtering for ARM architecture binaries (including ARM64/AArch64). Useful for compressing ARM executables and shared libraries. ```APIDOC ## ARMEncoder / ARMDecoder - ARM Architecture Filter ### Description Applies BCJ filtering for ARM architecture binaries (including ARM64/AArch64). These are useful when compressing ARM executables and shared libraries for better LZMA compression results. ### Method `ARMEncoder.encode(data: bytes) -> bytes` `ARMEncoder.flush() -> bytes` `ARMDecoder.__init__(total_size: int)` `ARMDecoder.decode(data: bytes) -> bytes` ### Parameters #### Request Body (for encode method) - **data** (bytes) - Required - The ARM binary data to encode. #### Path Parameters (for ARMDecoder constructor) - **total_size** (int) - Required - The total size of the encoded ARM data. #### Request Body (for decode method) - **data** (bytes) - Required - The BCJ-encoded ARM data to decode. ### Request Example (Encoding) ```python import bcj with open("arm_binary.bin", "rb") as f: arm_binary = f.read() encoder = bcj.ARMEncoder() encoded = encoder.encode(arm_binary) encoded += encoder.flush() ``` ### Response Example (Encoding) ```json { "encoded_data": "base64_encoded_binary_string" } ``` ### Request Example (Decoding) ```python import bcj encoded_data = b'your_encoded_arm_data' total_size = len(encoded_data) decoder = bcj.ARMDecoder(total_size) decoded = decoder.decode(encoded_data) ``` ### Response Example (Decoding) ```json { "decoded_data": "base64_encoded_binary_string" } ``` ``` -------------------------------- ### C++ Pytest Runner Source: https://github.com/miurahr/pybcj/blob/main/CMakeLists.txt A C++ executable designed to run pytest tests. It constructs Python code to set up the sys.path with necessary directories and then executes pytest with provided arguments. ```cpp #include #include #include int main(int argc, char **argv) { std::string args; if ( argc > 1) { args.append("["); for (int i = 1; i < argc; i++) { if (i > 2) args.append(","); args.append("\""); args.append(argv[i]); args.append("\""); } args.append("]"); } std::filesystem::path src_path = "${SRC_PATH}"; std::filesystem::path vsite_path_a = "${VPKG_PATH_A}"; std::filesystem::path vsite_path_b = "${VPKG_PATH_B}"; std::filesystem::path vsite_path_c = "${VPKG_PATH_C}"; std::string pycode = "import sys\n" "sys.path.append('" + src_path.string() + "')\n" "sys.path.append('" + vsite_path_a.string() + "')\n" "sys.path.append('" + vsite_path_b.string() + "')\n" "import pytest\n" "pytest.main(" + args + ")\n"; execl("${Python_EXECUTABLE}", "${Python_EXECUTABLE}", "-c", pycode.c_str(), (char*)0); return 0; } ``` -------------------------------- ### CMake: Pytest Runner Executable Source: https://github.com/miurahr/pybcj/blob/main/CMakeLists.txt Defines the 'pytest_runner' executable using the C++ source file. It links against Python libraries and includes necessary directories, and depends on the virtual environment and extension generation targets. ```cmake add_executable(pytest_runner ${CMAKE_CURRENT_BINARY_DIR}/pytest_runner.cpp) target_include_directories(pytest_runner PRIVATE ${Python_INCLUDE_DIRS}) target_link_libraries(pytest_runner PRIVATE ${Python_LIBRARIES}) add_dependencies(pytest_runner venv.stamp generate_ext) ``` -------------------------------- ### BCJDecoder - x86/x86_64 Decoder Source: https://context7.com/miurahr/pybcj/llms.txt Reverses the BCJ transformation on x86/x86_64 encoded data, converting absolute addresses back to relative ones. The decoder requires the total size of the encoded data at initialization. ```APIDOC ## BCJDecoder - x86/x86_64 Decoder ### Description Reverses the BCJ transformation on x86/x86_64 encoded data, converting absolute addresses back to relative ones. The decoder requires the total size of the encoded data to be specified at initialization, which is essential for proper handling of the final bytes. ### Method `__init__(total_size: int) decode(data: bytes) -> bytes` ### Parameters #### Path Parameters - **total_size** (int) - Required - The total size of the encoded data. #### Request Body (for decode method) - **data** (bytes) - Required - The BCJ-encoded data to decode. ### Request Example (decode) ```python import bcj encoded_data = b'your_encoded_data' total_size = len(encoded_data) decoder = bcj.BCJDecoder(total_size) decoded_data = decoder.decode(encoded_data) ``` ### Response (for decode method) - **decoded_data** (bytes) - The decoded binary data. ### Response Example (decode) ```json { "decoded_data": "base64_encoded_binary_string" } ``` ### Request Example (chunked decoding) ```python import bcj BLOCKSIZE = 8192 total_size = 3057801 # Known total size of encoded data decoder = bcj.BCJDecoder(total_size) output = bytearray() remaining = total_size with open("large_encoded.bin", "rb") as f: while remaining > 0: chunk = f.read(min(BLOCKSIZE, remaining)) decoded_chunk = decoder.decode(chunk) output += decoded_chunk remaining -= len(decoded_chunk) ``` ``` -------------------------------- ### Decode x86/x86_64 BCJ-Encoded Data with BCJDecoder Source: https://context7.com/miurahr/pybcj/llms.txt Reverses the BCJ transformation on x86/x86_64 encoded data. The total size of the encoded data must be provided at initialization. Handles chunked decoding for large files. ```python import bcj import hashlib # Read BCJ-encoded data with open("encoded.bin", "rb") as f: encoded_data = f.read() # Create decoder with total size and decode total_size = len(encoded_data) decoder = bcj.BCJDecoder(total_size) decoded_data = decoder.decode(encoded_data) print(f"Decoded size: {len(decoded_data)}") print(f"SHA256: {hashlib.sha256(decoded_data).hexdigest()}") # Chunked decoding for large files BLOCKSIZE = 8192 total_size = 3057801 # Known total size of encoded data decoder = bcj.BCJDecoder(total_size) output = bytearray() remaining = total_size with open("large_encoded.bin", "rb") as f: while remaining > 0: chunk = f.read(min(BLOCKSIZE, remaining)) decoded_chunk = decoder.decode(chunk) output += decoded_chunk remaining -= len(decoded_chunk) ``` -------------------------------- ### BCJEncoder - x86/x86_64 Encoder Source: https://context7.com/miurahr/pybcj/llms.txt Applies the BCJ filter to x86/x86_64 machine code. It transforms relative branch addresses into absolute addresses to enhance subsequent LZMA compression. Data can be processed in chunks using `encode()` and `flush()`. ```APIDOC ## BCJEncoder - x86/x86_64 Encoder ### Description Applies the BCJ filter to x86/x86_64 machine code, transforming relative branch addresses into absolute addresses to improve subsequent LZMA compression. The encoder can process data in chunks using the `encode()` method and must call `flush()` to retrieve any remaining buffered data. ### Method `encode(data: bytes) -> bytes` `flush() -> bytes` ### Parameters #### Request Body (for encode method) - **data** (bytes) - Required - The binary data to encode. ### Request Example (encode) ```python import bcj encoder = bcj.BCJEncoder() encoded_data = encoder.encode(b'your_binary_data') encoded_data += encoder.flush() ``` ### Response (for encode method) - **encoded_data** (bytes) - The BCJ-encoded data. ### Response Example (encode) ```json { "encoded_data": "base64_encoded_binary_string" } ``` ### Request Example (chunked encoding) ```python import bcj BLOCKSIZE = 8192 encoder = bcj.BCJEncoder() output = bytearray() with open("large_executable.bin", "rb") as f: while True: chunk = f.read(BLOCKSIZE) if not chunk: break output += encoder.encode(chunk) output += encoder.flush() ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.