RET同步代表反向工程工具同步。這是一組插件,有助於將調試會話(WINDBG/GDB/LLDB/OLLYDBG/OLLYDBG2/X64DBG)與拆卸器(IDA/GHIDRA/GHIDRA/BINARY NINJA)同步。潛在的想法很簡單:從兩全其美(靜態和動態分析)中汲取最好的想法。
調試者和動態分析為我們提供:
!peb , !drvobj ,! !address等)拆卸器和靜態分析為我們提供:
關鍵功能:
ret-sync是我在Quarkslab逗留期間開發和維護的QB-Sync的叉子。
調試器插件:
ext_windbg/sync :windbg擴展源文件,一旦構建: sync.dllext_gdb/sync.py :GDB插件ext_lldb/sync.py :lldb插件ext_olly1 :ollydbg 1.10插件ext_olly2 :ollydbg v2插件ext_x64dbg :x64dbg插件拆卸器插件:
ext_ida/SyncPlugin.pyext_ghidra/dist/ghidra_*_retsync.zip插件ext_bn/retsync :二進制忍者插件和庫插件:
ext_lib/sync.py :獨立python庫IDA和GDB插件需要有效的Python設置。支持Python 2(> = 2.7)和Python 3。
Windbg/Ollydbg/Ollydbg2/X64DBG調試者的預構建二進製文件是通過Azure DevOps管道提出的:
選擇最後一個構建並檢查Related部分下的工件: 6 published 。

Ghidra插件的預構建插件存檔在ext_ghidra/dist中提供。
ret-sync應該為大多數用戶提供典型設置的開箱即用:同一主機上的調試器和拆卸器,模塊名稱匹配。
不過,在某些情況下,可以使用特定的配置。為此,擴展名和插件在用戶主目錄中檢查了名為.sync的可選全局配置文件。它必須是有效的.INI文件。
此外,IDA和GHIDRA插件還首先在IDB或Project Directory( <project>.rep )中查找配置文件,以允許本地,每個IDB/Project,設置。如果存在本地配置文件,則忽略了全局配置文件。
在這些配置文件中聲明的值覆蓋默認值。請注意,默認情況下創建NO .sync文件。
下面我們詳細介紹了配置文件有用/需要的三個常見方案:
[INTERFACE]部分用於自定義與網絡相關的設置。讓我們假設一個人想將IDA與在虛擬機(或另一個主機)中運行的調試器同步,常見的遠程內核調試方案。
只需創建兩個.sync文件:
[INTERFACE]
host=192.168.128.1
port=9234
它告訴ret-sync IDA插件在端口9234上在接口192.168.128.1上聆聽。毋庸置疑,必須從遠程主機或虛擬機可以達到此接口。
[INTERFACE]
host=192.168.128.1
port=9234
它告訴RET-Sync調試插件,以連接到先前配置為在此接口中收聽的RET-Sync IDA插件。
注意:您必須在此處指定一個真實的IP,並且不要使用0.0.0.0 。這是因為該變量均由多個源用於綁定和連接,因此使用0.0.0.0會導致奇怪的錯誤。
[ALIASES]
ntoskrnl_vuln.exe=ntkrnlmp.exe
[ALIASES]部分用於自定義拆卸器(IDA/GHIDRA)使用的名稱,以將模塊註冊到其調度員/程序管理器中。
默認情況下,拆卸器插件使用輸入文件的名稱。但是,可能已事先重命名該文件,並且不再匹配實際過程的名稱或調試器所看到的已加載模塊。
在這裡,我們只需告訴調度程序即可匹配名稱ntkrnlmp.exe (真實名稱),而不是ntoskrnl_vuln.exe (IDB名稱)。
QT創建者調試前端更改GDB命令輸出的方式。由於這將乾擾同步,因此存在使用原始GDB輸出進行同步而不是臨時文件的選項。在.Sync配置文件中使用
[GENERAL]
use_tmp_logging_file=false
如果您希望將目標用於目標的QT調試前端。
/proc/<pid>/maps在某些情況下,例如在Qemu中通過串行或原始固件調試嵌入式設備,GDB不知道PID,無法訪問/proc/<pid>/maps 。
在這些情況下, [INIT]部分用於將自定義上下文傳遞給插件。它允許覆蓋某些字段,例如PID和內存映射。
.sync內容摘錄:
[INIT]
context = {
"pid": 200,
"mappings": [ [0x400000, 0x7A81158, 0x7681158, "asav941-200.qcow2|lina"] ]
}
映射中的每個條目是: mem_base , mem_end , mem_size , mem_name 。
在某些情況下,例如調試嵌入式設備或連接到簡約的調試界面,繞過拆卸器插件中實現的自動地址重新打開功能可能更方便。
當前僅針對Ghidra支持use_raw_addr選項。在.Sync配置文件中使用:
[GENERAL]
use_raw_addr=true
IDA 7.X需要分支。對於較舊版本(6.9倍),請參見存檔的版本ida6.9x 。
對於IDA安裝,請將Syncplugin.py和retsync文件夾從ext_ida複製到IDA插件目錄:
C:Program FilesIDA Pro 7.4plugins%APPDATA%Hex-RaysIDA Proplugins~/.idapro/pluginsAlt-Shift-S )或Edit中運行插件 - > Plugins - > ret-sync [sync] default idb name: ld.exe
[sync] sync enabled
[sync] cmdline: "C:Program FilesPython38python.exe" -u "C:UsersuserAppDataRoamingHex-RaysIDA Propluginsretsyncbroker.py" --idb "target.exe"
[sync] module base 0x100400000
[sync] hexrays #7.3.0.190614 found
[sync] broker started
[sync] plugin loaded
[sync] << broker << dispatcher not found, trying to run it
[sync] << broker << dispatcher now runs with pid: 6544
[sync] << broker << connected to dispatcher
[sync] << broker << listening on port 63107
要解決IDA擴展問題的問題,請在文件retsync/rsconfig.py中提供兩個選項:
LOG_LEVEL = logging.INFO
LOG_TO_FILE_ENABLE = False
將LOG_LEVEL值設置為logging.DEBUG使插件更詳細。
將LOG_TO_FILE_ENABLE設置為True值觸發了從broker.py和dispatcher.py將異常信息記錄到專用文件中。日誌文件是在%TMP%文件夾中生成的,並具有名稱模式retsync.%s.err 。
要么使用ext_ghidra/dist文件夾中的預構建版本,要么遵循指令構建它。每個擴展構建僅支持插件文件名中指定的Ghidra版本。例如ghidra_9.1_PUBLIC_20191104_retsync.zip用於Ghidra 9.1公共。
apt install gradle$GHIDRA_DIR ) cd ext_ghidra
gradle -PGHIDRA_INSTALL_DIR= $GHIDRA_DIRFile - > Install Extensions... ,單擊+標誌,然後選擇ext_ghidra/dist/ghidra_*_retsync.zip ,然後單擊“確定”。這將有效地將retsync文件夾從ZIP提取到$GHIDRA_DIR/Extensions/Ghidra/ [*] retsync init
[>] programOpened: tm.sys
imageBase: 0x1c0000000
Alt+s )/Disable( Alt+Shift+s )/RESTART( Alt+r )同步。 Windows > RetSyncPlugin也可以找到狀態窗口。您通常希望將其放在側面,以將其與Ghidra環境窗口集成在一起。
二進制忍者支持是實驗性的,請確保備份分析數據庫。
ret-sync最少需要二進制忍者2.2版,以及Python 3(不支持Python 2)。
ret-sync尚未通過二進制忍者的插件管理器分發;需要手動安裝。只需將ext_bn文件夾的內容複製到二進制忍者插件文件夾中,例如:
%APPDATA%Binary Ninjaplugins
重新啟動二進制忍者後,控制台窗口中應存在以下輸出:
[sync] commands added
Loaded python3 plugin 'retsync'
使用預構建的二進製文件,或使用ext_windbg中提供的Visual Studio 2017解決方案(請參閱https://docs.microsoft.com/en-us/visalstudio/releasenotes/vs2017-relnotes,如果需要時)。
這將構建x64releasesync.dll文件。
您將需要將結果sync.dll文件複製到適當的windbg擴展路徑中。
對於windbg的早期版本,這就是這樣(例如,請小心x86 / x64口味)
C:Program Files (x86)Windows Kits10Debuggersx64winextsync.dll
用於存儲擴展程序的文件夾似乎基於路徑,因此您需要將其放置為查詢位置之一。
一個例子是將其放在這裡:
C:UsersuserAppDataLocalMicrosoftWindowsAppssync.dll
.load命令) 0:000> .load sync
[sync.dll] DebugExtensionInitialize, ExtensionApis loaded
0:000> !sync
[sync] No argument found, using default host (127.0.0.1:9100)
[sync] sync success, sock 0x5a8
[sync] probing sync
[sync] sync is now enabled with host 127.0.0.1
例如在IDA的輸出窗口中
[*] << broker << dispatcher msg: add new client (listening on port 63898), nb client(s): 1
[*] << broker << dispatcher msg: new debugger client: dbg connect - HostMachineHostUser
[sync] set debugger dialect to windbg, enabling hotkeys
如果WindBG的當前模塊與IDA文件名匹配
[sync] idb is enabled with the idb client matching the module name.
注意:如果收到以下錯誤,則是因為您尚未將文件複製到上述步驟中的正確文件夾中。
0: kd> .load sync
The call to LoadLibrary(sync) failed, Win32 error 0n2
"The system cannot find the file specified."
Please check your debugger configuration and/or network access.
下面的誤差通常意味著WINDBG試圖加載擴展的不正確風味,例如: x64代替x86 sync.dll 。
0:000> .load sync
The call to LoadLibrary(sync) failed, Win32 error 0n193
"%1 is not a valid Win32 application."
Please check your debugger configuration and/or network access.
由於WindBG預覽從同一目錄加載插件( x86和x64 ),因此可以重命名x86文件sync32.dll 。
0:000> .load sync32
ext_gdb/sync.py複製到您選擇的目錄 gdb> source sync.py
[sync] configuration file loaded 192.168.52.1:9100
[sync] commands added
但是,LLDB支持是實驗性的:
~/.lldbinit中添加) lldb> command script import sync
OLLYDBG 1.10支持是實驗性的:
但是,OLLYDBG2支持是實驗性的:
基於testplugin,https://github.com/x64dbg/testplugin。 X64DBG支持是實驗性的:
pluginsdk ”目錄粘貼到“ ext_x64dbgx64dbg_sync ”中.d32或.dp64 )。對於以命令行為導向的調試者(主要是WINDBG和GDB), RET-Sync公開了一組命令,以協助進行反向工程任務。
下面的命令是通用的(WINDBG和GDB),請注意!在WINDBG上需要前綴(例如:GDB中的sync , !sync )。
| 調試器命令 | 描述 |
|---|---|
synchelp | 顯示帶有簡短說明的可用命令列表 |
sync | 開始同步 |
syncoff | 停止同步 |
cmt [-a address] <string> | 在拆卸器中的當前IP上添加評論 |
rcmt [-a address] | 在當前IP中重置評論 |
fcmt [-a address] <string> | 為當前IP所在的函數添加功能註釋 |
raddr <expression> | 添加評論,並從表達式中評估的重新反駁地址 |
rln <expression> | 從給定地址的拆卸器中獲取符號 |
lbl [-a address] <string> | 在當前IP中添加標籤名稱 |
cmd <string> | 在調試器中執行命令,並在當前IP中添加其輸出作為註釋。 |
bc <||on|off|set 0xBBGGRR> | 在拆卸器中啟用/禁用路徑著色 |
idblist | 獲取連接到調度程序的所有IDB客戶端的列表 |
syncmodauto <on|off> | 基於模塊名稱啟用/禁用拆卸器自動開關 |
idbn <n> | 將Active IDB設置為nth客戶端 |
jmpto <expression> | |
jmpraw <expression> | 如果啟用了IDB,則將拆卸器的視圖與結果地址同步。 |
translate <base> <addr> <mod> | 反彈有關其模塊的姓名和偏移的地址 |
windbg特定命令:
| 調試器命令 | 描述 |
|---|---|
curmod | 顯示用於當前指令偏移的模塊信息(用於故障排除) |
modlist | 調試器標記語言(DML)增強的模塊列表,用於更平滑的活動IDB切換 |
idb <module name> | 將給定模塊設置為活動IDB(請參閱lm的modlist增強版本) |
modmap <base> <size> <name> | 綜合(“偽造”)模塊(使用其基礎地址和大小定義)添加到調試器內部列表中 |
modunmap <base> | 在基地地址上刪除先前映射的合成模塊 |
modcheck <||md5> | 用於檢查當前模塊是否確實與IDB的文件匹配(例如:模塊已更新) |
bpcmds <||save|load|> | bpcmds包裝器,保存和重新加載.bpcmds (斷點命令列表)輸出到當前IDB |
ks | 調試器標記語言(DML)增強KV命令的輸出 |
GDB特定命令:
| 調試器命令 | 描述 |
|---|---|
bbt | 美麗的回溯。類似於GDB中的BT ,但請求拆卸器的符號 |
patch | 基於實時上下文中拆卸器中的補丁字節 |
bx | 類似於GDB X,但使用符號。該符號將通過拆卸器解決 |
cc | 繼續符合拆卸器 |
Overwrite idb name輸入字段旨在更改默認的IDB名稱。它是插件用於向調度程序註冊的名稱。 IDB自動開關基於模塊名稱匹配。如果名稱相互衝突(例如foo.exe和foo.dll ),則可以用來簡化匹配。請注意,如果您在同步活動時修改輸入字段,則必須與調度程序重新註冊;這可以簡單地使用“ Restart ”按鈕完成。
為了提醒您,默認情況下可以使用.sync配置文件別名。
ret-sync在IDA中定義了這些全球捷徑:
Alt-Shift-S運行RET-Sync插件Ctrl-Shift-S切換全局同步Ctrl-H切換十六進制射線同步調試工具欄中還可以使用兩個按鈕,以切換全局和十六進制射線同步。
Syncplugin.py還註冊調試器命令包裝器Hotkeys。
F2在光標地址設置斷點F3在光標地址設置一聲斷點Ctrl-F2在光標地址設置硬件斷點Ctrl-F3在光標地址設置一擊硬件斷點Alt-F2翻譯(在調試器中折疊)當前光標地址Alt-F5去Ctrl-Alt-F5 -run(僅GDB)F10單步F11單個跟踪這些命令僅在當前IDB處於活動狀態時可用。如果可能的話,他們也已為其他辯論者實施。
一旦Retsyncplugin打開,您可以通過簡單的Drag'n'Drop將其添加到CodeBrowser窗口中:

如果要查看幾個模塊,則需要在同一codebrowser查看器中打開文件,只需將“ drop”拖放到codebrowser窗口中的其他磁盤,以獲取上述結果。
ret-sync定義了吉德拉的這些全球捷徑:
Alt-S啟用同步Alt-Shift-S禁用同步Alt-R重新啟動同步Alt-Shift-R重新加載配置還實現了對調試器命令的綁定。它們類似於IDA擴展名(“ GO”命令除外)。
F2在光標地址設置斷點Ctrl-F2在光標地址設置硬件斷點Alt-F3在光標地址設置一聲斷點Ctrl-F3在光標地址設置一擊硬件斷點Alt-F2翻譯(在調試器中折疊)當前光標地址F5去Alt-F5 -Run(僅GDB)F10單步F11單個跟踪ret-sync在二元忍者中定義了這些全球捷徑:
Alt-S啟用同步Alt-Shift-S禁用同步還實現了對調試器命令的綁定。它們類似於IDA擴展名的。
F2在光標地址設置斷點Ctrl-F2在光標地址設置硬件斷點Alt-F3在光標地址設置一聲斷點Ctrl-F3在光標地址設置一擊硬件斷點Alt-F2翻譯(在調試器中折疊)當前光標地址Alt-F5去F10單步F11單個跟踪 [WinDbg]
0:000:x86> pr
eax=00000032 ebx=00000032 ecx=00000032 edx=0028eebc esi=00000032 edi=00000064
eip=00430db1 esp=0028ed94 ebp=00000000 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
image00000000_00400000+0x30db1:
00430db1 57 push edi
0:000:x86> dd esp 8
0028ed94 00000000 00433845 0028eebc 00000032
0028eda4 0028f88c 00000064 002b049e 00000110
0:000:x86> !cmt 0028ed94 00000000 00433845 0028eebc 00000032
[sync.dll] !cmt called
[IDA]
.text:00430DB1 push edi ; 0028ed94 00000000 00433845 0028eebc 00000032
[WinDbg]
0:000:x86> !rcmt
[sync] !rcmt called
[IDA]
.text:00430DB1 push edi
[WinDbg]
0:000:x86> !fcmt decodes buffer with key
[sync] !fcmt called
[IDA]
.text:004012E0 ; decodes buffer with key
.text:004012E0 public decrypt_func
.text:004012E0 decrypt_func proc near
.text:004012E0 push ebp
注意:呼叫此命令而無需重置該函數的評論。
[WinDbg]
0:000:x86> !lbl meaningful_label
[sync] !lbl called
[IDA]
.text:000000000040271E meaningful_label:
.text:000000000040271E mov rdx, rsp
[WinDbg]
0:000:x86> pr
eax=00000032 ebx=00000032 ecx=00000032 edx=0028eebc esi=00000032 edi=00000064
eip=00430db1 esp=0028ed94 ebp=00000000 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
image00000000_00400000+0x30db1:
00430db1 57 push edi
[sync.dll] !cmd r edi
[IDA]
.text:00430DB1 push edi ; edi=00000064
[WinDbg]
0:000> !idblist
> currently connected idb(s):
[0] target.exe
[WinDbg]
0:000> !syncmodauto off
[IDA]
[*] << broker << dispatcher msg: sync mode auto set to off
[WinDbg]
0:000:> !idbn 0
> current idb set to 0
在此示例中,當前的活動IDB客戶端將設置為:
[0] target.exe.
Alt-F2快捷方式)中使用,重新反映有關其模塊的姓名和偏移的地址。 ! 應作為十六進制價值通過。命令解析基於Python的-aargparse模塊。停止線解析使用-- 。
[WinDbg]
0:000:x86> !cmt -a 0x430DB2 comment
該地址必須是有效的指令的地址。
與主機同步:
gdb> sync
[sync] sync is now enabled with host 192.168.52.1
<not running>
gdb> r
Starting program: /bin/ls
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
使用命令,沒有“!”前綴
(gdb) cmd x/i $pc
[sync] command output: => 0x8049ca3: push edi
(gdb) synchelp
[sync] extension commands help:
> sync <host>
> syncoff
> cmt [-a address] <string>
> rcmt [-a address] <string>
> fcmt [-a address] <string>
> cmd <string>
> bc <on|off|>
> rln <address>
> bbt <symbol>
> patch <addr> <count> <size>
> bx /i <symbol>
> cc
> translate <base> <addr> <mod>
(gdb) bt
#0 0x0000000000a91a73 in ?? ()
#1 0x0000000000a6d994 in ?? ()
#2 0x0000000000a89125 in ?? ()
#3 0x0000000000a8a574 in ?? ()
#4 0x000000000044f83b in ?? ()
#5 0x0000000000000000 in ?? ()
(gdb) bbt
#0 0x0000000000a91a73 in IKE_GetAssembledPkt ()
#1 0x0000000000a6d994 in catcher ()
#2 0x0000000000a89125 in IKEProcessMsg ()
#3 0x0000000000a8a574 in IkeDaemon ()
#4 0x000000000044f83b in sub_44F7D0 ()
#5 0x0000000000000000 in ()
F3設置單發斷點和F5繼續進行的替代方法。如果您更喜歡從GDB進行操作,這將很有用。 (gdb) b* 0xA91A73
Breakpoint 1 at 0xa91a73
(gdb) c
Continuing.
Breakpoint 1, 0x0000000000a91a73 in ?? ()
(gdb) cc
[sync] current cursor: 0xa91a7f
[sync] reached successfully
(gdb)
lldb> process launch -s
lldb> sync
[sync] connecting to localhost
[sync] sync is now enabled with host localhost
[sync] event handler started
lldb> synchelp
[sync] extension commands help:
> sync <host> = synchronize with <host> or the default value
> syncoff = stop synchronization
> cmt <string> = add comment at current eip in IDA
> rcmt <string> = reset comments at current eip in IDA
> fcmt <string> = add a function comment for 'f = get_func(eip)' in IDA
> cmd <string> = execute command <string> and add its output as comment at current eip in IDA
> bc <on|off|> = enable/disable path coloring in IDA
color a single instruction at current eip if called without argument
lldb> cmt mooo
Alt+s )/Disable( Alt+u )同步。 Ctrl+s )/Disable( Ctrl+u )同步。由於OLLYDBG2 API的BETA狀態,僅實現了以下功能:
F7 ; F8用於步進]CTRL+;這是給出的CTRL+: ] 使用插件菜單或命令enable(“ !sync" )或禁用(“ !syncoff ”)同步。
使用命令
[sync] synchelp command!
[sync] extension commands help:
> !sync = synchronize with <host from conf> or the default value
> !syncoff = stop synchronization
> !syncmodauto <on | off> = enable / disable idb auto switch based on module name
> !synchelp = display this help
> !cmt <string> = add comment at current eip in IDA
> !rcmt <string> = reset comments at current eip in IDA
> !idblist = display list of all IDB clients connected to the dispatcher
> !idb <module name> = set given module as the active idb (see !idblist)
> !idbn <n> = set active idb to the n_th client. n should be a valid decimal value
> !translate <base> <addr> <mod> = rebase an address with respect to local module's base
注意:使用來自拆卸器(IDA/GHIDRA, Alt-F2快捷方式)的! translate命令,將使拆卸器窗口“跳”到特定地址(相當於X64DBG命令行中運行障礙的等效)。
即使沒有完整的調試環境或使用自定義工具,即使使用RET-Sync核心功能(與拆卸器,符號分辨率同步,符號分辨率)也可能需要使用。為此,提取了簡約的Python庫。
下面的示例說明了Python庫的使用情況,該腳本瀏覽了基於事件的日誌記錄/跟踪工具的輸出。
from sync import *
HOST = '127.0.0.1'
MAPPINGS = [
[ 0x555555400000 , 0x555555402000 , 0x2000 , " /bin/tempfile" ],
[ 0x7ffff7dd3000 , 0x7ffff7dfc000 , 0x29000 , " /lib/x86_64-linux-gnu/ld-2.27.so" ],
[ 0x7ffff7ff7000 , 0x7ffff7ffb000 , 0x4000 , " [vvar]" ],
[ 0x7ffff7ffb000 , 0x7ffff7ffc000 , 0x1000 , " [vdso]" ],
[ 0x7ffffffde000 , 0x7ffffffff000 , 0x21000 , " [stack]" ],
]
EVENTS = [
[ 0x0000555555400e74 , "malloc" ],
[ 0x0000555555400eb3 , "open" ],
[ 0x0000555555400ee8 , "exit" ]
]
synctool = Sync ( HOST , MAPPINGS )
for e in EVENTS :
offset , name = e
synctool . invoke ( offset )
print ( " 0x%08x - %s" % ( offset , name ))
print ( "[>] press enter for next event" )
input ()雖然最初專注於動態分析(DEBUGGERS),但可以擴展插件設置並與其他工具集成。
其他資源:
與GDB:
與windbg:
g ')的命令字符串,IDA的客戶端插件即使被通知。如果這些事件太多,這可能會導致重大減速。已經實施了有限的修復程序,最好的解決方案仍然是暫時同步。與Ghidra:
與ida:
衝突:
.sync配置文件來定義其他端口。 [INTERFACE]
host=127.0.0.1
port=9234
ret-sync是免費軟件:您可以將其重新分配和/或根據免費軟件基金會發布的GNU通用公共許可證的條款(該許可證版本3版本)或(在您的選項上)任何以後版本。
該程序的分佈是希望它將有用的,但沒有任何保修;即使沒有對特定目的的適銷性或適合性的隱含保證。有關更多詳細信息,請參見GNU通用公共許可證。
您應該已經收到了GNU通用公共許可證的副本以及此計劃。如果沒有,請參見http://www.gnu.org/licenses/。
二進制忍者插件按MIT許可發布。
向布魯斯·丹(Bruce Dang),斯特爾(Stalkr), @ivanlef0u,達米安·阿瑪(DamienAumaître),塞巴斯蒂安·雷納德(SébastienRenaud)和凱文·szkudlapski, @ m00dy ,@saidelike,xavier mehrenberger,ben64,ben64,raphaëligo,raphaëlRigo,jiss,jiss for他們的善意,善良,反饋和反饋和反饋。伊爾法克·吉爾法諾夫(Ilfak Guilfanov),伊戈爾·斯科辛斯基(Igor Skochinsky)和阿諾德·迪德(Arnaud Diederen)在IDA的內部和出色的支持下提供了幫助。感謝Jordan Wiens和Vector35。最後,也感謝所有貢獻者和所有報告問題/錯誤的人。