#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ kvsd_data.py Словари для дизассемблера КВС Трансляция x86-64 мнемоник в кастомный синтаксис """ # === СЛОВАРЬ ТРАНСЛЯЦИИ МНЕМОНИК === MNEMONIC_TRANSLATION = { "mov": "переместить", "movzx": "переместить_с_нулями", "movsx": "переместить_со_знаком", "lea": "загрузить_адрес", "add": "прибавить", "sub": "вычесть", "inc": "увеличить", "dec": "уменьшить", "mul": "умножить", "div": "разделить", "imul": "умножить_знаковое", "idiv": "разделить_знаковое", "neg": "отрицать", "and": "и", "or": "или", "xor": "исключающее_или", "not": "инвертировать", "cmp": "сравнить", "test": "проверить", "jmp": "переход", "je": "переход_если_равно", "jz": "переход_если_ноль", "jne": "переход_если_неравно", "jnz": "переход_если_не_ноль", "jl": "переход_если_меньше", "jg": "переход_если_больше", "jle": "переход_если_меньше_или_равно", "jge": "переход_если_больше_или_равно", "jc": "переход_если_перенос", "jnc": "переход_если_нет_переноса", "jo": "переход_если_переполнение", "jno": "переход_если_нет_переполнения", "js": "переход_если_знак", "jns": "переход_если_нет_знака", "jp": "переход_если_чётность", "jnp": "переход_если_не_чётность", "jbe": "переход_если_ниже_или_равно", "ja": "переход_если_выше", "call": "вызвать", "ret": "вернуться", "retn": "вернуться", "push": "втолкнуть", "pop": "вытолкнуть", "pushf": "втолкнуть_флаги", "popf": "вытолкнуть_флаги", "shl": "сдвиг_влево", "sal": "сдвиг_влево", "shr": "сдвиг_вправо", "sar": "сдвиг_арифметический_вправо", "rol": "вращать_влево", "ror": "вращать_вправо", "rcl": "вращать_через_перенос_влево", "rcr": "вращать_через_перенос_вправо", "syscall": "вызов_системы", "int": "прервать", "sysenter": "войти_в_систему", "hlt": "остановить", "cpuid": "идентифицировать_процессор", "rdtsc": "прочитать_счётчик", "nop": "нет_операции", "int3": "отладка", "movsb": "переместить_байт", "movsw": "переместить_слово", "movsd": "переместить_двойное_слово", "movsq": "переместить_квадрослово", "cmpsb": "сравнить_байты", "cmpsw": "сравнить_слова", "scasb": "сканировать_байт", "stosb": "сохранить_байт", "stc": "установить_перенос", "clc": "сбросить_перенос", "std": "установить_направление", "cld": "сбросить_направление", "in": "ввод_байта", "out": "вывод_байта", "loop": "цикл", "loope": "цикл_если_равно", "loopne": "цикл_если_не_равно", "xchg": "обменять", } # === СЛОВАРЬ ТРАНСЛЯЦИИ РЕГИСТРОВ === REGISTER_TRANSLATION = { "rax": "раикс", "rcx": "рсикс", "rdx": "рдикс", "rbx": "рбикс", "rsp": "рсипи", "rbp": "рбипи", "rsi": "рсиай", "rdi": "рдиай", "r8": "р8", "r9": "р9", "r10": "р10", "r11": "р11", "r12": "р12", "r13": "р13", "r14": "р14", "r15": "р15", "eax": "еаикс", "ecx": "есикс", "edx": "едикс", "ebx": "ебикс", "esp": "есипи", "ebp": "ебипи", "esi": "есиай", "edi": "едиай", "r8d": "р8д", "r9d": "р9д", "r10d": "р10д", "r11d": "р11д", "r12d": "р12д", "r13d": "р13д", "r14d": "р14д", "r15d": "р15д", "ax": "аикс", "cx": "сикс", "dx": "дикс", "bx": "бикс", "sp": "эсп", "bp": "бипи", "si": "эс", "di": "ди", "r8w": "р8в", "r9w": "р9в", "r10w": "р10в", "r11w": "р11в", "r12w": "р12в", "r13w": "р13в", "r14w": "р14в", "r15w": "р15в", "al": "ал", "cl": "кл", "dl": "дл", "bl": "бл", "spl": "спл", "bpl": "бпл", "sil": "сил", "dil": "дил", "r8b": "р8б", "r9b": "р9б", "r10b": "р10б", "r11b": "р11б", "r12b": "р12б", "r13b": "р13б", "r14b": "р14б", "r15b": "р15б", "ah": "аш", "ch": "чш", "dh": "дш", "bh": "бш", "rip": "рип", "rflags": "рфлаги", } def translate_mnemonic(mnemonic, operand_str="", instr_len=0): """ Переводит мнемонику x86-64 в кастомный синтаксис КВС. Аргументы: mnemonic (str): исходная мнемоника operand_str (str): строка операндов (для определения short) instr_len (int): длина инструкции в байтах (для определения коротких/длинных переходов) """ # Для JMP: определяем по наличию "short" в операндах if mnemonic == "jmp" and "short" in operand_str: return "короткий_переход" # Для условных переходов: определяем по длине инструкции if mnemonic in ["je", "jz", "jne", "jnz", "jl", "jg", "jle", "jge", "jc", "jnc", "jo", "jno", "js", "jns", "jp", "jnp", "jbe", "ja"]: # Длина 2 байта = короткий переход (rel8) if instr_len == 2: translation = { "je": "короткий_переход_если_равно", "jz": "короткий_переход_если_ноль", "jne": "короткий_переход_если_неравно", "jnz": "короткий_переход_если_не_ноль", "jl": "короткий_переход_если_меньше", "jg": "короткий_переход_если_больше", "jle": "короткий_переход_если_меньше_или_равно", "jge": "короткий_переход_если_больше_или_равно", "jc": "короткий_переход_если_перенос", "jnc": "короткий_переход_если_нет_переноса", "jo": "короткий_переход_если_переполнение", "jno": "короткий_переход_если_нет_переполнения", "js": "короткий_переход_если_знак", "jns": "короткий_переход_если_нет_знака", "jp": "короткий_переход_если_чётность", "jnp": "короткий_переход_если_не_чётность", "jbe": "короткий_переход_если_ниже_или_равно", "ja": "короткий_переход_если_выше", } return translation.get(mnemonic, mnemonic) # Длина 6 байт = длинный переход (rel32) elif instr_len == 6: translation = { "je": "переход_если_равно", "jz": "переход_если_ноль", "jne": "переход_если_неравно", "jnz": "переход_если_не_ноль", "jl": "переход_если_меньше", "jg": "переход_если_больше", "jle": "переход_если_меньше_или_равно", "jge": "переход_если_больше_или_равно", "jc": "переход_если_перенос", "jnc": "переход_если_нет_переноса", "jo": "переход_если_переполнение", "jno": "переход_если_нет_переполнения", "js": "переход_если_знак", "jns": "переход_если_нет_знака", "jp": "переход_если_чётность", "jnp": "переход_если_не_чётность", "jbe": "переход_если_ниже_или_равно", "ja": "переход_если_выше", } return translation.get(mnemonic, mnemonic) return MNEMONIC_TRANSLATION.get(mnemonic, mnemonic) def translate_operand(operand): """ Переводит операнд: заменяет все регистры на кастомные имена. Также удаляет слово "short" из операндов. """ if not operand: return operand result = operand # Удаляем "short" из операндов (для коротких переходов) result = result.replace("short ", "") result = result.replace(" short", "") # Сортируем регистры по длине (от длинных к коротким) sorted_regs = sorted(REGISTER_TRANSLATION.keys(), key=len, reverse=True) for reg in sorted_regs: trans_reg = REGISTER_TRANSLATION[reg] for sep in ['', ' ', ',', '+', '-', '*', '/', '(', ')', '[', ']', ':', '&', '|']: result = result.replace(reg + sep, trans_reg + sep) result = result.replace(sep + reg, sep + trans_reg) if result.startswith(reg): result = trans_reg + result[len(reg):] if result.endswith(reg): result = result[:-len(reg)] + trans_reg result = result.replace(reg, trans_reg) return result def translate_line(line): """ Переводит строку дизассемблера. Формат: "00401000 48B80A0000000000 mov rax,0xa" """ if not line.strip(): return line parts = line.split(maxsplit=2) if len(parts) < 3: return line address = parts[0] bytes_hex = parts[1] rest = parts[2] rest_parts = rest.split(maxsplit=1) mnemonic = rest_parts[0] operands = rest_parts[1] if len(rest_parts) > 1 else "" # Вычисляем длину инструкции instr_len = len(bytes_hex) // 2 if bytes_hex else 0 new_mnemonic = translate_mnemonic(mnemonic, operands, instr_len) new_operands = translate_operand(operands) if new_operands: return f"{address} {bytes_hex} {new_mnemonic} {new_operands}" else: return f"{address} {bytes_hex} {new_mnemonic}"