diff --git a/docker-compose.yaml b/docker-compose.yaml index 087d883..ef1833e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,16 +1,11 @@ version: '3' services: - sins_build: + sins_run: image: sins build: context: . volumes: - ${PWD}:/app working_dir: /app - command: yasm seed.asm -o seed - sins_run: - image: sins - volumes: - - ${PWD}:/app - working_dir: /app command: python3 -m sins + # command: yasm seed.asm -o seed diff --git a/sins/__init__.py b/sins/__init__.py index bafc736..96ff1cd 100644 --- a/sins/__init__.py +++ b/sins/__init__.py @@ -1,3 +1,3 @@ #! /usr/bin/env python3 -from .run import sins, shell_func +from .run import sins, generation # from .orm import SeedNode diff --git a/sins/run.py b/sins/run.py index 3fc305f..836d654 100755 --- a/sins/run.py +++ b/sins/run.py @@ -3,6 +3,8 @@ from argparse import ArgumentParser from datetime import datetime from pathlib import Path from random import randint +from multiprocessing import Process, Queue +from queue import Empty import binascii import ctypes import logging @@ -27,7 +29,15 @@ seed_shell = b''.join([ b'\xc3']) -def shell_func(shellcode: bytes): +def flip(shellcode: bytes): + shellcode = bytearray(shellcode) + offset = randint(0, len(shellcode) -1) + flip = randint(0, 255) + shellcode[offset] ^= flip + return bytes(shellcode) + + +def generation(queue: Queue, shellcode: bytes): prot = mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC flags = mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE exec_mem = mmap.mmap(-1, len(shellcode), prot=prot, flags=flags) @@ -39,7 +49,10 @@ def shell_func(shellcode: bytes): function = ctypes.CFUNCTYPE(ctypes.c_uint, ctypes.c_uint)(addr) function._avoid_gc_for_mmap = exec_mem - return function + shellcode_len = ctypes.c_uint(len(shellcode)) + result = function(shellcode_len) + + queue.put(result) def sins(): @@ -49,6 +62,8 @@ def sins(): parser.add_argument('-v', '--verbose', action='count') parser.add_argument('-s', '--seed', help='path to PIC image.') parser.add_argument('-o', '--output', help='path to results directory.') + parser.add_argument('-l', '--lineage', default=10, + help='max count of unsuccessful generation.') args = parser.parse_args() log_level = logging.INFO @@ -84,17 +99,31 @@ def sins(): with seed.open('rb') as seed_file: seed_data = seed_file.read() - seed_data = bytearray(seed_data) + logger.info(f'seed:\n{seed_data}') - offset = randint(0, len(seed_data)) - flip = randint(0, 255) - seed_data[offset] ^= flip + queue = Queue() - seed_len = ctypes.c_uint(len(seed_data)) - logger.info(f'seed_data\n{binascii.b2a_hex(seed_data)}') - logger.info(f'seed_len: {seed_len}') + while True: + lineage = 0 + seed_flipped = flip(seed_data) - seed = shell_func(seed_shell) - ret_val = seed(seed_len) + while lineage < args.lineage: + logger.info(f'lineage: {lineage}') + result = None - logger.info(f'ret_val: {ret_val}') + proc = Process(target=generation, args=(queue, seed_flipped)) + proc.start() + try: + result = queue.get(timeout=1) + except Empty: + lineage += 1 + continue + + if not result: + lineage += 1 + continue + + logger.info(f'scrap:\n{seed_flipped}') + logger.info(f'result: {result}') + lineage = 0 + seed_flipped = flip(seed_flipped)