منظره مهندسی معکوس: تاریخچه، خانواده های ابزار و نحوه ساخت یک دستگاه تخفیف
Type: Build
Languages: Python, C, x86-64 assembly, Java (one Ghidra script)
Prerequisites: Phase 13 · 32 (ELF from scratch), Phase 13 · 33 (disassembly and control flow), Phase 13 · 34 (lifting to pseudocode)
Time: ~150 minutes
اهداف یادگیری
- ابزار اصلی این زمینه را بر روی یک جدول زمانی از سال ۱۹۷۳ تا ۲۰۲۶ قرار دهید و نام خانواده ای را که هر کدام از آنها متعلق به آن هستند نام دهید.
- هشت مرحله ی یک decompiler و اصطلاحی که Ghidra، Binary Ninja، Hex-Rays، radare2، rizin و angr برای هر مرحله استفاده می کنند را نام دهید.
- یک دستورالعمل را به ESIL، RzIL، P-code و VEX ببرید و توضیح دهید که کدام یک از آنها پرچم را با مشتاقانه می نویسند و کدام یک یک را ذخیره می کنند.
- آدرس پنج ابزار را به یک نفر کاهش دهید
.textتعویض و اثبات کاهش در یک تابع. - یک آرم مقایسه بسازید که خروجی ابزار ضبط شده را می خواند و گزارش توافق در شروع دستورالعمل، بلوک ها، لبه ها و شروع عملکرد را می دهد.
- نام، از شواهد ضبط شده، جایی که هر ابزار کد را اختراع می کند، کد را از دست می دهد، یا در یک پرش غیر مستقیم متوقف می شود.
مشکل
از يه مامور ميخواي خلاصه کنه که سه ابزار مهندسی معکوس درباره چي ميگنgradeدرledger-x86_64-O1.o. آژانس هر ابزار را اجرا می کند، سه لیست را می خواند و گزارش می دهد که عملکرد در 0x08000050در یک ابزار،0x400010در یکی دیگر و0x100010در سوم این نتیجه می رسد که ابزارها در مورد محل عملکرد اختلاف دارند.
ابزارها موافقند. این شی قابل انتقال است و هیچ آدرس بارگذاری ندارد، بنابراین هر ابزار یکی را انتخاب می کند. آدرس هر ابزار داده شده را حذف کنید .textو هر جوابي0x10مامور آدرس هاي خام رو با هم مقایسه کرد چون هيچ چيزي به اون نمي گفت آدرس در هر ابزار چيه
بعد همون مامور ميگهgradeدر-O0ساخت و گزارش بلوک های پایه ۳، ۸، ۸ و ۹ از چهار ابزار. همه چهار عدد واقعی هستند. یک ابزار متوقف شده در jmp raxدو ابزار جدول پرش را از طریق نقل مکان های آن می خوانند. یک ابزار یک بلوک را در پرش تقسیم می کند تا برچسب را قرار دهد. تعداد بلوک بدون دلیل پشت آن یک عدد بدون ادعای است.
این درس نقشه ای است که قبل از اینکه به هر یک از این اعداد اعتماد کنید نیاز دارید. دروس 32 تا 36 یک دیکودر، یک لیفتر، یک ثبت شواهد و یک بازسازی ساختند. نیمه دوم مسیر آنها را کنار ابزار استفاده شده قرار می دهد. برای انجام این کار شما نیاز به تاریخچه میدان، خانواده هایی که ابزارها به آن تعلق دارند، خط لوله هر decompiler اجرا می شود، و یک هرنس که آنچه ابزارها در مورد اشیاء که شما خودتان مرتب کرده اید می گویند را مقایسه کند.
پنجاه و سه سال در مراحل تاریخ
این زمینه از اکثر ابزارها قدیمی تر است. هر تاریخ زیر دارای منبع اصلی در ادامه خواندن است.
1973 تا 1991: اول debuggers، سپس جداسازی
اولین پایان نامه های تجزیه و تحلیل از سال 1973 است. هولندر در استنفورد و هوزل در پردو آنها را نوشتند و هر دو امروزه از طریق نقل قول شناخته می شوند. ابزار عملی دوره ها debuggers بودند. مارانزانو و بورن نوشتند adbدر سال 1977 در آزمایشگاه بل، و در سال 1979 با UNIX V7 عرضه شد.DEBUG، با یک جداکننده 8086 ، در PC-DOS 1.00 در اوت 1981 عرضه شد. GDB ریچارد استالمن در سال 1986 وارد توزیع شد. SoftICE یک دیبگر هسته را در سال 1987 در DOS قرار داد.
بعد از آن، دستگاه های جداسازی دسته ای به کار آمدند. سوئرسر، از V Communications در سال 1988، چندین گذر از یک برنامه DOS را اجرا کرد و یک لیست اظهار نظر نوشت. دوتاژ GNU با عکس های غیرم شماری در سال 1988 شروع شد و در سال 1988 به کار خود ادامه داد.objdumpIlfak Guilfanov اولین خط IDA را در ژانویه 1991 نوشت و IDA 0.1 را به عنوان برنامه مشترک در 20 مه 1991 منتشر کرد.
1991 تا 2009: جداکننده های تعاملی و اولین جداکننده ها
کریستینا سیفوانتز در ژوئیه 1994 "تکنولوژی های جمع آوری معکوس" را در QUT تکمیل کرد.dccدر سال 1995، او با گوف مراحل را تعیین کرد که هر کدوم از کپیگرهای بعدی در سال 1997 و Boomerang در سال 2002 دنبال کردند. اولین کپیگر منبع باز تحت مجوز BSD.
IDA در سال 1996 به یک محصول تجاری در DataRescue تبدیل شد، در سال 1999 یک SDK افزونه را به دست آورد و به Hex-Rays که در سال 2005 تاسیس شد، نقل مکان کرد. Hex-Rays Decompiler 1.0 در 17 سپتامبر 2007 عرضه شد. در همان سال مایک وان امریک "تعهد واحد ای آماری برای تجزیه و تحلیل" را ارائه داد، پایان نامه ای که SSA را در مرکز جریان داده های تجزیه کننده قرار داد. "مقارنة هنداری از اشیاء قابل اجرا" (۲۰۰۴) هالوار فلاک، خانواده ی مختلف را آغاز کرد و بن دیف در اوت ۲۰۰۴ به فروش رسید.
radare در فوریه 2006 به عنوان یک ویرایشگر هیکس قانونی با 64 بیت تعویض آغاز شد. radare2 ، نسخه ی ماژولار تحت LGPL-3.0 ، اولین نسخه ی خود را در 7 مارس 2009 منتشر کرد.
2009 تا 2019: چارچوب ها و نمایندگی های میانگین
LLDB به عنوان یک زیر پروژه LLVM در 8 ژوئن 2010 اعلام شد. BAP، پلتفرم تجزیه و تحلیل دوگانه با زبان میانگین BIL خود، در CAV 2011 ظاهر شد. گوگل زینامیک، سازندگان BinDiff را در 1 مارس 2011 خریداری کرد. هاپر در Mac App Store در اواخر 2011 ظاهر شد. مت گودبولت در سال 2012 کمپایلر اکسپلورر را راه اندازی کرد تا یک برنامه نویس C ++ بتواند مجموعه ای را که یک کمپایلر تولید کرده است ببیند.
این در حالی است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این در نظر گرفته شده است که این است که این در نظر گرفته شده است که این است که این در نظر گرفته شده است که این است که این است که این است که این است که این است که این است که این است که این است که در نظر داشته باشد که این است که این است که این است که این است که این است که این است که این است که این است که این است که این است که در نظر داشته باشد که این است که این است که این است که این است که این است که این است که این است که این است که این است که این است که چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چه چهgotoدر این گزارش، در این گزارش آمده است که در این گزارش، در حال حاضر در حال بررسی و بررسی اطلاعات مربوط به 8،676 تابع است.gotoاظهارات با ساختار مستقل از الگوی. ویکتور 35 در 14 ژانویه 2015 تاسیس شد و Binary Ninja در 23 ژوئیه 2016 با سطح پایین IL و API پایتون به فروش رسید. این برنامه در سال 2015 به طور عمومی منتشر شد و در ماه اوت 2016 در DARPA Cyber Grand Challenge رتبه سوم را به دست آورد. بین دیف در مارس 2016 رایگان شد. Cutter 1.0 در دسامبر 2017 به radare2 یک GUI Qt داد. در سال 2018 گیلفانوف "داخل های Decompiler: میکروکود" را در ریکون ارائه کرد، اولین توصیف عمومی از Hex-Rays IR.
2019 تا 2026: تجزیه کننده های باز و نوبت تحقیقات
Ghidra 9.0 توسط NSA در کنفرانس RSA در 5 مارس 2019 تحت Apache-2.0 منتشر شد، با منبع کامل در GitHub یک ماه بعد. در این سال، در بخش 8.19.2.4 یک decompiler اولیه اضافه شد. باینری نینجا 2.0 در 20 مه 2020، دیکومپلر IL سطح بالا خود را ارسال کرد. رزین به عنوان یک شکاف رادار2 در 8 دسامبر 2020 اعلام شد و تیم کتر به آن نقل مکان کرد. IDA Freeware 7.6 یک decompiler x64 ابر را در ماه مه 2021 اضافه کرد.
BinDiff 8 در 25 سپتامبر 2023 تحت Apache-2.0 به منبع باز عرضه شد. SAILR (Basque و دیگران، USENIX Security 2024) به عنوان ساختار دهنده پیش فرض angr تبدیل شد و استدلال کرد که فقط دروغین است.gotoبیانات باید حذف شود، زیرا لینوکس 6.1 دارای 3754 مورد از آنها در منبع خود است. Binary Ninja 4.0 نسخه رایگان را در فوریه 2024 اضافه کرد و IDA 9.0 اضافه شد idalibبرای استفاده بدون سر. مقاله های آموخته شده از SLaDe (2023) تا LLM4Decompile (2024) تا DecompileBench (2025) و دو مطالعه 2026 در مورد قابلیت خواندن با کمک عامل و بر روی decompileers که بیشتر را جمع آوری و حفظ کمتر.
نسخه های اجرا شده این درس در تاریخ 14 اکتبر 2026 هستند: Ghidra 12.1.4 (21 سپتامبر 2026) ، radare2 6.2.4 (5 اکتبر 2026) ، rizin 0.9.1 (29 ژوئن 2026) و angr 10.0.3 (10 اکتبر 2026). Binary Ninja 6.0 "Krypton" (3 سپتامبر 2026) و IDA 9.4 (13 ژوئیه 2026) ابزارهای فعلی بسته هستند. این درس آنها را اجرا نکرد.
خانواده های ابزار
یک ابزار به خانواده تعلق دارد به خاطر آنچه تولید می کند. خانواده ها در یک برنامه همپوشیده می شوند و همپوشیدن جایی است که بیشتر سردرگمی شروع می شود.
دستگاه های جداسازی
یک پاکش خطی از اولین بایت یک بخش کد تا آخرین کد را رمزگذاری می کند.objdump -dوllvm-objdump -dاین روش کار می کند و هیچ یک از آنها یک گراف کنترل جریان را ایجاد نمی کند.objdumpبا این حال، با استفاده از این ابزار، با استفاده از سیستم عامل های مختلف، به طور کامل به عنوان یک سیستم عامل قابل استفاده استفاده می شود.llvm-objdumpبه عنوان "آپل LLVM نسخه 17.0.0"، و این نسخه این درس گرفته شده است.
یک جداکننده تعاملی، کاهش تکراری از ورودی های شناخته شده را اجرا می کند، هوریستیک را برای شروع عملکرد اضافه می کند و یک پایگاه داده را حفظ می کند.Disassemblerعلاوه بر تحلیلگرهای خودکار، نینجا دوگانه (هبوط مکرر، سپس لاینری در مناطق ناشناخته) ، هاپر، رادار2 و ریزین (aa،aaa،afآندریس و دیگران (USENIX Security 2016) ۹ عدد از آنها را بر روی دوگانه های تولید شده توسط سازنده اندازه گیری کردند. دقت دستورالعمل نزدیک به ۱۰۰ درصد بود و عملکرد سخت اولیه شروع می شد، با نرخ منفی نادرست ۲۰ درصد یا بیشتر.
دستگاه های تجزیه
Decompiler های تجاری: Hex-Rays Decompiler (دوازده خانواده هدف از x86 تا RISC-V) ، HLIL Binary Ninja با نمایش Pseudo C خود و نمایش کد نامزدی Hopper. پیکربندی باز: پیکربندی Ghidra، یک موتور C ++ تحت Apache-2.0 که r2ghidra و rz-ghidra به عنوان افزونه استفاده می کنند و pypcode به عنوان یک بلند کننده استفاده می کند؛ پیکربندی Angr در AIL با ساختار SAILR تحت BSD-2-Clause؛ r2dec و jsdec در جاوا اسکریپت؛ بومرنگ و dccبه عنوان سابقه. رادار2 هم يه دستگاه ساخته شده دارهpdc، "پسیدو ازمایشگر در ترکیب شبیه به C" ریزین هیچ دیکامپلر داخلی نداردpdcدر رزین 0. 9. 1 وجود ندارد وpdgبه پلاگین rz-ghidra نیاز داره
بازیافت کننده
GDB (1986) با GEF و pwndbg front-end، LLDB (2010), WinDbg با Time Travel Debugging (2017), OllyDbg (در سال 2014 منجمد شده) ، x64dbg (GPL-3.0, 2014), Ghidra Debugger با رابط های پایتون، Debugger Binary Ninja و دیبگرهای داخلی radare2 و rizin. درس 42 از دو مورد را در ساخت های خود استفاده می کند.
چارچوب های تجزیه و تحلیل دوگانه
angr (VEX IR، اجرای نمادین، CFGFastوCFGEmulatedاین فریم ورک ها را اندریسه نامگذاری کرد. Ghidra یک کتابخانه از طریق PyGhidra، Binary Ninja از طریق import binaryninja، و از طریق IDAidalib. .
کتابخانه های فرمت و موتور
LIEF 1.0.0 (12 ژوئیه 2026, Apache-2.0) ELF، PE، Mach-O، COFF و فرمت های اندروید را تجزیه و تحلیل می کند. CLE، "CLE Loads Everything" بارگذاری کننده Angr است. Capstone 5.0.9 (28 مه 2026, BSD-3-Clause) رمزگذاری می کند. Keystone 0.9.2 (GPL-2.0) مجموعه ها؛ Unicorn 2.1.4 (GPL-2.0) شبیه سازی می کند. radare2 6.2.4 بسته های Capstone 5 و rizin 0.9.1 فروشندگان Capstone، Zydis و درخت-sitter.
ابزار های دفینگ و بیننده های طرفی سازنده
BinDiff 8 (Apache-2.0) با افزونه BinExport 12 برای IDA Pro، Binary Ninja و Ghidra؛ Diaphora 3.4.3 (11 اکتبر 2026, AGPL-3.0) به عنوان افزونه IDA؛radiff2وrz-diff. اکسپلورر کامپیلر (BSD-2-Clause) مجموعه ای را نشان می دهد که کامپیلر برای یک قطعه منبع منتشر می کند، که جهت پیشروی همه چیز دیگر در این لیست است. درس 44 از خانواده متفاوت استفاده می کند.
نسخه ها، مجوزها و آنچه در این درس بود
| Tool | Version read on 2026-10-14 | Licence | Headless entry | Ran here |
|---|---|---|---|---|
| Ghidra | 12.1.4 | Apache-2.0 | analyzeHeadless, pyghidra.start() | yes, on all four objects |
| radare2 | 6.2.4 | LGPL-3.0 | r2 -qc '<cmds>' file, rabin2 | yes |
| rizin | 0.9.1 | LGPL-3.0 | rizin -qc '<cmds>' file, rz-bin | yes |
| angr | 10.0.3 | BSD-2-Clause | angr.Project in Python | yes |
| llvm-objdump | Apple LLVM 17.0.0 | Apache-2.0 with LLVM exception | llvm-objdump -d -r | yes |
| Binary Ninja | 6.0 "Krypton" | commercial; Free edition for non-commercial use | binaryninja.load() with a Commercial, Ultimate, or headless licence | no, documentation only |
| IDA Pro | 9.4 | commercial subscription; IDA Free for non-commercial x86 and x86-64 | idat, ida -A -S, idalib | no, documentation only |
| Hopper | 6.6.0 | commercial, perpetual | none documented | no, documentation only |
| Cutter | 2.5.0 | GPL-3.0 | GUI over rizin | no |
نسخه رایگان از Binary Ninja فقط x86, x86-64, ARMv7 و AArch64 را تجزیه می کند و هیچ API ندارد. IDA Free هیچ IDAPython، هیچ SDK و هیچ idalibهر جمله ای در مورد این دو ابزار در این درس از اسناد و یادداشت های انتشار آنها می آید و این رقم آنها را نشان می دهد که اجرا نشده است.
خط لوله ی Decompiler، مرحله به مرحله
سیفوانتس در سال ۱۹۹۴ این مراحل را نامید: تجزیه و تحلیل نحوی، تجزیه و تحلیل معنوی، تولید کد متوسط، تولید گراف جریان کنترل، تجزیه و تحلیل جریان داده، تجزیه و تحلیل جریان کنترل و تولید کد. او آنها را به یک فرنت کنترلی وابسته به ماشین، یک وسط مستقل از ماشین و زبان و یک پشت کنترلی وابسته به زبان تقسیم کرد. از اون موقع هر کليد بازيابي اين شکل رو حفظ کرده و نامي به قسمت ها ميده جدول زیر هشت مرحله ای را که در این درس استفاده می شود و نام هر ابزار را به آنها می دهد، نشان می دهد. این نمودار همان جدول را با ستون های ابزار انتخاب می کند.
| Stage | Ghidra | Binary Ninja | Hex-Rays / IDA | radare2 | rizin | angr |
|---|---|---|---|---|---|---|
| Loader | ElfLoader, MachoLoader, PeLoader; .ldefs picks the language | BinaryView, BinaryViewType | loader module (LDSC) | RBin (rabin2) | RzBin (rz-bin) | CLE (cle.Loader, main_object) |
| Disassembly | Disassembler; SLEIGH .slaspec compiled to .sla; analyzers "Disassemble Entry Points", "Function Start Search" | architecture plugin; Recursive Descent, then linear sweep phases | processor module (ana.cpp, emu.cpp, out.cpp); autoanalysis queues; FLIRT | RArch plugin to RAnalOp; aa, aaa, af | RzAnalysis plugin; aa, aaa, af | Capstone blocks; CFGFast function start search |
| CFG recovery | "Generate Basic Blocks and the CFG"; BlockGraph; "Decompiler Switch Analysis" | Function, BasicBlock; "Control Flow Graph (CFG) Analysis" phase | mbl_graph_t, ready at MMAT_LOCOPT | afb, agf, aab | afb, agf, aab (Nucleus) | CFGFast, CFGEmulated; kb.functions; IRSB |
| Lifting | "Generate Raw P-code"; Varnodes in ram, register, const, unique | Lifted IL, LLIL, Mapped MLIL, MLIL | microcode (minsn_t, mop_t); MMAT_GENERATED | ESIL (asm.esil, ae) | RzIL (aoi, aez) | VEX (pyvex.lift, IRSB), then AIL |
| SSA | Heritage, ActionHeritage; MULTIEQUAL, INDIRECT | LLIL SSA, MLIL SSA, HLIL SSA; HLIL_VAR_PHI | no named SSA; use-def data flow in MMAT_GLBOPT1 to 3 | none; ESIL is built for emulation | none; RzIL is built for emulation | _stage_transform_to_ssa_level0 and level1; SeqNodeDephication |
| Data flow and types | ActionDeadCode, ActionInferTypes, the Rule pool; prototype from .cspec | MLIL constant propagation, variables and types; analyzeReturns | "Transform microcode"; MMAT_CALLS, MMAT_GLBOPT, MMAT_LVARS; TIL | afv, afc, aaft; ESIL emulation | afv, afc, aft | CallingConventionAnalysis, VariableRecoveryFast, Typehoon |
| Structuring | CollapseStructure; BlockIf, BlockWhileDo, BlockSwitch, BlockGoto | HLIL_IF, HLIL_WHILE, HLIL_SWITCH; AST at root | "Generate ctree"; structural analysis; goto regions | pdc; pdd (r2dec); pdg (r2ghidra) | pdg (rz-ghidra); jsdec | RegionIdentifier; RecursiveStructurer with SAILRStructurer |
| Emission | "Emit Final C Tokens"; PrintC, ActionNameVars, ActionSetCasts | HLIL rendering; Pseudo C, Pseudo Rust, Pseudo Python | "Beautify ctree; Print ctree"; cfunc_t | text of pdc, pdd, pdg | pdg text | CStructuredCodeGenerator; codegen.text |
بارگذاری
بارگذاری کننده کانتینر را تجزیه و تحلیل می کند، بخش ها را نقشه می کشد و نمادها و نقل مکان ها را می خواند. در یک شی قابل نقل مکان هنوز هیچ چیز آدرس ندارد، بنابراین بارگذاری کننده یکی را انتخاب می کند. رادار2 و رزین نقشه فایل را در 0x08000000، که میگه.textدر0x08000040چون بخش شروع شده در file offset0x40. مکان های CLE.textدر0x400000. گيدراElfLoaderقرارش بده0x100000.llvm-objdumpاز قسمت هاي بازيابي پرينتر مياد و اصلا پايه اي نداره
بارگذاری ها نیز در مورد نقل مکان متفاوت هستند. Ghidra آنها را در هنگام واردات پردازش می کند و CLE آنها را اعمال می کند. radare2 هنگام باز کردن شی نشان می دهد: نقل مکان ها اعمال نشده است و bin.relocs.apply=trueآنچه که یک بارنده با نقل مکان ها انجام می دهد، آنچه را که هر مرحله بعدی می تواند ببیند، تعیین می کند و شما در مرحله بعدی تاثیر را مشاهده خواهید کرد.-O0از میز زیر بپره
جداسازی
درس 33 هر دو روش رو ساخت.llvm-objdumpرد برگشتي اجرا مي کند و سپس جستجو را براي شروع تابع اضافه مي كند. اسناد دوگانه نینجا مراحل را به ترتیب نام می دهد: کاهش مکرر، تجزیه و تحلیل هدف تماس، تجزیه و تحلیل CFG به عنوان "تراکم خطی مناطق ناشناخته" و تجزیه و تحلیل تماس عقب. گیدرا تحلیلگرهای خود را به اولویت اجرا می کند، با "پوائندهای ورود را تجزیه کنید" و " جستجوی عملکرد شروع کنید" زودتر. IDA صف هاي خودتحليل را نگه مي دارد، هرکدوم با اولویت و امضا FLIRT برای کد کتابخانه. اينجريCFGFastاین منبع آخر جایی است که Angr در پدید کردن عملکردها را اختراع می کند.
بازیافت CFG
هر ابزار به شکل کلاس 33 بلاک ها را قطع می کند، با یک تفاوت اندازه گیری می کنید. Angr یک بلاک را در یک نقطه می کند.call،چون IRSBش یک بلوک ورود و خروج چندگانه است و تماس یک خروج است.grade_labelدر-O0، که زنگ ميزنهgrade، اینر دو بلوک گزارش می دهد و سه بلوک دیگر گزارش 1 . دستورالعمل ها یکسان هستند.
بلند کردن
این نوع زبان ها به عنوان یک زبان متوسط با عنوان بالاتر شناخته می شوند. این IR ها به منظور آنها متفاوت هستند. کد P و VEX برای تجزیه و تحلیل و تجزیه و تحلیل ساخته شده است. ESIL و RzIL برای شبیه سازی ساخته شده اند و هیچ یک از آنها مرحله SSA ندارد. میکرو کد Hex-Rays به عنوان کد شبیه RISC با 72 کد و از طریق سطوح بلوغ از ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ تا ۰ ۰ ۰ تا ۰ تا ۰ تا ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰ ۰MMAT_GENERATEDبهMMAT_LVARS.این دوگانه Ninja به Lifted IL می رسد، سپس پرچم ها را به شرایط LLIL می کند و MLIL "ریجستر ها و دسترسی به حافظه را به متغیرها ترجمه می کند". بخش بعدی چهار IR را در کنار یکدیگر در یک دستورالعمل قرار می دهد.
SSA
پایان نامه وان امریک آنچه را که SSA یک decompiler می خرید را فهرست می کند: گسترش عبارت، پارامتر و شناسایی بازگشت بدون فرضیه ABI، تجزیه و تحلیل حفظ، تجزیه و تحلیل نوع به عنوان یک مشکل جریان داده اندک، و تجزیه و تحلیل پرش های غیر مستقیم و تماس ها. Ghidra ساختار SSA را می نامد Heritageو دو عملیات را اضافه می کند که فقط در نمودار وجود دارد.MULTIEQUALبرای فیا وINDIRECTبرای اثرات جانبی. بناری نینجا در هر سطح IL یک فرم SSA را نشان می دهد. angr دارای دو مرحله SSA در داخل است Clinicهیکس- رایز یک فرم SSA را نام نمی دهد و در گذرنامه های بهینه سازی جهانی خود از جریان داده های استفاده می کند. ESIL و RzIL هیچ کدام را ندارند.
جریان و انواع داده ها
حلقه ساده سازی اصلی Ghidra "کد مرده را حذف کنید"، "تایپ های محلی را تبلیغ کنید" و "تایپ مجدد اصطلاح را انجام دهید" را اجرا می کند تا زمانی که هیچ چیز تغییر نکند، با نوشتن مجدد توسط یک مجموعه از Ruleهیکس رایز میکروکودی را تغییر می دهد، استدلال های تماس را درMMAT_CALLS, و متغیرهای محلی را در MMAT_LVARS. اينجري رانCallingConventionAnalysis،VariableRecoveryFastوTypehoonدر مورد این مرحله درس 41 در مورد این مرحله است.
ساختار
گيدراCollapseStructureدر جستجوی زیرگراف هایی که با یک ساختار مطابقت دارند، آنها را به یک گره فرو می کشد و وقتی گیر کرده است، یک لبه را حذف می کند و آن را غیر ساختار یافته نشان می دهد. هیکس-ریز CFG را به if،while،doوswitchاین منطقه را به عنوان مناطق goto می گذارد. این منطقه را به عنوان مناطق ورود و خروج واحد شناسایی می کند و با آنها ساختار می دهد.SAILRStructurerبطور پیش فرض، با PhoenixStructurerوDreamStructurerدروس 34 یک ساختار دهنده به دست نوشته بود.
انتشار
گيدرا توکن هاي سي رو از طریقش پخش ميکنهPrintCبا اون پرينتر خوبي اوپن بعدشActionNameVarsوActionSetCasts. هیکس-ریز درخت را زیباتر می کند و چاپ می کند. ننجا دوگانه HLIL را به عنوان Pseudo C، Pseudo Rust یا Pseudo Python ارائه می دهد. angr باز می گردد codegen.text. رادار2 پرنده هاpdc،pdd، یاpdg. .
یک دستورالعمل در چهار IR
اینو بگیر48 83 ec 10،subq $0x10, %rsp. با قوانین درس 33 روی کاغذ رمزگشاییش کن
48REX باW = 1اوپران 64 بیت هست83کد حسابداری گروه 1 با یک 8 بیت فوری است. میدان ModRM reg عملیات را انتخاب می کند.ecModRM است11 101 100.mod = 11این فرم ثبت نام است.reg = 101./5، کهsub.r/m = 100.%rsp. .10. 16 تا حالا
چهار نفر از بلندپرسان به این چهار بايت داده شدند.
ESIL از radare2 6.2.4 یک رشته از 30 توکن با قطره جدا شده است:
text16,0x8000000000000000,-,!,16,rsp,-=,63,$o,^,of,:=,63,$s,sf,:=,$z,zf,:=,$p,pf,:=,64,$b,cf,:=,4,$b,af,:=يه ماشين جمع شده16,rsp,-=هر پرچم بعد با یک عامل داخلی نوشته می شود: $oپر شدن آب$sعلامت$zصفر$pبرابر بودن$bقرض بگیر
RzIL از رزین 0. 9. 1 یک S- بیان با 14 setاثرات:
text(seq (set op1 (var rsp)) (set op2 (bv 64 0x10)) (set sub (- (var op1) (var op2))) (set rsp (var sub))
(set _result (var sub)) (set pf (! (lsb (let _val (cast 8 false (var _result)) ...))))
(set zf (is_zero (var _result))) (set sf (msb (var _result))) ... (set cf (|| ...)) (set of (|| ...)) (set af (|| ...)))هر پرچم یک عبارت بولی بر روی بیت ویکتورها است. پرچم برابر به تنهایی یک چهار سطح است.let. .
کد P از مشخصات SLEIGH x86:LE:64:defaultاز طریق کد پایپ 4.0.1 ۹ عملیات بعد از IMARK:
textCF = RSP < 0x10
OF = sborrow(RSP, 0x10)
RSP = RSP - 0x10
SF = RSP s< 0x0
ZF = RSP == 0x0
unique[58300:8] = RSP & 0xff
unique[58400:1] = popcount(unique[58300:8])
unique[58500:1] = unique[58400:1] & 0x1
PF = unique[58500:1] == 0x0ثبت انتقال ها با موقت در uniqueپرچم ها با توجه به دستورات، با مشتاقي وCFوOFقبل از اینکه تخفیف را بیش از حد محاسبه کنندRSP. .
VEX از pyvex 10. 0. 3 هفت اعلامیه بعد از IMark:
textt2 = GET:I64(offset=48)
t0 = Sub64(t2,0x0000000000000010)
PUT(offset=144) = 0x0000000000000008
PUT(offset=152) = t2
PUT(offset=160) = 0x0000000000000010
PUT(offset=168) = 0x0000000000000000
PUT(offset=48) = t0هیچ پرچم ظاهر نمی شود. نام های VEX به صورت تعویض در دولت مهمان ثبت می شوند و تعویض 48 است rsp. معاوضه 144 تا 168cc_op،cc_dep1،cc_dep2وcc_ndep. بلند کننده کد عملیات 8 را ذخیره می کند که 64 بیت است و دو اپراند. یک شاخه بعدی که پرچم را می خواند آن را از ستون محاسبه می کند. به همین دلیل استpcode.writesFlagsدرست است وvex.computesFlagsدر گزارش هنيز اشتباه است و چرا VEX کوتاه ترين چهار مورده
همون چهارتا اون بالا بردن48 63 c7،movslq %edi, %rax، اولین دستورالعمل ازgradeدر-O1، 5 توکن ESIL را ارائه دهید (32,edi,~,rax,=), 1 RzIL set, 1 عملیات کد P (RAX = sext(EDI)هیچ بلند کننده ای پرچم نمی نویسد، زیرا دستورالعمل هیچ پرچم ای ندارد. فهرست خود Ghidra از این دستورالعمل، از طریق اسکریپت بدون سر، همان عملیات را چاپ می کند.(register, 0x0, 8) INT_SEXT (register, 0x38, 4): ثبت تخفیف 0 است RAX، تعویض0x38.RDI، و اندازه ها 8 و 4 بایت هستند.
83 f9 04،cmpl $0x4, %ecx، از مرزها چک درgrade، 30 توکن ESIL را می دهد، 13 RzIL setاثرات، 10 عملیات کد P و 7 بیانیه VEX با cc_op7، ازاد 32 بت هیچ چیزی نمی نویسد%ecxدو عرض تخفیف که در VEX پیدا خواهید کرد، 7 برای 32 بیت و 8 برای 64 بیت هستند، و مترجم که شما می سازید، این جدول را حمل می کند.
چهار پایگاه آدرس برای یک عملکرد
قبل از اینکه هرنس بتواند هر چیزی را با خودش مقایسه کند باید در مورد جایی که یک تابع است با خودش موافق باشد.gradeدرledger-x86_64-O1.o. .
| Tool | Address of .text | Address of grade | Offset |
|---|---|---|---|
llvm-objdump | 0x0 | 0x10 | 0x10 - 0x0 = 0x10 |
| radare2, rizin | 0x08000040 | 0x08000050 | 0x08000050 - 0x08000040 = 0x10 |
| angr | 0x400000 | 0x400010 | 0x400010 - 0x400000 = 0x10 |
| Ghidra | 0x100000 | 0x100010 | 0x100010 - 0x100000 = 0x10 |
جدول نماد ميگهgradeدر حال حاضر.text + 0x10هر ابزار با اساس کنار می آید.iSjدر رادار2 و ریزین،.textدر بخش ثبت شده در ضبط آنگرو، .textبلوک حافظه در ضبط گیدرا و صفر برای پاک کردن.test_every_tool_places_grade_at_offset_0x10_from_its_own_baseاين حقيقت رو درست ميکنه
جایی که ابزارها با هم موافقند و جایی که آنها تقسیم می شوند
. آبروس درcode/main.pyاین اعداد را گزارش می دهد و آزمایش ها هر یک از آنها را تأیید می کند.
پرونده توافق: دفترچه در -O1
چهار تابع، 56 دستورالعمل در پاکش، 54 در داخل نمادها و 2 در پدید. هر ابزار گزارش همان دستورالعمل شروع در هر تابع: 9, 14, 13 و 18. چهار سازنده گراف گزارش 3, 3, 5 و 4 بلوک و 2, 3, 5 و 4 لبه، و مجموعه لبه یکسان هستند، جفت برای جفت، در سراسر رادار2, رزین, انگر و Ghidra. پنج بلوک و پنج لبه از totalدرسي 33 به دست رسيده شده
تنها تفاوت در پر کردن است.66 90بعد ازgrade،90بعد ازtotal) توسط پاک کردن رمزگذاری می شوند که هیچ دلیلی برای متوقف شدن ندارد و توسط Angr که ایجاد می کند sub_40003eوsub_40005fبدون نماد رادار، ريزين و گيدرا هيچ کدوم از آنها را ادعا نمي کنند
مورد متریزه: دفترچه در -O2
totalاین در هر یک از چهار سازنده گرافیک، 41 دستورالعمل در 10 بلوک با 13 لبه است. حلقه SSE2 و حلقه باقی مانده اسکالر از درس 33 به همان شکل در همه جا قطع می شوند. angr دوباره دو تابع را در پدید می آورد.
میز پرتاب: درجه در -O0
در اینجا ابزارها تقسیم می شوند، و تقسیم درس است.
| Tool | Blocks | Edges | What the capture says |
|---|---|---|---|
| radare2 | 3 | 2 | the block at 0x62 has no successor; bytes 0x76 to 0x9a are never reached; 8 instruction starts missing |
| rizin | 8 | 11 | the block at 0x62 carries a switch_op with 5 cases and 4 distinct targets |
| angr | 8 | 7 | the case blocks exist, and the transfer at 0x62 goes to an unresolvable target node |
| Ghidra | 9 | 12 | switchD label at 0x74 splits the block; four COMPUTED_JUMP flows to 0x76, 0x7f, 0x88, 0x91 |
هر چهار تا همون 33 دستور رو وقتي بهشون رسيدن رمزنگاري کردند. رادار2 درjmp raxو 36 بايت بدون درخواست و نام هاي استفاده شده را به عنوان کد گم شده گذاشتند. رزين و گيدرا چهار هدف متمایز را که درسي 33 از پنج نقل مکان در سال 2003 در نظر گرفته شده بود، پيدا کردند.rela.rodata. اينر فهرست بلوک هاي پرونده رو در داخل ميکنهgradeو هنوز هم هیچ حاشیه ای از بلوک پرتاب به آنها ندارد؛ گرفتن آن ثبت انتقال در 0x62به عنوان منجر به یک گره هدف حل نشده، و decompiler آن یک محاسب چاپ شده استgotoگیدرا برای جریان کنترل مشابه یک بلوک و یک لبه بیشتر از رزین دارد زیرا تجزیه و تحلیل سوئیچش برچسب را روی jmp raxو مدل بلوک یک بلوک جدید را در یک برچسب شروع می کند.
دروس ۳۳ نمودار ۸ بلوک و ۱۱ لبه داشت. رزین دقیقاً با آن مطابقت دارد. نکته این است که ببینید ۹ و ۱۱ و ۷ و ۲ چهار اندازه گیری کد یافت نشده است. آنها چهار پاسخ به اینکه یک ابزار چقدر به یک پرش غیر مستقیم ادامه داده و کجا تصمیم گرفته تا برش کند.
داده ها در کد: تله پاکسازی
lookup24 بايت با 4 بايت جدول است31 c0 90 48در0x10. گزارش های پاکسازی 8 دستورالعمل شروع در این محدوده.0x10،0x12و0x13، و شروع گمشده در0x14. اينمaddq $0x1, %raxاز درس 33 بايت زودتر. رادار2، ريزين و گيدرا گزارش 6 شروع، 2 بلوک، 1 کناره و ترک0x10به0x14بدون مطالبه. اینگرا گزارش داده است که 2 بلوک و 1 کناره برایlookupو بعد اختراع می کنهsub_400010در جدول بائیت ها: 2 دستور در یک بلوک 4 بائیت که به 0x14، جایی که بلوک دوم ازlookupشروع می شود، پس بايت REX در 0x13آخرین یافته ی این ربط برای این شی این است که هیچ سازنده گرافیک رمزگشایی نمی کند0x10به0x14، پس این بائتهایی در داخل یک تابع قرار دارند و داده هستند.
اختراع شده و فراموش شده، با ابزار
در چهار شی، هرنس ۹ تابع را نام می دهد که آن را بدون علامت اختراع می کند، هر یک در پدید یا در میز تله.gradeدر-O0این نام 9 دامنه را که در ردیف خطی پاک کردن کد و هیچ سازنده نمودار به عنوان کد: هشت شکاف پر کردن به علاوه جدول دام نام می دهد. این نام هیچ عملکرد گم شده در هر ابزار.
سه تا از "دکامپلر" در درجه
سه تا از ابزار ضبط شده متن شبیه به C را برای gradeدر-O1. منبعش اينهswitch (score / 10)با پنج مورد، که به صورت چک محدودیت و جدول ارزش های بازپرداخت مرتب شده است.
گیدرا 12.1.4:
cuint grade(int param_1)
{
uint uVar1;
uint uVar2;
uVar2 = param_1 / 10 - 6;
uVar1 = -(param_1 >> 0x1f) ^ (uint)((ulong)((long)param_1 * 0x66666667) >> 0x3f);
if (uVar2 < 5) {
uVar1 = *(uint *)(&DAT_001000b4 + (ulong)uVar2 * 4);
}
return uVar1;
}Angr 10.0.3
cextern unsigned int g_4000b4[4];
unsigned int grade(int a0)
{
unsigned int v1; // ecx
unsigned int v2; // eax
v1 = (unsigned int)((long long)(a0 * 1717986919) >> 0x22) + (unsigned int)(a0 * 1717986919 >> 63) - 6;
v2 = 0;
if (v1 <= 4)
v2 = g_4000b4[v1];
return v2;
}رادار2 6.2.4pdc:
cvoid sym.grade (int64_t arg1) {
rax = edi
rax = rax * 0x66666667
rcx = rax
rcx >>= 0x22
rax >>>= 0x3f
ecx += eax
ecx += 0xfffffffa
eax = 0
v = ecx - 4
if (((unsigned) v) <= 0) {
eax = ecx
rcx = rip
eax = dword [rcx + rax*4]
}
return
}سه تا رو در مقابل خط لوله بخونيد.0x66666667و تغییر 34 به عقب به param_1 / 10اين زبان درس 34ه. انگر بايت هاي مشابه رو بلند کرد و حساب رو ترک کردa0 * 1717986919 >> 0x22. رادار2pdcاین شبیه سازی ESIL و ترکیب مزخرفه است: نام های ثبت، هیچ متغیر، هیچ نوع و چک محدودیت به عنوان <= 0بعد از تخفیف بدون امضا گیدرا بار میز رو از طریق تایپ کردDAT_001000b4; اعلام شدهg_4000b4[4]نه گیدرا و نه انگر تعداد موارد را بدست آوردند، زیرا در-O1هیچ سوئیچ در بائتهای باقی نمی ماند-O0، جایی که میز پرتاب وجود داره، گیدرا چاپ شدهswitch(param_1 / 10)با موارد 6 تا 10 و پیش فرض، و angr چاپ یک محاسبgoto. .
رزين هيچ کدوم از کليد هاي خود رو نداره و سوابق ضبطي کهpdcHLIL دوگانه Ninja و درخت هیکس رایه دو محصول است که این درس نمی تواند ضبط کند.
آن را بسازید
نمایش نمایش را اجرا کن:
bashcd phases/13-tools-and-protocols/37-the-reverse-engineering-landscape
python3 code/main.pyمحصول یک گزارش JSON است. با نسخه های ابزار ثبت شده در زمان ضبط و با ابزار موجود در دستگاه شما باز می شود که ممکن است همه از دست رفته باشند. سپس برای هر یک از چهار شی نشان دهنده ی دامنه های نماد، شکاف های پر کردن، پایه هر ابزار مورد استفاده، عملکرد هر ابزار یافت یا اختراع شده را شروع می کند، و برای هر عملکرد توافق شروع دستورالعمل، شمارش بلوک، شمارش لبه، و لبه های هر ابزار از دست رفته است. این با حسابداری باایت هر ابزار، یادداشت های ابزار، لیست یافته ها در جملات ساده و بخش IR: تولید مترجم برای سه دستورالعمل در کنار شمارش اندازه گیری شده در آسانسور های ضبط شده.
شکل انتظار می رود:
json{
"captureTools": {"llvm-objdump": "Apple LLVM version 17.0.0", "radare2": "radare2 6.2.4 ...", "rizin": "rizin 0.9.1 ...", "angr": "10.0.3", "ghidra": "12.1.4"},
"localTools": {"radare2": "absent", "...": "..."},
"fixtures": {
"ledger-x86_64-O0.o": {
"bases": {"llvm-objdump": "0x0", "radare2": "0x8000040", "angr": "0x400000", "ghidra": "0x100000", "...": "..."},
"functions": {"grade": {"blocks": {"radare2": 3, "rizin": 8, "angr": 8, "ghidra": 9}, "edges": {"radare2": 2, "rizin": 11, "angr": 7, "ghidra": 12}, "...": "..."}},
"findings": ["radare2 never reaches bytes 0x76-0x9a inside grade that the other graph builders decode", "..."]
}
},
"ir": {"translator": [{"text": "subq $0x10, %rsp", "flags": {"pcodeLike": "eager", "vexLike": "thunk"}, "...": "..."}], "observed": {"...": "..."}}
}بخونcode/main.pyدر این ترتیب:
read_text_symbols()در قسمت های زیر به عنوان و در قسمت های بعدی به عنوانSTT_FUNCنماد های.text. جدول نماد تنها حقیقت زمینی که در قلاده وجود دارهTextSection.gaps()ازش پودر می گیرد.parse_objdump()،parse_r2_family()،parse_angr()وparse_ghidra()هرکدوم از اين دسته ها رو به يه دسته تبديل ميکننToolView: یک پایه، دستورالعمل ها به عنوان تعویض به طول و یکFunctionViewهر کارگر لغت یک ابزار را می داند و هیچ چیز دیگری را نمی داند.majority()وranges()آیا دو نفر همکارند که هر مقایسه ای برایشان مفید است؟function_report()شروع دستورالعمل را با اکثر سازندگان گرافیک مقایسه می کند، سپس تعداد بلاک، سپس مجموعه های کناری را مقایسه می کند و لیست آنچه که هر ابزار از دست می دهد را فهرست می کند.byte_report()برای هر بایت به عنوان کد درون یک نماد، پوشاندن، غیرقابل ادعا، اختراع یا از دست رفته، و نام دادن به بایت ها در داخل نماد که هیچ سازنده گرافیک آن را رمزنگاری نمی کند.findings()اينها رو به جمله ها تبديل ميکنه وcompare()یک گزارش در هر موجود را جمع آوری می کند.decode_small()،to_pcode_like()وto_vex_like()ترجمه کننده: سه کد در قالب ثبت، یک سبک مشتاق، یک سبک تنده.observed_ir()اندازه گیری آسانسور های گرفته شده وfigure_data()جدول زمان، جدول صحنه و شواهد موجود در این شکل را جمع می کند.
سه فرمان ديگه وجود دارهpython3 code/main.py compare FIXTURE.oگزارش یک شی را چاپ می کند.python3 code/main.py ir 4883ec10دو فرم ترجمه کننده را برای یک دستورالعمل چاپ می کند. python3 code/main.py figure-dataداده های موجود در این شکل را چاپ می کند.
دستاوردها يه بار توسطcode/fixtures/capture_tools.py، که هر فرمان و نسخه رو درcaptures.json.آره و تست ها هرگز ابزار را راه اندازی نمی کنند. اگر ابزار دارید، اسکریپت ضبط را اجرا کنید تا فایل ها را تازه کنید و لوازم README را برای محیط مورد نیاز بخوانید.
ازش استفاده کن
از بندش براي يه كشي جديد در اين ترتيب استفاده كنيد
- خود شما این شی را بسازید و دستور کامپایلر را حفظ کنید. قبل از اینکه هر ابزار را باز کنید، جدول نماد آن را بخوانید تا بدانید چند تابع وجود دارد و پوشش کجاست.
- هر ابزار را یک بار در حالت بدون سر ضبط کنید. محصول خام و دستور دقیق را کنار شی ذخیره کنید. اختلاف نظر شما را نمی توانید دوباره بخوانید، یک یافته نیست.
- پایه را بررسی کنید. یک تابع را انتخاب کنید و تایید کنید که هر ابزار بعد از حذف آن را در همان تعویض قرار می دهد
.textاگه نميدونه، بزار و ببين که اون ابزار چي رو بار کرده - در این مورد، دستورالعمل مقایسه ابتدا شروع می شود. اگر سازندگان گرافیک در اینجا با هم مخالفند، بقیه مقایسه در مورد رمزگذاری است و نه در مورد تجزیه و تحلیل.
- با بلوک ها و لبه ها مقایسه کنید و قبل از اینکه به حسابی قضاوت کنید یادداشت های هر ابزار را بخوانید.
switch_op، یکCOMPUTED_JUMP، یا یک گره هدف حل نشدنی بیشتر تفاوت ها را توضیح می دهد. - حساب برای بایت ها. پیدا کردن که یک ابزار ادعا می کند یک هوریستیک در کار است. بایت های نماد که یک ابزار ترک می کند یک قدم متوقف است. بایت های نماد که هیچ سازنده گرافی ادعا نمی کند داده است.
- یک توصیف از اسناد مفید است و نوعی شواهد متفاوت از یک ضبط است.
آزمایشگاه تعاملی
آزمایشگاه A: یک تابع، چهار پایه
ازcodeدایرکتوری، پیتون باز:
bashcd phases/13-tools-and-protocols/37-the-reverse-engineering-landscape/code
python3 -qراه رفتن:
pythonfrom main import *
views = load_views("ledger-x86_64-O1.o")
{tool: hex(view.base) for tool, view in views.items()}
{tool: hex(view.functions["grade"].start + view.base) for tool, view in views.items()}قبل از اینکه خط دوم را اجرا کنید، چهار آدرس خام را بنویسید و آنها را با جدول در این درس بررسی کنید. سپس جایگزین کنیدgradeباgrade_labelو به دست برآوردش در جنده قرار دارد.
لابراتوار ب: میز پرتاب از چهار طرف
pythonreport = compare("ledger-x86_64-O0.o")
report["functions"]["grade"]["blocks"]
report["functions"]["grade"]["edgesMissingPerTool"]["radare2"]
report["notes"]["rizin"]
report["notes"]["ghidra"]
report["bytes"]["radare2"]["misses"]لبهاي رادار2 رو بشماريد و هرکدوم رو با خطي از رادار2 مطابقت بدهيد-O0بعد نويت گيدرا رو بخونيد و دنبال اونswitchDبرچسب در ضبط گیدرا
لابراتوار C: پرچم های مشتاق در برابر یک سنگ
pythontranslate("48 83 ec 10")["pcodeLike"]
translate("48 83 ec 10")["vexLike"]
translate("83 f9 04")["vexLike"]
{row["name"]: (row["pcode"]["ops"], row["vex"]["statements"]) for row in observed_ir()["instructions"]}پیدا کنcc_opثابت در هر دو محصول و توضیح دهید که چرا یکی 8 و دیگری 7 است. سپس سعی کنیدtranslate("48 01 c8")و بخونيدTranslateError. .
لابراتوار D: تله زیر پنج ابزار
pythonreport = compare("sweep-trap.o")
report["functions"]["lookup"]["instructionStarts"]
report["bytes"]["dataInsideSymbols"]
report["functionStarts"]["angr"]بائتهاي رمزگشایی شده31 c0 90 48 83 c0 01در کاغذ مثل يه جارو ميکنه، بعدش مثل يه نزول بعد ازjmpدوتا لیست رو با اضافه کردن هم سازي کن و گزارش هاي بازي بازي شروع ميشه
آزمایشگاه تمرین
پنجم گرفتگي رو اضافه کن و بند رو گسترش بده
الزامات:
- یکی از ابزارهایی را که این درس ضبط نکرده و می توانید روی ماشین خود اجرا کنید را انتخاب کنید: GNU
objdump, LIEF با Capstone , یک جلسه Binary Ninja Free صادر شده توسط دست , یا Ghidra با یک مجموعه تجزیه و تحلیل مختلف.captures.json. . - يه پارسر بنويس که گرفتاري رو به يه
ToolViewبا پایه ابزار، دستورالعمل ها، عملکردها، بلوک هایی که ابزار آنها را دارد و حاشیه هایی که آنها را دارد. - ابزار را به اضافه کنید
TOOLSو اگر نمودار بسازد، بهDESCENT_TOOLS. دمو رو اجرا کن و بگير که چه چيزي در مجموعه هاي بيشترين عوض شده - یک تست بنویس که نشان دهد بلوک ابزار به حساب می آید
ledger-x86_64-O1.oو يک آزمون که ثابت ميکنه با ميز فريب چه کاري ميکنه - یک پاراگراف برای درس بنویسید که به زبان خود ابزار، آنچه را که بارگذاری، جداسازی و CFG می نامد می گوید.
موفقیت به معنیpython3 code/main.pyگزارش ابزار جدید در captureTools، هر وظيفه درledger-x86_64-O1.oنگه دارهallDescentToolsAgreeدرست است و یافته ها برایsweep-trap.oبگو ابزار جدید با بايت ها چه کار کرد0x10به0x14. .
درس هنرپیشه
این درس شاملoutputs/skill-the-reverse-engineering-landscape.mdاز آن برای اجرای چندین ابزار در یک شی که ساخته اید، آدرس آنها را به یک پایه کاهش دهید و به هر تابع گزارش دهید که در آن آنها در مورد شروع دستورالعمل، بلوک ها و لبه ها توافق دارند و کدام بایت هر ابزار ایجاد یا گم می کند. این نیاز به ضبط با دستورات و نسخه های ضبط شده، یک جدول نماد از فایل خوانده شده و بیانیه ای از ابزار که فقط از اسناد توصیف شده است.
بررسی کنید
نمایش و مجموعه تعیین کننده را اجرا کنید:
bashcd phases/13-tools-and-protocols/37-the-reverse-engineering-landscape
python3 code/main.py
python3 -m unittest discover -s code/tests -vبررسی باید ثابت کند:
- خواننده ELF چهار نماد تابع را در
ledger-x86_64-O1.oبا اندازه های 16، 46، 31 و 63 و دو شکاف پوشان - در این قسمت، دستورالعمل های 86, 56, 84 و 11 برای چهار شی را در اختیار دارید.
- رادار2 و رزين از همون دستورالعمل ها، بلوک ها و حواشی در
ledger-x86_64-O1.o، و فقط رادار2 دارهpdcمتن - علامت های انگلی
sub_40003eوsub_40005fبه عنوان تابع بدون علامت - بلوک هاي گيدرا براي
totalپنج بلوک درسی 33 و جریان های تماس آن نه حاشیه های نمودار هستند - هر ابزار رو جايگاه ميکنه
gradeدر تعویض0x10پس از برداشتن پایه آن - هر ابزار با هر شروع دستورالعمل در هر عملکرد از
ledger-x86_64-O1.o - چهار سازنده گرافیک گزارش 3، 3، 5، 4 بلوک و 2، 3، 5، 4 لبه در آنجا، با مجموعه لبه های یکسان
totalدر-O210 بلوک و 13 لبه در هر سازنده گراف داردgradeدر-O0دارای بلوک های ۳، ۸، ۸ و ۹ و ۲، ۱۱، ۷ و ۱۲ لبه در رادار، رزین، آنگر و گیدر، با دلایل در یادداشت های هر ابزارgrade_labelدر-O0یک بلوک در همه جا است به جز Angr، که یک بلوک در تماس پایان می یابد- angr یک تابع را در هر شکاف پر کردن به علاوه یک را در میز تله اختراع می کند و هیچ ابزار دیگری یک تابع را اختراع یا از دست نمی دهد
- سود هاي پاک کردن شروع ميشه
0x10،0x12،0x13و از دست می دهد0x14در دام و هيچ گراف سازي كد نمي كنه0x10به0x14 - یافته ها نام دامنه گمشده در رادار2 و هر تابع اختراع شده در Angr
- در مانیست یک نسخه و یک دستور برای تمام 21 فایل ضبط ثبت می شود
- سه ابزار را جمع آوری کنید
grade، و فقط گيدرا به زبان تقسيم مياد - مترجم CF، OF، SF، ZF، PF را با مشتاقانه در یک سبک و یک
cc_opاون يکي هم يه جورايي به دستش ميادcmp، و هيچ پرچم برايmovslq - مترجم از فرم های حافظه، دیگر کد های opcode، بیت های REX اضافی و طول های نادرست، انکار می کند
- ترجمه کننده
cc_opشماره 8 و 7 برابر با شماره های VEX گرفته شده - آسانسور های ضبط شده، عملیات کد P ۹، ۱، ۱۰ و ۷، ۴، ۷ را برای سه دستورالعمل VEX بیان می کنند.
- خط زمانی از سال 1973 تا 2026 در ترتیب است، خط لوله هشت مرحله و شش ابزار با یک اصطلاح در هر سلول دارد، و دو ابزار بسته به عنوان اجرا نشده نشان داده شده است
- این شکل تعاملی همان داده هایی را که هرنس تولید می کند، در خود جای می دهد.
روش های شکست تولید
| Failure | What the weak report says | What the harness must prove |
|---|---|---|
| Raw addresses from different tools | "the tools disagree about where grade is" | one offset after each base is removed, checked on one function |
| Block count as a measure of code found | "Ghidra found the most code" | the same instruction starts, with the extra block explained by a label |
| One tool as the oracle | "objdump shows the table bytes are instructions" | the sweep is a linear sweep; three graph builders leave the bytes unclaimed |
| Padding functions counted as discoveries | "angr found seven more functions" | every one sits in a padding gap or on data, and none has a symbol |
| A stopped walk reported as dead code | "the four case blocks are unreachable" | 36 bytes missed by one tool and reached by three |
| Edge counts compared without the notes | "rizin and Ghidra disagree on grade" | the same four computed targets, one extra split at a label |
| A decompiler's arithmetic read as the program | "the function multiplies by 1717986919" | the idiom from lesson 34, folded by one tool and left by another |
| A closed tool described as if run | "Binary Ninja reports five blocks" | the figure and the table mark it as documentation only |
| Captures without commands | "we ran radare2" | the manifest with version, command, and date for every file |
| An IR with no flags read as a lossy lift | "VEX dropped the flags" | the thunk in cc_op, cc_dep1, cc_dep2, evaluated at the branch |
قاعده عملیاتی
هر ابزار را یک بار با دستور و نسخه آن ضبط کنید، هر آدرس را به یک پایه کاهش دهید و دستورالعمل ها را قبل از بلوک ها و بلوک ها قبل از لبه ها مقایسه کنید. حساب برای هر بایت به عنوان ادعا شده، پوشاندن، داده ها یا از دست رفته است. یادداشت خود ابزار را قبل از قضاوت از تعداد آن بخوانید و بگویید که در مورد کدام ابزارها فقط می خوانید.
خواندن بیشتر
- Cifuentes, "Reverse Compilation Techniques", PhD thesis, QUT (1994)
- Cifuentes and Gough, "Decompilation of Binary Programs", Software: Practice and Experience (1995)
- Van Emmerik, "Static Single Assignment for Decompilation", PhD thesis, University of Queensland (2007)
- Schwartz, Lee, Woo, Brumley, "Native x86 Decompilation Using Semantics-Preserving Structural Analysis and Iterative Control-Flow Structuring" (USENIX Security 2013)
- Yakdan et al., "No More Gotos" (NDSS 2015)
- Basque et al., "Ahoy SAILR! There is No Need to DREAM of C" (USENIX Security 2024)
- Andriesse et al., "An In-Depth Analysis of Disassembly on Full-Scale x86/x64 Binaries" (USENIX Security 2016)
- Flake, "Structural Comparison of Executable Objects" (DIMVA 2004)
- Maranzano and Bourne, "A Tutorial Introduction to ADB", Bell Labs (1977)
- Stallman, KTH lecture on GDB entering distribution (30 October 1986)
- Hex-Rays, "IDA: celebrating 30 years of binary analysis innovation"
- Guilfanov, "Decompiler internals: microcode", Recon Brussels 2018 (slides)
- Hex-Rays, microcode view and maturity levels
- Hex-Rays, IDA 9.4 release notes
- Hex-Rays, IDA Free
- Ghidra releases (12.1.4)
- Ghidra P-code reference
- Ghidra decompiler source, main work flow and Action classes
- Ghidra analyzeHeadless README
- Binary Ninja, BNIL overview
- Binary Ninja, "Architecture Agnostic Function Detection in Binaries" (2017)
- Binary Ninja, batch processing and headless licences
- Binary Ninja 6.0 "Krypton" release post
- Binary Ninja Free
- radare2 book, ESIL
- radare2 book, decompilers
- radare2 releases (6.2.4)
- rizin, RzIL design notes
- rizin releases (0.9.1)
- Announcing Rizin (8 December 2020)
- Cutter releases (2.5.0)
- angr documentation, CFG recovery
- angr documentation, the decompiler and its analysis passes
- angr documentation, intermediate representation (VEX)
- angr on PyPI (10.0.3)
- pypcode on PyPI
- llvm-objdump command guide
- GNU objdump manual
- LIEF documentation
- Capstone releases
- BinDiff releases (v8, open source)
- Diaphora
- Hopper Disassembler downloads
- Compiler Explorer
- LLDB announced as an LLVM subproject (2010)
- Boomerang decompiler
- Tan et al., "LLM4Decompile" (EMNLP 2024)
- Gao et al., "DecompileBench" (Findings of ACL 2025)
- Liu, Raff, Micinski, "When LLM Decompilers Recompile More and Preserve Less" (2026)
This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.
Browse the complete course catalog or open this lesson on GitHub.