{"id":493011,"date":"2026-08-31T23:25:59","date_gmt":"2026-08-31T23:25:59","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=493011"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=493011","title":{"rendered":"Callfuscated \u2014 \u0412\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, MBA, opaque predicates \u0438 \u043c\u0443\u0441\u043e\u0440\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0438"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0417\u0430\u0434\u0430\u043d\u0438\u0435: <a href=\"https:\/\/app.hackthebox.com\/challenges\/Callfuscated?tab=play_challenge\" rel=\"noopener nofollow\">https:\/\/app.hackthebox.com\/challenges\/Callfuscated<\/a><\/p>\n<h2>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0438\u0448\u0443 \u044d\u0442\u043e<\/h2>\n<p>\u041c\u0435\u043d\u044f \u0437\u0430\u0440\u0435\u0439\u0434\u0436\u0431\u0430\u0439\u0442\u0438\u043b\u0430 <a href=\"https:\/\/habr.com\/ru\/articles\/1061634\/\" rel=\"noopener nofollow\">\u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f<\/a>. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e \u0442\u0440\u0430\u0441\u0441\u0435, \u0431\u0435\u0437 \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430, MBA \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u00ab\u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u043a\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043a\u0443\u0440\u0441\u0430\u00bb \u2014 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c 2 \u043e\u043f\u043a\u043e\u0434\u0430 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u044b \u043d\u0435\u0432\u0435\u0440\u043d\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 \u043d\u0435 \u0432\u0441\u043f\u043b\u044b\u043b\u0430 \u0438\u0437-\u0437\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0430\u0441\u043a\u0430. \u0420\u0430\u0437\u0431\u0435\u0440\u0443 \u0438\u043d\u0430\u0447\u0435: \u0441\u0442\u0430\u0442\u0438\u043a\u043e\u0439, \u0441 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435\u043c MBA \u0438 \u0441\u043d\u044f\u0442\u0438\u0435\u043c \u043c\u0443\u0441\u043e\u0440\u0430.<\/p>\n<h2>\u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434<\/h2>\n<p>\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c, \u0432\u0438\u0434\u0438\u043c \u044d\u0442\u043e:<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9f9\/1c4\/328\/9f91c432842671abd11eabd7ad2ed40f.png\" alt=\"\u041a\u0430\u043a\u043e\u0439-\u0442\u043e \u0431\u0440\u0435\u0434\" title=\"\u041a\u0430\u043a\u043e\u0439-\u0442\u043e \u0431\u0440\u0435\u0434\" width=\"1035\" height=\"1212\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/9f9\/1c4\/328\/9f91c432842671abd11eabd7ad2ed40f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9f9\/1c4\/328\/9f91c432842671abd11eabd7ad2ed40f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041a\u0430\u043a\u043e\u0439-\u0442\u043e \u0431\u0440\u0435\u0434<\/figcaption><\/div>\n<\/figure>\n<p>\u041b\u0430\u0434\u043d\u043e, \u0435\u0441\u0442\u044c \u043a\u0443\u0447\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f Callfuscated, \u0430 \u0447\u0442\u043e \u0437\u0430 \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e arg_*? \u0422\u0430\u043a \u0438 \u043d\u0435 \u043f\u043e\u043d\u044f\u043b, \u043e\u0442\u043a\u0443\u0434\u0430 \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0438\u0445 \u0431\u0435\u0440\u0451\u0442. \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \u043b\u044e\u0431\u043e\u0439 \u0438\u0437 \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432\u0435\u0434\u0451\u0442 \u043a\u0443\u0434\u0430-\u0442\u043e \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0443 \u0442\u043e\u0433\u043e \u0436\u0435 main. \u0427\u0442\u043e-\u0442\u043e \u0442\u0443\u0442 \u043d\u0435 \u0442\u0430\u043a. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/40d\/72c\/a57\/40d72ca5784b4e19f1ef213aabe5dda7.png\" alt=\"\u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\" title=\"\u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\" width=\"691\" height=\"700\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/40d\/72c\/a57\/40d72ca5784b4e19f1ef213aabe5dda7.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/40d\/72c\/a57\/40d72ca5784b4e19f1ef213aabe5dda7.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u0430\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439: call, pop r8 \u0438 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f. \u041f\u043e\u0442\u044b\u043a\u0430\u0435\u043c \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0443\u0436\u0435 \u0432 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0443\u0434\u0430 \u043e\u043d\u0438 \u0432\u0435\u0434\u0443\u0442; \u0437\u0430\u043c\u0435\u0447\u0430\u0435\u043c, \u0447\u0442\u043e call \u0432\u0435\u0434\u0451\u0442 \u043d\u0430 pop r8 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e, \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 call \u0432\u0435\u0434\u0451\u0442 \u043d\u0430 \u0442\u0443 \u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443. \u0412\u043e\u0442 \u0447\u0442\u043e \u043f\u043e \u0438\u0442\u043e\u0433\u0443 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:<\/p>\n<pre><code class=\"assembly\">call 1; \u0446\u0435\u043b\u044c \u043a\u043e\u043b\u043b\u0430 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0437\u0430 \u043d\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043b1:pop r8; \u0447\u0442\u043e-\u0442\u043ecall 22:pop r8; \u0447\u0442\u043e-\u0442\u043e; \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>call \u043a\u043b\u0430\u0434\u0451\u0442 \u043d\u0430 \u0441\u0442\u0435\u043a \u0430\u0434\u0440\u0435\u0441 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, pop r8 \u0442\u0443\u0442 \u0436\u0435 \u0435\u0433\u043e \u0441\u043d\u0438\u043c\u0430\u0435\u0442. \u0421\u0442\u0435\u043a \u0432 \u0438\u0442\u043e\u0433\u0435 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f, \u0438\u0441\u043f\u043e\u0440\u0447\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e r8. \u0415\u0441\u043b\u0438 r8 \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0435 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u2014 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u043c\u0438 jmp, \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432 \u0434\u0432\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u0430\u0436\u0435\u043c, \u0447\u0442\u043e r8 \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f<\/p>\n<pre><code class=\"python\">import ioimport structfrom pathlib import Pathfrom capstone import Cs, CS_ARCH_X86, CS_MODE_64from elftools.elf.elffile import ELFFilefrom unicorn import Uc, UC_ARCH_X86, UC_MODE_64, UC_PROT_ALLfrom unicorn.x86_const import (    UC_X86_REG_R8, UC_X86_REG_RAX, UC_X86_REG_RDI,    UC_X86_REG_RIP, UC_X86_REG_RSI, UC_X86_REG_RSP,)FILE = Path(r\"crackme\")START, STOP = 0x409002, 0x60000000STACK, PAGE = 0x70000000, 0x1000SRAND, SCANF, RAND = 0x401050, 0x401060, 0x401070IMPORTS = {0x401030, 0x401040, SRAND, SCANF, RAND}MAX_INSTRUCTIONS = 2_000_000def rng(seed):    s = [seed &amp; 0xffffffff or 1]    for _ in range(30):        s.append(16807 * s[-1] % 2147483647)    s += s[:3]    for i in range(34, 344):        s.append((s[i - 31] + s[i - 3]) &amp; 0xffffffff)    return sdef ret(uc):    rsp = uc.reg_read(UC_X86_REG_RSP)    uc.reg_write(UC_X86_REG_RSP, rsp + 8)    uc.reg_write(UC_X86_REG_RIP, struct.unpack(\"&lt;Q\", uc.mem_read(rsp, 8))[0])data = FILE.read_bytes()elf = ELFFile(io.BytesIO(data))segments = [s for s in elf.iter_segments() if s[\"p_type\"] == \"PT_LOAD\"]lo = min(s[\"p_vaddr\"] for s in segments) &amp; -PAGEhi = (max(s[\"p_vaddr\"] + s[\"p_memsz\"] for s in segments) + PAGE - 1) &amp; -PAGEuc = Uc(UC_ARCH_X86, UC_MODE_64)uc.mem_map(lo, hi - lo, UC_PROT_ALL)for segment in segments:    uc.mem_write(segment[\"p_vaddr\"], segment.data())uc.mem_map(STACK, PAGE * 16, UC_PROT_ALL)uc.mem_map(STOP, PAGE, UC_PROT_ALL)rsp = STACK + PAGE * 16 - 8uc.mem_write(rsp, struct.pack(\"&lt;Q\", STOP))uc.reg_write(UC_X86_REG_RSP, rsp)uc.reg_write(UC_X86_REG_RIP, START)cs = Cs(CS_ARCH_X86, CS_MODE_64)cs.detail = Truestate = Nonereads = set()executed = 0while uc.reg_read(UC_X86_REG_RIP) != STOP:    rip = uc.reg_read(UC_X86_REG_RIP)    if executed &gt;= MAX_INSTRUCTIONS:        raise RuntimeError(\"instruction limit exceeded\")    if rip == SRAND:        state = rng(uc.reg_read(UC_X86_REG_RDI))        ret(uc)        continue    if rip == RAND:        if state is None:            raise RuntimeError(\"rand before srand\")        value = (state[-31] + state[-3]) &amp; 0xffffffff        state.append(value)        uc.reg_write(UC_X86_REG_RAX, value &gt;&gt; 1)        ret(uc)        continue    if rip == SCANF:        uc.mem_write(uc.reg_read(UC_X86_REG_RSI), b\"A\" * 63 + b\"\\0\")        uc.reg_write(UC_X86_REG_RAX, 1)        ret(uc)        continue    if rip in IMPORTS:        ret(uc)        continue    ins = next(cs.disasm(bytes(uc.mem_read(rip, 15)), rip, count=1))    if any(cs.reg_name(reg).lower() in {\"r8\", \"r8d\", \"r8w\", \"r8b\"}           for reg in ins.regs_access()[0]):        reads.add(rip)    uc.emu_start(rip, 0, count=1)    executed += 1print(f\"executed: {executed}\")print(f\"r8 reads: {len(reads)}\")if reads:    print(\"addresses:\", \", \".join(f\"{address:#x}\" for address in sorted(reads)))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:<\/p>\n<pre><code>executed: 186802r8 reads: 0<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043e\u043a\u0430\u0437\u0430\u043b\u0438.<\/p>\n<p>\u0412 \u0441\u0430\u043c\u043e\u043c call \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0431\u0430\u0439\u0442: call rel32 (E8) \u0438 jmp rel32 (E9) \u043e\u0434\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0438 \u0441\u0447\u0438\u0442\u0430\u044e\u0442 \u0430\u0434\u0440\u0435\u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e, \u043e\u0442 \u043a\u043e\u043d\u0446\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u041c\u0435\u043d\u044f\u0435\u043c \u043e\u043f\u043a\u043e\u0434 \u2014 \u0446\u0435\u043b\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f. pop r8 (41 58) \u0437\u0430\u0431\u0438\u0432\u0430\u0435\u043c \u0434\u0432\u0443\u043c\u044f nop. <\/p>\n<h2>\u0421\u043d\u0438\u043c\u0430\u0435\u043c \u043c\u0443\u0441\u043e\u0440<\/h2>\n<p>\u042f \u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043b, \u043a\u0430\u043a \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0438\u0448\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e<\/p>\n<pre><code class=\"python\">import iofrom pathlib import Pathfrom capstone import Cs, CS_ARCH_X86, CS_MODE_64from capstone.x86 import X86_OP_IMMfrom elftools.elf.elffile import ELFFileFILE = Path(r\"crackme\")OUT = FILE.with_name(FILE.name + \"_patched\")original = FILE.read_bytes()patched = bytearray(original)elf = ELFFile(io.BytesIO(original))segments = [s for s in elf.iter_segments() if s[\"p_type\"] == \"PT_LOAD\"]def file_offset(address):    segment = next(        s for s in segments        if s[\"p_vaddr\"] &lt;= address &lt; s[\"p_vaddr\"] + s[\"p_filesz\"]    )    return segment[\"p_offset\"] + address - segment[\"p_vaddr\"]cs = Cs(CS_ARCH_X86, CS_MODE_64)cs.detail = Truecount = 0for segment in segments:    if not segment[\"p_flags\"] &amp; 1:        continue    for instruction in cs.disasm(segment.data(), segment[\"p_vaddr\"]):        if instruction.mnemonic != \"call\":            continue        operand = instruction.operands[0]        if operand.type != X86_OP_IMM:            continue        target = operand.imm        try:            target_offset = file_offset(target)        except StopIteration:            continue        is_pop_r8 = original[target_offset:target_offset + 2] == b\"\\x41\\x58\"        if not is_pop_r8:            continue        call_offset = file_offset(instruction.address)        patched[call_offset] = 0xE9                 # call -&gt; jmp        patched[target_offset:target_offset + 2] = b\"\\x90\\x90\"        count += 1        print(f\"{instruction.address:#x}: call -&gt; jmp, {target:#x}: pop r8 -&gt; nop nop\")OUT.write_bytes(patched)print(f\"\u0413\u043e\u0442\u043e\u0432\u043e: {OUT} ({count} \u043f\u0430\u0442\u0447\u0435\u0439)\")<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c, \u0438 \u0432\u0438\u0434\u0438\u043c \u044d\u0442\u043e:<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9a4\/9c6\/2e8\/9a49c62e82d88bfee610fdce7587bd34.png\" alt=\"\u0427\u0438\u0441\u0442\u044b\u0439 main\" title=\"\u0427\u0438\u0441\u0442\u044b\u0439 main\" width=\"1167\" height=\"1074\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/9a4\/9c6\/2e8\/9a49c62e82d88bfee610fdce7587bd34.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9a4\/9c6\/2e8\/9a49c62e82d88bfee610fdce7587bd34.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0427\u0438\u0441\u0442\u044b\u0439 main<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0430 \u044d\u0442\u043e \u0436\u0435 \u0412\u041c! \u0423\u0437\u043d\u0430\u0451\u0442\u0441\u044f \u043f\u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u043e\u043c\u0443 while (true): \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u043e\u043f\u043a\u043e\u0434) \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442, \u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u0441\u0432\u043e\u0439 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 \u2014 \u0445\u0435\u043d\u0434\u043b\u0435\u0440. <\/p>\n<h2>\u0420\u0430\u0437\u0431\u043e\u0440 \u0412\u041c<\/h2>\n<p>\u0422\u0443\u0442 \u043e\u0431\u044b\u043a\u043d\u043e\u0432\u0435\u043d\u043d\u0430\u044f \u0441\u0442\u0435\u043a\u043e\u0432\u0430\u044f \u0412\u041c, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c \u0435\u0451 \u0438 \u0432\u0438\u0434\u0438\u043c \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u044b \u0441 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/345\/fbb\/7ac\/345fbb7accd25eb108d6d1d548a60526.png\" alt=\"\u0425\u0435\u043d\u0434\u043b\u0435\u0440\u044b \u0441 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439\" title=\"\u0425\u0435\u043d\u0434\u043b\u0435\u0440\u044b \u0441 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439\" width=\"981\" height=\"807\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/345\/fbb\/7ac\/345fbb7accd25eb108d6d1d548a60526.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/345\/fbb\/7ac\/345fbb7accd25eb108d6d1d548a60526.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0425\u0435\u043d\u0434\u043b\u0435\u0440\u044b \u0441 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0441\u0435\u043b\u043e<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/70f\/76a\/6ce\/70f76a6ce7675ae09fa3f761ec72eef8.png\" alt=\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0437 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430 \u21162\" title=\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0437 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430 \u21162\" width=\"1243\" height=\"862\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/70f\/76a\/6ce\/70f76a6ce7675ae09fa3f761ec72eef8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/70f\/76a\/6ce\/70f76a6ce7675ae09fa3f761ec72eef8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0437 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430 \u21162<\/figcaption><\/div>\n<\/figure>\n<p>\u0410 \u0432\u043e\u0442 \u0438 \u043e\u0431\u0435\u0449\u0430\u043d\u043d\u0430\u044f MBA. \u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c\u0441\u044f \u043a \u043a\u043e\u0434\u0443 2 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f rand \u0432 \u0434\u0432\u0443\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u0432\u044b\u0437\u043e\u0432\u0430, \u044d\u0442\u043e \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u043e\u0431\u0435\u0449\u0430\u043d\u043d\u044b\u0435 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442\u044b<\/p>\n<h2>\u0420\u0435\u0448\u0430\u0435\u043c MBA<\/h2>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442: MBA \u2014 \u044d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (\u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435, XOR \u0438 \u0442\u0434) \u043d\u0430 \u0440\u0430\u0437\u0434\u0443\u0442\u044b\u0435 \u0433\u0438\u0433\u0430\u043d\u0442\u0441\u043a\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0423 \u043d\u0430\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 MBA \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u043b\u0430\u0434\u0451\u0442\u0441\u044f \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0443 \u0441\u0442\u0435\u043a\u0430 \u043a\u0430\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u043f\u043a\u043e\u0434\u0430, \u0430 \u043e\u043f\u043a\u043e\u0434 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u2014 \u044d\u0442\u043e \u043e\u0434\u043d\u0430 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f. \u0417\u043d\u0430\u0447\u0438\u0442, \u0437\u0430 \u0434\u0435\u0440\u0435\u0432\u043e\u043c \u043d\u0430 \u0441\u043e\u0442\u043d\u0438 \u0443\u0437\u043b\u043e\u0432 \u043f\u0440\u044f\u0447\u0435\u0442\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 a + b.<\/p>\n<p>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 MBA \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u0430 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c-\u0442\u043e \u0431\u0443\u0434\u0435\u043c? \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b simplify() \u0438\u0437 <a href=\"https:\/\/github.com\/jonathansalwan\/triton\" rel=\"noopener nofollow\">Triton<\/a>: \u043d\u0435 \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0441\u044f. \u041f\u043e\u0442\u043e\u043c <a href=\"https:\/\/github.com\/DenuvoSoftwareSolutions\/GAMBA\" rel=\"noopener nofollow\">GAMBA <\/a>\u2014 \u0442\u043e\u0436\u0435 \u043c\u0438\u043c\u043e. \u0420\u0430\u0437\u043e\u0431\u0440\u0430\u0432\u0448\u0438\u0441\u044c, \u043f\u043e\u043d\u044f\u043b \u043f\u043e\u0447\u0435\u043c\u0443: <a href=\"https:\/\/github.com\/jonathansalwan\/triton\" rel=\"noopener nofollow\">Triton <\/a>\u2014 \u043d\u0435 MBA-\u0441\u043e\u043b\u0432\u0435\u0440, \u0430 <a href=\"https:\/\/github.com\/DenuvoSoftwareSolutions\/GAMBA\" rel=\"noopener nofollow\">GAMBA <\/a>\u0437\u0430\u0442\u043e\u0447\u0435\u043d \u043f\u043e\u0434 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b MBA. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043d\u0430\u0433\u0443\u0433\u043b\u0438\u043b <a href=\"https:\/\/github.com\/trailofbits\/CoBRA\" rel=\"noopener nofollow\">CoBRA <\/a>\u2014 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u0448\u0430\u043b\u043a\u0443 MBA, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u0447\u0435\u043c <a href=\"https:\/\/github.com\/DenuvoSoftwareSolutions\/GAMBA\" rel=\"noopener nofollow\">GAMBA<\/a>. \u041e\u043d\u0430 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430, \u043f\u0440\u043e \u043d\u0435\u0451 \u0438 \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0412 \u043d\u0435\u0451 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u2014 \u043d\u0443\u0436\u0435\u043d \u043b\u0438\u0444\u0442. \u0422\u0443\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u043b\u0441\u044f <a href=\"https:\/\/github.com\/jonathansalwan\/triton\" rel=\"noopener nofollow\">Triton<\/a>: \u043e\u043d \u0443\u043c\u0435\u0435\u0442 \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0438 \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0442\u0434\u0430\u0442\u044c AST-\u0444\u043e\u0440\u043c\u0443\u043b\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 \u0438\u043b\u0438 \u044f\u0447\u0435\u0439\u043a\u0438 \u043f\u0430\u043c\u044f\u0442\u0438. Triton \u0442\u0443\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0438\u0444\u0442\u0435\u0440: \u0441\u0442\u0440\u043e\u0438\u0442 AST, \u0430 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0443\u0436\u0435 CoBRA. <\/p>\n<h3>\u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c<\/h3>\n<p>\u041d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430. \u0412\u043e\u0442 \u043a\u043e\u0434, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b:<\/p>\n<pre><code class=\"python\">import ioimport sysimport subprocessfrom pathlib import Pathfrom elftools.elf.elffile import ELFFilefrom triton import ARCH, Instruction, MemoryAccess, OPCODE, TritonContextsys.path.insert(0, str(Path(__file__).resolve().parent))from triton_to_cobra import triton_ast_to_cobraFILE = Path(r\"crackme_patched\")COBRA = Path(r\"cobra-cli.exe\")HANDLERS = {    0x401166: 4,    0x401F18: 4,    0x4025D8: 2,    0x4050AA: 2,    0x405C1F: 2,    0x406E47: 2,    0x4080D6: 2,}COBRA_MAX_VARS = 20REGISTERS = (\"rdi\", \"rsi\", \"rdx\", \"rcx\")def symbolic_formula(address, argc, segments):    ctx = TritonContext(ARCH.X86_64)    for segment in segments:        ctx.setConcreteMemoryAreaValue(segment[\"p_vaddr\"], segment.data())    for name in REGISTERS[:argc]:        ctx.symbolizeRegister(getattr(ctx.registers, name), name)    ctx.setConcreteRegisterValue(ctx.registers.rsp, 0x70000000)    ctx.setConcreteMemoryValue(MemoryAccess(0x70000000, 8), 0)    ctx.setConcreteRegisterValue(ctx.registers.rip, address)    for count in range(100000):        rip = ctx.getConcreteRegisterValue(ctx.registers.rip)        instruction = Instruction(rip, bytes(ctx.getConcreteMemoryAreaValue(rip, 16)))        ctx.processing(instruction)        if instruction.getType() == OPCODE.X86.RET:            ast = ctx.getAstContext().extract(31, 0, ctx.getRegisterAst(ctx.registers.rax))            return ctx.getAstContext().unroll(ast), count + 1    raise RuntimeError(f\"sub_{address:x}: ret not found\")data = FILE.read_bytes()elf = ELFFile(io.BytesIO(data))segments = [segment for segment in elf.iter_segments() if segment[\"p_type\"] == \"PT_LOAD\"]for address, argc in HANDLERS.items():    print(f\"sub_{address:x}: Triton...\", flush=True)    formula, instructions = symbolic_formula(address, argc, segments)    try:        expression = triton_ast_to_cobra(formula)    except ValueError as error:        print(f\"  SUPEROP\/unsupported by CoBRA grammar: {error}\", flush=True)        continue    print(f\"  {instructions} instructions, {len(expression)} chars; CoBRA full AST...\", flush=True)    input_path = Path(f\"sub_{address:x}.mba\")    input_path.write_text(expression, encoding=\"ascii\")    process = subprocess.run(        [str(COBRA), \"--mba-file\", str(input_path), \"--bitwidth\", \"32\", \"--max-vars\", str(COBRA_MAX_VARS)],        text=True,        capture_output=True,        timeout=600,    )    if process.returncode:        print(\"  FAILED:\", process.stderr.strip(), flush=True)    else:        result = process.stdout.strip()        Path(f\"sub_{address:x}.simplified.txt\").write_text(result + \"\\n\", encoding=\"ascii\")        print(f\"  {result}\", flush=True)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043a\u0440\u0430\u0442\u0446\u0435: \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c AST \u0434\u043b\u044f rax, \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c AST Triton \u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 CoBRA, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"https:\/\/gist.github.com\/farvend\/954133a105d3d00de2629b997d355711\" rel=\"noopener nofollow\">\u044d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442<\/a>, \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u044d\u0442\u043e:<\/p>\n<pre><code>sub_401166: Triton...  1385 instructions, 5835 chars; CoBRA full AST...  rdi * rsisub_401f18: Triton...  681 instructions, 2663 chars; CoBRA full AST...  rsi + rdisub_4025d8: Triton...  SUPEROP\/unsupported by CoBRA grammar:  ...sub_4050aa: Triton...  1141 instructions, 4318 chars; CoBRA full AST...  rdi + -rsisub_405c1f: Triton...  1813 instructions, 7026 chars; CoBRA full AST...  rdi ^ rsisub_406e47: Triton...  1857 instructions, 7375 chars; CoBRA full AST...  rdi | rsisub_4080d6: Triton...  1509 instructions, 5535 chars; CoBRA full AST...  rdi &amp; rsi<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>sub_4025d8 \u043d\u0435 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043b\u0441\u044f, \u043d\u043e \u0441\u043f\u043e\u0439\u043b\u0435\u0440: \u043e\u043d \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f. \u0417\u0430\u043e\u0434\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u0440\u043e rand: \u0434\u0432\u0443\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u043f\u043e 4 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, \u0430 \u0432 \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e rdi \u0438 rsi. \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0441 rand \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435 \u0432\u043b\u0438\u044f\u044e\u0442 \u2014 \u0440\u043e\u0432\u043d\u043e \u0442\u043e, \u0447\u0435\u043c \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0439 \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430\u043c\u0438! \u042f \u043f\u0440\u043e\u043f\u0443\u0449\u0443 \u044d\u0442\u0430\u043f \u0441 \u043e\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u043e\u0432 \u2014 \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u044f \u0432\u0435\u0440\u044e, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u044d\u0442\u043e \u0441\u0430\u043c\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f.<\/p>\n<h2>\u041f\u0438\u0448\u0435\u043c \u0434\u0435\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440<\/h2>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0412\u041c, \u0437\u043d\u0430\u0435\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u043f\u043a\u043e\u0434\u043e\u0432, \u0431\u0430\u0439\u0442\u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u043f\u0440\u043e\u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0432 \u0435\u0433\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u0447\u0435\u0440\u0435\u0437 Unicorn, \u0438\u043b\u0438 \u0441\u0434\u0430\u043c\u043f\u0438\u0432 \u0435\u0433\u043e \u0440\u0443\u043a\u0430\u043c\u0438.<\/p>\n<p>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c-\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c? \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0443\u0442\u0435\u0439: \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u044d\u0442\u043e\u0439 \u0412\u041c, \u043d\u043e \u043f\u043e \u043c\u043e\u0435\u043c\u0443 \u043e\u043f\u044b\u0442\u0443 \u044d\u0442\u043e \u043c\u0443\u0442\u043e\u0440\u043d\u043e\u0435 \u0437\u0430\u043d\u044f\u0442\u0438\u0435. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u0432 \u043b\u043e\u0431 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u043f\u043a\u043e\u0434\u043e\u0432 \u0412\u041c \u043d\u0430 C, \u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0441 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u0432\u0441\u0451 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442. \u0422\u0430\u043a \u043c\u044b \u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043c. \u042d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u044f \u0432\u0437\u044f\u043b <a href=\"https:\/\/washi1337.github.io\/ctf-writeups\/writeups\/flare-on\/2024\/10\/\" rel=\"noopener nofollow\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>. \u041c\u043e\u0436\u0435\u0442, \u0435\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0434\u0435\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u043e \u043c\u043d\u0435 \u043e\u043d\u0438 \u043d\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0438\u0441\u044c.<\/p>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u044f \u0434\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043b \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443<\/p>\n<pre><code class=\"python\">import ioimport structfrom pathlib import Pathfrom elftools.elf.elffile import ELFFilefrom unicorn import Uc, UC_ARCH_X86, UC_MODE_64, UC_PROT_ALLfrom unicorn.x86_const import UC_X86_REG_RBP, UC_X86_REG_RIP, UC_X86_REG_RSPFILE = Path(r\"H:\\UserMoved\\Downloads\\crackme_patched\")OUTPUT = Path(\"devirtualized.c\")DUMP = Path(\"bytecode_dump.bin\")START = 0x409002BYTECODE_READY = 0x40978FINPUT_BASE = 0x40F080STACK = 0x70000000PAGE = 0x1000MAX_SETUP_INSTRUCTIONS = 5_000_000OPERATORS = {    2: \"+\",    3: \"-\",    5: \"*\",    6: \"&amp;\",    7: \"|\",    8: \"^\",}def load_elf(file_name):    data = file_name.read_bytes()    elf = ELFFile(io.BytesIO(data))    segments = [segment for segment in elf.iter_segments() if segment[\"p_type\"] == \"PT_LOAD\"]    low = min(segment[\"p_vaddr\"] for segment in segments) &amp; -PAGE    high = (max(segment[\"p_vaddr\"] + segment[\"p_memsz\"] for segment in segments) + PAGE - 1) &amp; -PAGE    uc = Uc(UC_ARCH_X86, UC_MODE_64)    uc.mem_map(low, high - low, UC_PROT_ALL)    for segment in segments:        uc.mem_write(segment[\"p_vaddr\"], segment.data())    uc.mem_map(STACK, PAGE * 16, UC_PROT_ALL)    uc.reg_write(UC_X86_REG_RSP, STACK + PAGE * 16 - 8)    uc.reg_write(UC_X86_REG_RIP, START)    return ucdef capture_bytecode(file_name):    uc = load_elf(file_name)    for _ in range(MAX_SETUP_INSTRUCTIONS):        if uc.reg_read(UC_X86_REG_RIP) == BYTECODE_READY:            rbp = uc.reg_read(UC_X86_REG_RBP)            length = struct.unpack(\"&lt;i\", uc.mem_read(rbp - 0x1C, 4))[0]            if not 0 &lt; length &lt;= 0x10000:                raise RuntimeError(f\"invalid bytecode length: {length}\")            raw = bytes(uc.mem_read(rbp - 0x950, length * 4))            return list(struct.unpack(\"&lt;\" + \"I\" * length, raw))        uc.emu_start(uc.reg_read(UC_X86_REG_RIP), 0, count=1)    raise RuntimeError(\"bytecode initialization did not finish\")def bytecode_to_c(words):    c = []    ip = 0    while ip &lt; len(words):        opcode = words[ip]        comment = f\"    \/\/ bytecode {ip:04x}\"        if opcode == 0:            c.append(f\"    stack[++sp] = 0x{words[ip + 1]:08x};{comment}\")            ip += 2        elif opcode == 1:            c.append(f\"    --sp;{comment}\")            ip += 1        elif opcode in OPERATORS:            op = OPERATORS[opcode]            c.append(f\"    stack[sp - 1] = stack[sp - 1] {op} stack[sp]; --sp;{comment}\")            ip += 1        elif opcode == 9:            address = words[ip + 1]            c.append(                f\"    stack[++sp] = *((const uint8_t *)(uintptr_t)0x{address:08x});{comment}\"            )            ip += 2        elif opcode == 10:            c.append(f\"    stack[sp] = input[stack[sp] - 0x{INPUT_BASE:08x}];{comment}\")            ip += 1        else:            raise RuntimeError(f\"unknown VM opcode {opcode} at {ip:#x}\")    return cdef main():    words = capture_bytecode(FILE)    c_lines = bytecode_to_c(words)    DUMP.write_bytes(struct.pack(\"&lt;\" + \"I\" * len(words), *words))    OUTPUT.write_text(\"\\n\".join([        \"#include &lt;stdint.h&gt;\",        \"\",        \"__declspec(dllexport) uint32_t devirtualized(const uint8_t *input) {\",        \"    uint32_t stack[256];\",        \"    int sp = -1;\",        *c_lines,        \"    return stack[sp];\",        \"}\",        \"\",    ]), encoding=\"utf-8\")    print(f\"Dumped {len(words)} words to {DUMP}\")    print(f\"Disassembled {len(c_lines)} VM instructions\")    print(f\"Generated {OUTPUT}\")if __name__ == \"__main__\":    main()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0432 devirtualized.c, \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0435\u0433\u043e<\/p>\n<pre><code class=\"powershell\">clang-cl.exe \/LD \/O2 \/Fe:C:\\tmp\\devirtualized.dll C:\\tmp\\devirtualized.c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0432 \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0435 \u0438 \u0432\u0438\u0434\u0438\u043c<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5fc\/6df\/da9\/5fc6dfda9f2f20747cbbbe93d1dbfb9a.png\" alt=\"\u0414\u0435\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434\" title=\"\u0414\u0435\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434\" width=\"1216\" height=\"372\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/5fc\/6df\/da9\/5fc6dfda9f2f20747cbbbe93d1dbfb9a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5fc\/6df\/da9\/5fc6dfda9f2f20747cbbbe93d1dbfb9a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0414\u0435\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c 0<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4fe\/e14\/65e\/4fee1465efb270ecb4e66b0786c60c1e.png\" alt=\"\u041a\u0443\u0441\u043e\u043a \u0441 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0444\u043b\u0430\u0433\u0430\" title=\"\u041a\u0443\u0441\u043e\u043a \u0441 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0444\u043b\u0430\u0433\u0430\" width=\"850\" height=\"217\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/4fe\/e14\/65e\/4fee1465efb270ecb4e66b0786c60c1e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4fe\/e14\/65e\/4fee1465efb270ecb4e66b0786c60c1e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041a\u0443\u0441\u043e\u043a \u0441 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0444\u043b\u0430\u0433\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0438\u0448\u0435\u043c \u0440\u0435\u0448\u0430\u043b\u043a\u0443:<\/p>\n<pre><code class=\"python\">import structblocks = [    (0x0915033A, -0x41414141),    (0x427D7872, -0x11111111),    (0x30310A00, -0x55555555),    (0x2A052E32, -0x5A5A5A5A),    (0xCFF5ECDF,  0x55555556),    (0x1914031E, -0x77777777),    (0xF6F7C6AD,  0x66666667),    (0x6C6A524E, -0x33333333),]flag = b\"\"for xor_c, add_c in blocks:    need = (-add_c) &amp; 0xFFFFFFFF    val  = need ^ xor_c    # bswap \u2014 \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u043e\u0442 \u0431\u0430\u0439\u0442\u043e\u0432 uint32, struct \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u043c\u0435\u043d\u0443 endian    flag += struct.pack(\"&gt;I\", val)print(flag.decode())<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0443 \u043d\u0430\u0441 \u0444\u043b\u0430\u0433! <\/p>\n<p>\u041d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u2014 \u043f\u043e\u0447\u0435\u043c\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e \u0442\u0440\u0430\u0441\u0441\u0435 \u0437\u0434\u0435\u0441\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e.<\/p>\n<p>\u041f\u043e\u0432\u0435\u0437\u043b\u043e \u0434\u0432\u0430\u0436\u0434\u044b. \u041f\u0435\u0440\u0432\u043e\u0435: \u0432\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043b\u0435\u0436\u0438\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0412\u041c, \u0440\u044f\u0434\u043e\u043c \u0441 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0435\u0442. \u0415\u0441\u043b\u0438 \u0431\u044b \u0440\u044f\u0434\u043e\u043c \u0441 \u0412\u041c \u0431\u044b\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u043a\u043e\u0434\u0430, \u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043b\u0438\u0448\u044c \u043d\u0435\u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0434\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u043b\u0435\u0440\u043e\u043c: \u043d\u0438 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0439, \u043d\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432, \u043d\u0438 \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0435: \u043d\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432, \u043f\u043e\u0442\u043e\u043a \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0432\u0432\u043e\u0434\u0430 \u2014 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0434\u043d\u0430 \u0432\u044b\u0432\u0435\u0440\u0435\u043d\u043d\u0430\u044f \u0442\u0440\u0430\u0441\u0441\u0430 \u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u0430\u0440\u043e\u043b\u044f.<\/p>\n<p>\u0422\u0435 \u0436\u0435 \u0434\u0432\u0435 \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0438 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u0438 \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0431\u0430\u0439\u0442\u043a\u043e\u0434\u0443. \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442: \u043c\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0435\u0442\u043a\u0443 \u0432 \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0442\u043e\u0440 \u0431\u0430\u0439\u0442\u043a\u043e\u0434\u0430 \u0432 C \u2014 \u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0443 \u043c\u0435\u043d\u044f \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f. <\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1076974\/\">https:\/\/habr.com\/ru\/articles\/1076974\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0417\u0430\u0434\u0430\u043d\u0438\u0435: https:\/\/app.hackthebox.com\/challenges\/Callfuscated\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0438\u0448\u0443 \u044d\u0442\u043e\u041c\u0435\u043d\u044f \u0437\u0430\u0440\u0435\u0439\u0434\u0436\u0431\u0430\u0439\u0442\u0438\u043b\u0430 \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e \u0442\u0440\u0430\u0441\u0441\u0435, \u0431\u0435\u0437 \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430, MBA \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u00ab\u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u043a\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043a\u0443\u0440\u0441\u0430\u00bb \u2014 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c 2 \u043e\u043f\u043a\u043e\u0434\u0430 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u044b \u043d\u0435\u0432\u0435\u0440\u043d\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 \u043d\u0435 \u0432\u0441\u043f\u043b\u044b\u043b\u0430 \u0438\u0437-\u0437\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0430\u0441\u043a\u0430. \u0420\u0430\u0437\u0431\u0435\u0440\u0443 \u0438\u043d\u0430\u0447\u0435: \u0441\u0442\u0430\u0442\u0438\u043a\u043e\u0439, \u0441 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435\u043c MBA \u0438 \u0441\u043d\u044f\u0442\u0438\u0435\u043c \u043c\u0443\u0441\u043e\u0440\u0430.\u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c, \u0432\u0438\u0434\u0438\u043c \u044d\u0442\u043e:\u041a\u0430\u043a\u043e\u0439-\u0442\u043e \u0431\u0440\u0435\u0434\u041b\u0430\u0434\u043d\u043e, \u0435\u0441\u0442\u044c \u043a\u0443\u0447\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f Callfuscated, \u0430 \u0447\u0442\u043e \u0437\u0430 \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e arg_*? \u0422\u0430\u043a \u0438 \u043d\u0435 \u043f\u043e\u043d\u044f\u043b, \u043e\u0442\u043a\u0443\u0434\u0430 \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0438\u0445 \u0431\u0435\u0440\u0451\u0442. \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \u043b\u044e\u0431\u043e\u0439 \u0438\u0437 \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432\u0435\u0434\u0451\u0442 \u043a\u0443\u0434\u0430-\u0442\u043e \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0443 \u0442\u043e\u0433\u043e \u0436\u0435 main. \u0427\u0442\u043e-\u0442\u043e \u0442\u0443\u0442 \u043d\u0435 \u0442\u0430\u043a. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0410\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u041f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u0430\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439: call, pop r8 \u0438 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f. \u041f\u043e\u0442\u044b\u043a\u0430\u0435\u043c \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0443\u0436\u0435 \u0432 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0443\u0434\u0430 \u043e\u043d\u0438 \u0432\u0435\u0434\u0443\u0442; \u0437\u0430\u043c\u0435\u0447\u0430\u0435\u043c, \u0447\u0442\u043e call \u0432\u0435\u0434\u0451\u0442 \u043d\u0430 pop r8 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e, \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 call \u0432\u0435\u0434\u0451\u0442 \u043d\u0430 \u0442\u0443 \u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443. \u0412\u043e\u0442 \u0447\u0442\u043e \u043f\u043e \u0438\u0442\u043e\u0433\u0443 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:call 1; \u0446\u0435\u043b\u044c \u043a\u043e\u043b\u043b\u0430 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0437\u0430 \u043d\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043b1:pop r8; \u0447\u0442\u043e-\u0442\u043ecall 22:pop r8; \u0447\u0442\u043e-\u0442\u043e; \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435call \u043a\u043b\u0430\u0434\u0451\u0442 \u043d\u0430 \u0441\u0442\u0435\u043a \u0430\u0434\u0440\u0435\u0441 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, pop r8 \u0442\u0443\u0442 \u0436\u0435 \u0435\u0433\u043e \u0441\u043d\u0438\u043c\u0430\u0435\u0442. \u0421\u0442\u0435\u043a \u0432 \u0438\u0442\u043e\u0433\u0435 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f, \u0438\u0441\u043f\u043e\u0440\u0447\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e r8. \u0415\u0441\u043b\u0438 r8 \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0435 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u2014 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u043c\u0438 jmp, \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432 \u0434\u0432\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u0430\u0436\u0435\u043c, \u0447\u0442\u043e r8 \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044fimport ioimport structfrom pathlib import Pathfrom capstone import Cs, CS_ARCH_X86, CS_MODE_64from elftools.elf.elffile import ELFFilefrom unicorn import Uc, UC_ARCH_X86, UC_MODE_64, UC_PROT_ALLfrom unicorn.x86_const import (    UC_X86_REG_R8, UC_X86_REG_RAX, UC_X86_REG_RDI,    UC_X86_REG_RIP, UC_X86_REG_RSI, UC_X86_REG_RSP,)FILE = Path(r&#187;crackme&#187;)START, STOP = 0x409002, 0x60000000STACK, PAGE = 0x70000000, 0x1000SRAND, SCANF, RAND = 0x401050, 0x401060, 0x401070IMPORTS = {0x401030, 0x401040, SRAND, SCANF, RAND}MAX_INSTRUCTIONS = 2_000_000def rng(seed):    s = [seed &amp; 0xffffffff or 1]    for _ in range(30):        s.append(16807 * s[-1] % 2147483647)    s += s[:3]    for i in range(34, 344):        s.append((s[i &#8212; 31] + s[i &#8212; 3]) &amp; 0xffffffff)    return sdef ret(uc):    rsp = uc.reg_read(UC_X86_REG_RSP)    uc.reg_write(UC_X86_REG_RSP, rsp + 8)    uc.reg_write(UC_X86_REG_RIP, struct.unpack(&#171;&lt;Q&#187;, uc.mem_read(rsp, 8))[0])data = FILE.read_bytes()elf = ELFFile(io.BytesIO(data))segments = [s for s in elf.iter_segments() if s[&#171;p_type&#187;] == &#171;PT_LOAD&#187;]lo = min(s[&#171;p_vaddr&#187;] for s in segments) &amp; -PAGEhi = (max(s[&#171;p_vaddr&#187;] + s[&#171;p_memsz&#187;] for s in segments) + PAGE &#8212; 1) &amp; -PAGEuc = Uc(UC_ARCH_X86, UC_MODE_64)uc.mem_map(lo, hi &#8212; lo, UC_PROT_ALL)for segment in segments:    uc.mem_write(segment[&#171;p_vaddr&#187;], segment.data())uc.mem_map(STACK, PAGE * 16, UC_PROT_ALL)uc.mem_map(STOP, PAGE, UC_PROT_ALL)rsp = STACK + PAGE * 16 &#8212; 8uc.mem_write(rsp, struct.pack(&#171;&lt;Q&#187;, STOP))uc.reg_write(UC_X86_REG_RSP, rsp)uc.reg_write(UC_X86_REG_RIP, START)cs = Cs(CS_ARCH_X86, CS_MODE_64)cs.detail = Truestate = Nonereads = set()executed = 0while uc.reg_read(UC_X86_REG_RIP) != STOP:    rip = uc.reg_read(UC_X86_REG_RIP)    if executed &gt;= MAX_INSTRUCTIONS:        raise RuntimeError(&#171;instruction limit exceeded&#187;)    if rip == SRAND:        state = rng(uc.reg_read(UC_X86_REG_RDI))        ret(uc)        continue    if rip == RAND:        if state is None:            raise RuntimeError(&#171;rand before srand&#187;)        value = (state[-31] + state[-3]) &amp; 0xffffffff        state.append(value)        uc.reg_write(UC_X86_REG_RAX, value &gt;&gt; 1)        ret(uc)        continue    if rip == SCANF:        uc.mem_write(uc.reg_read(UC_X86_REG_RSI), b&#187;A&#187; * 63 + b&#187;\\0&#8243;)        uc.reg_write(UC_X86_REG_RAX, 1)        ret(uc)        continue    if rip in IMPORTS:        ret(uc)        continue    ins = next(cs.disasm(bytes(uc.mem_read(rip, 15)), rip, count=1))    if any(cs.reg_name(reg).lower() in {&#171;r8&#187;, &#171;r8d&#187;, &#171;r8w&#187;, &#171;r8b&#187;}           for reg in ins.regs_access()[0]):        reads.add(rip)    uc.emu_start(rip, 0, count=1)    executed += 1print(f&#187;executed: {executed}&#187;)print(f&#187;r8 reads: {len(reads)}&#187;)if reads:    print(&#171;addresses:&#187;, &#171;, &#171;.join(f&#187;{address:#x}&#187; for address in sorted(reads)))\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:executed: 186802r8 reads: 0\u0414\u043e\u043a\u0430\u0437\u0430\u043b\u0438.\u0412 \u0441\u0430\u043c\u043e\u043c call \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0431\u0430\u0439\u0442: call rel32 (E8) \u0438 jmp rel32 (E9) \u043e\u0434\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0438 \u0441\u0447\u0438\u0442\u0430\u044e\u0442 \u0430\u0434\u0440\u0435\u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e, \u043e\u0442 \u043a\u043e\u043d\u0446\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u041c\u0435\u043d\u044f\u0435\u043c \u043e\u043f\u043a\u043e\u0434 \u2014 \u0446\u0435\u043b\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f. pop r8 (41 58) \u0437\u0430\u0431\u0438\u0432\u0430\u0435\u043c \u0434\u0432\u0443\u043c\u044f nop. \u0421\u043d\u0438\u043c\u0430\u0435\u043c \u043c\u0443\u0441\u043e\u0440\u042f \u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043b, \u043a\u0430\u043a \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0438\u0448\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043eimport iofrom pathlib import Pathfrom capstone import Cs, CS_ARCH_X86, CS_MODE_64from capstone.x86 import X86_OP_IMMfrom elftools.elf.elffile import ELFFileFILE = Path(r&#187;crackme&#187;)OUT = FILE.with_name(FILE.name + &#171;_patched&#187;)original = FILE.read_bytes()patched = bytearray(original)elf = ELFFile(io.BytesIO(original))segments = [s for s in elf.iter_segments() if s[&#171;p_type&#187;] == &#171;PT_LOAD&#187;]def file_offset(address):    segment = next(        s for s in segments        if s[&#171;p_vaddr&#187;] &lt;= address &lt; s[&#171;p_vaddr&#187;] + s[&#171;p_filesz&#187;]    )    return segment[&#171;p_offset&#187;] + address &#8212; segment[&#171;p_vaddr&#187;]cs = Cs(CS_ARCH_X86, CS_MODE_64)cs.detail = Truecount = 0for segment in segments:    if not segment[&#171;p_flags&#187;] &amp; 1:        continue    for instruction in cs.disasm(segment.data(), segment[&#171;p_vaddr&#187;]):        if instruction.mnemonic != &#171;call&#187;:            continue        operand = instruction.operands[0]        if operand.type != X86_OP_IMM:            continue        target = operand.imm        try:            target_offset = file_offset(target)        except StopIteration:            continue        is_pop_r8 = original[target_offset:target_offset + 2] == b&#187;\\x41\\x58&#8243;        if not is_pop_r8:            continue        call_offset = file_offset(instruction.address)        patched[call_offset] = 0xE9                 # call -&gt; jmp        patched[target_offset:target_offset + 2] = b&#187;\\x90\\x90&#8243;        count += 1        print(f&#187;{instruction.address:#x}: call -&gt; jmp, {target:#x}: pop r8 -&gt; nop nop&#187;)OUT.write_bytes(patched)print(f&#187;\u0413\u043e\u0442\u043e\u0432\u043e: {OUT} ({count} \u043f\u0430\u0442\u0447\u0435\u0439)&#187;)\u0414\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c, \u0438 \u0432\u0438\u0434\u0438\u043c \u044d\u0442\u043e:\u0427\u0438\u0441\u0442\u044b\u0439 main\u0414\u0430 \u044d\u0442\u043e \u0436\u0435 \u0412\u041c! \u0423\u0437\u043d\u0430\u0451\u0442\u0441\u044f \u043f\u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u043e\u043c\u0443 while (true): \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u043e\u043f\u043a\u043e\u0434) \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442, \u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u0441\u0432\u043e\u0439 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 \u2014 \u0445\u0435\u043d\u0434\u043b\u0435\u0440. \u0420\u0430\u0437\u0431\u043e\u0440 \u0412\u041c\u0422\u0443\u0442 \u043e\u0431\u044b\u043a\u043d\u043e\u0432\u0435\u043d\u043d\u0430\u044f \u0441\u0442\u0435\u043a\u043e\u0432\u0430\u044f \u0412\u041c, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c \u0435\u0451 \u0438 \u0432\u0438\u0434\u0438\u043c \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u044b \u0441 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:\u0425\u0435\u043d\u0434\u043b\u0435\u0440\u044b \u0441 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439\u0421\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0441\u0435\u043b\u043e\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0437 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430 \u21162\u0410 \u0432\u043e\u0442 \u0438 \u043e\u0431\u0435\u0449\u0430\u043d\u043d\u0430\u044f MBA. \u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c\u0441\u044f \u043a \u043a\u043e\u0434\u0443 2 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f rand \u0432 \u0434\u0432\u0443\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u0432\u044b\u0437\u043e\u0432\u0430, \u044d\u0442\u043e \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u043e\u0431\u0435\u0449\u0430\u043d\u043d\u044b\u0435 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442\u044b\u0420\u0435\u0448\u0430\u0435\u043c MBA\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442: MBA \u2014 \u044d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (\u0441\u043b\u043e\u0436\u0435\u043d\u0438\u0435, XOR \u0438 \u0442\u0434) \u043d\u0430 \u0440\u0430\u0437\u0434\u0443\u0442\u044b\u0435 \u0433\u0438\u0433\u0430\u043d\u0442\u0441\u043a\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0423 \u043d\u0430\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 MBA \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u043b\u0430\u0434\u0451\u0442\u0441\u044f \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0443 \u0441\u0442\u0435\u043a\u0430 \u043a\u0430\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u043f\u043a\u043e\u0434\u0430, \u0430 \u043e\u043f\u043a\u043e\u0434 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u2014 \u044d\u0442\u043e \u043e\u0434\u043d\u0430 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f. \u0417\u043d\u0430\u0447\u0438\u0442, \u0437\u0430 \u0434\u0435\u0440\u0435\u0432\u043e\u043c \u043d\u0430 \u0441\u043e\u0442\u043d\u0438 \u0443\u0437\u043b\u043e\u0432 \u043f\u0440\u044f\u0447\u0435\u0442\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 a + b.\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 MBA \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u0430 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c-\u0442\u043e \u0431\u0443\u0434\u0435\u043c? \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b simplify() \u0438\u0437 Triton: \u043d\u0435 \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0441\u044f. \u041f\u043e\u0442\u043e\u043c GAMBA \u2014 \u0442\u043e\u0436\u0435 \u043c\u0438\u043c\u043e. \u0420\u0430\u0437\u043e\u0431\u0440\u0430\u0432\u0448\u0438\u0441\u044c, \u043f\u043e\u043d\u044f\u043b \u043f\u043e\u0447\u0435\u043c\u0443: Triton \u2014 \u043d\u0435 MBA-\u0441\u043e\u043b\u0432\u0435\u0440, \u0430 GAMBA \u0437\u0430\u0442\u043e\u0447\u0435\u043d \u043f\u043e\u0434 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b MBA. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043d\u0430\u0433\u0443\u0433\u043b\u0438\u043b CoBRA \u2014 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u0448\u0430\u043b\u043a\u0443 MBA, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u0447\u0435\u043c GAMBA. \u041e\u043d\u0430 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430, \u043f\u0440\u043e \u043d\u0435\u0451 \u0438 \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c.\u0412 \u043d\u0435\u0451 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u2014 \u043d\u0443\u0436\u0435\u043d \u043b\u0438\u0444\u0442. \u0422\u0443\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u043b\u0441\u044f Triton: \u043e\u043d \u0443\u043c\u0435\u0435\u0442 \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0438 \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0442\u0434\u0430\u0442\u044c AST-\u0444\u043e\u0440\u043c\u0443\u043b\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 \u0438\u043b\u0438 \u044f\u0447\u0435\u0439\u043a\u0438 \u043f\u0430\u043c\u044f\u0442\u0438. Triton \u0442\u0443\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0438\u0444\u0442\u0435\u0440: \u0441\u0442\u0440\u043e\u0438\u0442 AST, \u0430 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0443\u0436\u0435 CoBRA. \u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c\u041d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430. \u0412\u043e\u0442 \u043a\u043e\u0434, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b:import ioimport sysimport subprocessfrom pathlib import Pathfrom elftools.elf.elffile import ELFFilefrom triton import ARCH, Instruction, MemoryAccess, OPCODE, TritonContextsys.path.insert(0, str(Path(__file__).resolve().parent))from triton_to_cobra import triton_ast_to_cobraFILE = Path(r&#187;crackme_patched&#187;)COBRA = Path(r&#187;cobra-cli.exe&#187;)HANDLERS = {    0x401166: 4,    0x401F18: 4,    0x4025D8: 2,    0x4050AA: 2,    0x405C1F: 2,    0x406E47: 2,    0x4080D6: 2,}COBRA_MAX_VARS = 20REGISTERS = (&#171;rdi&#187;, &#171;rsi&#187;, &#171;rdx&#187;, &#171;rcx&#187;)def symbolic_formula(address, argc, segments):    ctx = TritonContext(ARCH.X86_64)    for segment in segments:        ctx.setConcreteMemoryAreaValue(segment[&#171;p_vaddr&#187;], segment.data())    for name in REGISTERS[:argc]:        ctx.symbolizeRegister(getattr(ctx.registers, name), name)    ctx.setConcreteRegisterValue(ctx.registers.rsp, 0x70000000)    ctx.setConcreteMemoryValue(MemoryAccess(0x70000000, 8), 0)    ctx.setConcreteRegisterValue(ctx.registers.rip, address)    for count in range(100000):        rip = ctx.getConcreteRegisterValue(ctx.registers.rip)        instruction = Instruction(rip, bytes(ctx.getConcreteMemoryAreaValue(rip, 16)))        ctx.processing(instruction)        if instruction.getType() == OPCODE.X86.RET:            ast = ctx.getAstContext().extract(31, 0, ctx.getRegisterAst(ctx.registers.rax))            return ctx.getAstContext().unroll(ast), count + 1    raise RuntimeError(f&#187;sub_{address:x}: ret not found&#187;)data = FILE.read_bytes()elf = ELFFile(io.BytesIO(data))segments = [segment for segment in elf.iter_segments() if segment[&#171;p_type&#187;] == &#171;PT_LOAD&#187;]for address, argc in HANDLERS.items():    print(f&#187;sub_{address:x}: Triton&#8230;&#187;, flush=True)    formula, instructions = symbolic_formula(address, argc, segments)    try:        expression = triton_ast_to_cobra(formula)    except ValueError as error:        print(f&#187;  SUPEROP\/unsupported by CoBRA grammar: {error}&#187;, flush=True)        continue    print(f&#187;  {instructions} instructions, {len(expression)} chars; CoBRA full AST&#8230;&#187;, flush=True)    input_path = Path(f&#187;sub_{address:x}.mba&#187;)    input_path.write_text(expression, encoding=&#187;ascii&#187;)    process = subprocess.run(        [str(COBRA), &#171;&#8212;mba-file&#187;, str(input_path), &#171;&#8212;bitwidth&#187;, &#171;32&#187;, &#171;&#8212;max-vars&#187;, str(COBRA_MAX_VARS)],        text=True,        capture_output=True,        timeout=600,    )    if&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-493011","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/493011","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=493011"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/493011\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=493011"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=493011"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=493011"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}