
ret-sync는 디버깅 세션(WinDbg/GDB/LLDB/OllyDbg2/x64dbg)을 IDA/Ghidra/Binary Ninja 디스어셈블러와 동기화하는 데 도움이 되는 플러그인 세트입니다.
ret-sync는 Reverse-Engineering Tools SYNChronization을 의미합니다. 이는 디버깅 세션(WinDbg/GDB/LLDB/OllyDbg/OllyDbg2/x64dbg)을 디스어셈블러(IDA/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: Ghidra 플러그인ext_bn/retsync: Binary Ninja 플러그인그리고 라이브러리 플러그인:
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>.rep)에서 구성 파일을 찾아 로컬(per-IDB/project) 설정을 허용합니다. 로컬 구성 파일이 있으면 전역 구성 파일은 무시됩니다.
이러한 구성 파일에 선언된 값은 기본값을 재정의합니다. 기본적으로 .sync 파일은 생성되지 않습니다.
아래에서는 구성 파일이 유용하거나 필요한 세 가지 일반적인 시나리오를 자세히 설명합니다:
[INTERFACE] 섹션은 네트워크 관련 설정을 사용자 정의하는 데 사용됩니다. 가상 머신(또는 단순히 다른 호스트) 내에서 실행 중인 디버거와 IDA를 동기화하려는 일반적인 원격 커널 디버깅 시나리오를 가정해 보겠습니다.
간단히 두 개의 .sync 파일을 만듭니다:
이는 **ret-sync** ``IDA`` 플러그인이 인터페이스 ``192.168.128.1``에서 포트 ``9234``로 수신하도록 지시합니다. 말할 필요도 없이 이 인터페이스는 원격 호스트나 가상 머신에서 접근 가능해야 합니다.
* 디버거가 실행되는 머신의 사용자 홈 디렉토리에 있는 하나:```
[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 이름) 대신 일치시키도록 알려줍니다.
## gdb with Qt Creator debugging frontend
Qt Creator 디버깅 프론트엔드는 gdb 명령어 출력이 기록되는 방식을 변경합니다. 이는 동기화를 방해하므로 임시 파일 대신 동기화에 원시 gdb 출력을 사용하는 옵션이 있습니다. `.sync` 설정 파일에서 사용```
[GENERAL]
use_tmp_logging_file=false
타겟에 Qt 디버깅 프론트엔드를 사용하려면.
/proc/<pid>/maps직렬 연결을 통한 임베디드 장치 디버깅 또는 QEMU에서의 raw 펌웨어 디버깅과 같은 일부 시나리오에서는 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``.
## 자동 주소 재배치 우회
임베디드 장치 디버깅이나 미니멀한 디버그 인터페이스에 연결하는 등의 시나리오에서는 디스어셈블러 플러그인에 구현된 자동 주소 재배치 기능을 우회하는 것이 더 편리할 수 있습니다.
`use_raw_addr` 옵션은 현재 Ghidra에서만 지원됩니다. .sync 설정 파일에서 다음과 같이 사용합니다:```
[GENERAL]
use_raw_addr=true
IDA 9.2+가 필요합니다. 이전 버전의 경우 사용 가능한 Tags에서 ida9.2 태그 이전의 프로젝트를 체크아웃하세요.
IDA 설치의 경우, ext_ida에서 Syncplugin.py 및 retsync 폴더를 IDA 플러그인 디렉터리로 복사하세요. 예:
C:\Program Files\IDA Pro 7.4\plugins%APPDATA%\Hex-Rays\IDA Pro\plugins~/.idapro/pluginsAlt-Shift-S) 또는 Edit -> Plugins -> ``ret-sync`````
[sync] default idb name: ld.exe
[sync] sync enabled
[sync] cmdline: "C:\Program Files\Python38\python.exe" -u "C:\Users\user\AppData\Roaming\Hex-Rays\IDA Pro\plugins\retsync\broker.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 플러그인 문제 해결
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 Public용입니다.
3. Ghidra 설치에 맞게 확장 프로그램 빌드 (`$GHIDRA_DIR`을 설치 디렉터리로 바꾸세요)```bash
cd ext_ghidra
gradle -PGHIDRA_INSTALL_DIR=$GHIDRA_DIR
File -> Install Extensions...를 선택한 후,
+ 기호를 클릭하고 ext_ghidra/dist/ghidra_*_retsync.zip 파일을 선택한 후 확인을 클릭합니다.
이렇게 하면 zip 파일에서 retsync 폴더가 $GHIDRA_DIR/Extensions/Ghidra/로 추출됩니다.4. Ghidra CodeBrowser 도구: 툴바 아이콘이나 단축키를 사용하여 동기화를 활성화(``Alt+s``)/비활성화(``Alt+Shift+s``)/재시작(``Alt+r``)
합니다.
상태 창은 ``Windows`` -> ``RetSyncPlugin``에서도 사용할 수 있습니다. 일반적으로 Ghidra 환경 창과 통합하기 위해
측면에 배치하는 것이 좋습니다.
## Binary Ninja 확장
Binary Ninja 지원은 실험적이므로 분석 데이터베이스를 백업하세요.
### Binary Ninja 필수 조건
**ret-sync**는 최소 Binary Ninja 버전 2.2 및 Python 3이 필요합니다(Python 2는 지원되지 않습니다).
### Binary Ninja 확장 설치
**ret-sync**는 아직 Binary Ninja의 플러그인 관리자를 통해 배포되지 않습니다. 수동 설치가 필요합니다. `ext_bn` 폴더의 내용을 Binary Ninja의 플러그인 폴더에 복사하기만 하면 됩니다. 예:
`%APPDATA%\Binary Ninja\plugins`
Binary Ninja를 다시 시작하면 콘솔 창에 다음 출력이 표시되어야 합니다:```
[sync] commands added
Loaded python3 plugin 'retsync'
ext_windbg에 제공된 Visual Studio 2017 솔루션을 사용합니다.
Visual Studio Community Edition
2017 및 2026이 성공적으로 테스트되었습니다(그 사이의 버전도 작동할 것입니다).
이렇게 하면 x64\release\sync.dll 파일이 빌드됩니다.
빌드된 sync.dll 파일을 적절한 WinDbg 확장 경로에 복사해야 합니다.
이전 버전의 WinDbg의 경우, 경로는 대략 다음과 같습니다(x86/x64 비트에 주의). 예:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\sync.dll
확장 프로그램을 저장하는 폴더는 PATH 기반으로 설정되는 것으로 보이므로, 쿼리되는 위치 중 하나에 넣어야 합니다.
예를 들어, 다음 위치에 넣을 수 있습니다:
C:\Users\user\AppData\Local\Microsoft\WindowsApps\sync.dll
.load 명령어).```
0:000> .load sync
[sync.dll] DebugExtensionInitialize, ExtensionApis loaded3. WinDbg 동기화```
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 - HostMachine\HostUser [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가 잘못된 버전의 확장을 로드하려 했음을 의미합니다. 예: ``x86`` `sync.dll` 대신 ``x64``를 사용한 경우.```
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 Preview가 동일한 디렉터리에서 두 플러그인(x86 및 x64)을 모두 로드하므로, x86 파일 sync32.dll의 이름을 바꿀 수 있습니다.```
0:000> .load sync32
## GNU gdb (GDB) 설치
1. 원하는 디렉토리에 `ext_gdb/sync.py`를 복사하세요
2. 확장 프로그램을 로드하십시오 (auto-load-scripts 참조)```
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 설치
OllyDbg 1.10 지원은 실험적이지만, 다음과 같습니다:
1. VS 솔루션을 사용하여 플러그인을 빌드합니다(선택 사항, 사전 빌드된 바이너리 참조).
2. dll을 OllyDbg의 플러그인 디렉터리에 복사합니다.
## OllyDbg2 설치
OllyDbg2 지원은 실험적이지만, 다음과 같습니다:
1. VS 솔루션을 사용하여 플러그인을 빌드합니다(선택 사항, 사전 빌드된 바이너리 참조).
2. dll을 OllyDbg2의 플러그인 디렉터리에 복사합니다.
## x64dbg 설치
testplugin(https://github.com/x64dbg/testplugin)을 기반으로 합니다. x64dbg 지원은 실험적이지만, 다음과 같습니다:
1. VS 솔루션을 사용하여 플러그인을 빌드합니다(선택 사항, 사전 빌드된 바이너리 참조).
플러그인 SDK의 다른 버전이 필요할 수 있으며,
사본은 각 x64dbg 릴리스에서 찾을 수 있습니다.
``pluginsdk`` 디렉터리를 ``ext_x64dbg\x64dbg_sync``에 붙여넣습니다.
2. dll(확장자는 ``.d32`` 또는 ``.dp64``)을 x64dbg의 플러그인 디렉터리에 복사합니다.
# 사용법
## **ret-sync** 디버거 명령어
명령줄 지향 디버거(주로 Windbg 및 GDB)의 경우 **ret-sync**에서 리버스 엔지니어링 작업을 지원하기 위해 명령어 집합을 제공합니다.
아래 명령어는 일반적입니다(Windbg 및 GDB). WinDbg에서는 `!` 접두사가 필요합니다(예: GDB의 `sync`, WinDbg의 `!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>` | 활성 IDB를 n번째 클라이언트로 설정 |
| `jmpto <expression>` | |
| `jmpraw <expression>` | IDB가 활성화된 경우 디스어셈블러 보기가 결과 주소와 동기화됩니다. |
| `translate <base> <addr> <mod>` | 모듈 이름 및 오프셋을 기준으로 주소 재배치 |
WinDbg 전용 명령어:
| 디버거 명령어 | 설명 |
|----------------------------|-------------------------------------------------------------------------------------------|
| `curmod` | 현재 명령어 오프셋에 대한 모듈 정보 표시(문제 해결용) |
| `modlist` | 더 원활한 활성 IDB 전환을 위한 DML(Debugger Markup Language) 향상 모듈 목록 |
| `idb <module name>` | 주어진 모듈을 활성 IDB로 설정(`modlist` 참조, `lm`의 향상된 버전) |
| `modmap <base> <size> <name>` | 합성("가짜") 모듈(기본 주소와 크기로 정의)이 디버거 내부 목록에 추가됩니다 |
| `modunmap <base>` | 기본 주소에서 이전에 매핑된 합성 모듈 제거 |
| `modcheck <\|\|md5>` | 현재 모듈이 IDB의 파일과 실제로 일치하는지 확인하는 데 사용(예: 모듈이 업데이트된 경우) |
| `bpcmds <\|\|save\|load\|>` | **bpcmds** 래퍼, **.bpcmds** (중단점 명령어 목록) 출력을 현재 IDB에 저장 및 다시 로드 |
| `ks` | **kv** 명령어의 DML(Debugger Markup Language) 향상 출력 |
GDB 전용 명령어:
| 디버거 명령어 | 설명 |
|----------------------------|-------------------------------------------------------------------------------------------|
|`bbt` | 아름다운 백트레이스. GDB의 **bt**와 유사하지만 디스어셈블러에서 심볼을 요청합니다 |
| `patch` | 라이브 컨텍스트를 기반으로 디스어셈블러에서 바이트 패치 |
| `bx` | GDB **x**와 유사하지만 심볼을 사용합니다. 심볼은 디스어셈블러에 의해 확인됩니다 |
| `cc` | 디스어셈블러에서 커서까지 계속 실행 |
## IDA 사용법
### IDA 플러그인 GUI
``Overwrite idb name`` 입력 필드는 기본 IDB 이름을 변경하기 위한 것입니다. 이는 플러그인이 디스패처에 등록하는 데 사용하는 이름입니다. IDB 자동 전환은 모듈 이름 일치를 기반으로 합니다. 이름이 충돌하는 경우(예: ``foo.exe`` 및 ``foo.dll``) 일치를 쉽게 하기 위해 사용할 수 있습니다. 동기화가 활성화된 상태에서 입력 필드를 수정하면 디스패처에 다시 등록해야 합니다. 이는 "``Restart``" 버튼을 사용하여 간단히 수행할 수 있습니다. 참고로 ``.sync`` 구성 파일을 사용하여 기본적으로 별칭을 지정할 수 있습니다.
### IDA 전역 단축키
**ret-sync**는 IDA에서 다음 전역 단축키를 정의합니다:
* ``Alt-Shift-S`` - **ret-sync** 플러그인 실행
* ``Ctrl-Shift-S`` - 전역 동기화 전환
* ``Ctrl-H`` - Hex-Rays 동기화 전환
전역 및 Hex-Rays 동기화를 전환하기 위한 두 개의 버튼이 디버그 도구 모음에도 있습니다.
### 디버거 명령어에 대한 IDA 바인딩
``Syncplugin.py``는 또한 디버거 명령어 래퍼 단축키를 등록합니다.
* ``F2`` - 커서 주소에 중단점 설정
* ``F3`` - 커서 주소에 일회성 중단점 설정
* ``Ctrl-F2`` - 커서 주소에 하드웨어 중단점 설정
* ``Ctrl-F3`` - 커서 주소에 일회성 하드웨어 중단점 설정
* ``Alt-F2`` - 현재 커서 주소 변환(디버거에서 재배치)
* ``Alt-F5`` - 이동
* ``Ctrl-Alt-F5`` - 실행(GDB 전용)
* ``F10`` - 한 단계 실행
* ``F11`` - 한 단계 추적
이 명령어는 현재 IDB가 활성 상태인 경우에만 사용할 수 있습니다. 가능한 경우 다른 디버거에 대해서도 구현되었습니다.
## Ghidra 사용법
### Ghidra 플러그인 GUI
RetSyncPlugin을 열면 간단히 드래그 앤 드롭하여 CodeBrowser 창에 추가할 수 있습니다:

여러 모듈을 보려면 동일한 CodeBrowser 뷰어에서 파일을 열어야 합니다. 위와 같은 결과를 얻으려면 추가 파일을 CodeBrowser 창에 드래그 앤 드롭하면 됩니다.
### Ghidra 전역 단축키
**ret-sync**는 Ghidra에서 다음 전역 단축키를 정의합니다:
* ``Alt-S`` - 동기화 활성화
* ``Alt-Shift-S`` - 동기화 비활성화
* ``Alt-R`` - 동기화 다시 시작
* ``Alt-Shift-R`` - 구성 다시 로드
### 디버거 명령어에 대한 Ghidra 바인딩
디버거 명령어에 대한 바인딩도 구현되어 있습니다. IDA 확장의 바인딩과 유사합니다("Go" 명령어 제외).
* ``F2`` - 커서 주소에 중단점 설정
* ``Ctrl-F2`` - 커서 주소에 하드웨어 중단점 설정
* ``Alt-F3`` - 커서 주소에 일회성 중단점 설정
* ``Ctrl-F3`` - 커서 주소에 일회성 하드웨어 중단점 설정
* ``Alt-F2`` - 현재 커서 주소 변환(디버거에서 재배치)
* ``F5`` - 이동
* ``Alt-F5`` - 실행(GDB 전용)
* ``F10`` - 한 단계 실행
* ``F11`` - 한 단계 추적
## Binary Ninja 사용법
### Binary Ninja 전역 단축키
**ret-sync**는 Binary Ninja에서 다음 전역 단축키를 정의합니다:
* ``Alt-S`` - 동기화 활성화
* ``Alt-Shift-S`` - 동기화 비활성화
### Binary Ninja 단축키
디버거 명령어에 대한 바인딩도 구현되어 있습니다. IDA 확장의 바인딩과 유사합니다.
* ``F2`` - 커서 주소에 중단점 설정
* ``Ctrl-F2`` - 커서 주소에 하드웨어 중단점 설정
* ``Alt-F3`` - 커서 주소에 일회성 중단점 설정
* ``Ctrl-F3`` - 커서 주소에 일회성 하드웨어 중단점 설정
* ``Alt-F2`` - 현재 커서 주소 변환(디버거에서 재배치)
* ``Alt-F5`` - 이동
* ``F10`` - 한 단계 실행
* ``F11`` - 한 단계 추적
## WinDbg 사용법
### WinDbg 플러그인 명령어
* **!sync**: 동기화 시작
* **!syncoff**: 동기화 중지
* **!synchelp**: 사용 가능한 명령어 목록을 간단한 설명과 함께 표시합니다.
* **!cmt [-a address] <string>**: IDA의 현재 ip에 주석 추가```
[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
!rcmt [-a address]: IDA에서 현재 ip의 주석을 재설정합니다.``` [WinDbg] 0:000:x86> !rcmt [sync] !rcmt called
[IDA] .text:00430DB1 push edi
* **!fcmt [-a address] <string>**: 현재 IP가 위치한 함수에 대한 함수 주석을 추가합니다.```
[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
참고: 이 명령어를 인자 없이 호출하면 함수의 주석이 초기화됩니다.
!raddr : 표현식에서 평가된 재배치된 주소를 주석으로 추가합니다.
!rln : 주어진 주소에 대한 디스어셈블러에서 심볼을 가져옵니다.
!lbl [-a address] : 디스어셈블러의 현재 IP에 레이블 이름을 추가합니다.``` [WinDbg] 0:000:x86> !lbl meaningful_label [sync] !lbl called
[IDA] .text:000000000040271E meaningful_label: .text:000000000040271E mov rdx, rsp
* **!cmd <string>**: WinDbg에서 명령을 실행하고 그 출력을 디스어셈블러의 현재 ip에 주석으로 추가합니다```
[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
currently connected idb(s): [0] target.exe
* **!syncmodauto <on|off>**: 모듈 이름에 따라 디스어셈블러 자동 전환을 활성화/비활성화합니다.```
[WinDbg]
0:000> !syncmodauto off
[IDA]
[*] << broker << dispatcher msg: sync mode auto set to off
current idb set to 0
이 예제에서 현재 활성 IDB 클라이언트는 다음으로 설정되었을 것입니다:```
[0] target.exe.
Alt-F2 단축키). 모듈 이름과 오프셋을 기준으로 주소를 재배치합니다.!cmt, !rcmt 및 !fcmt 명령어는 선택적 주소 옵션 -a 또는 --address를 지원합니다. 주소는 16진수 값으로 전달해야 합니다. 명령어 구문 분석은 Python의 argparse 모듈을 기반으로 합니다. 줄 구문 분석을 중지하려면 --를 사용하세요.```
[WinDbg]
0:000:x86> !cmt -a 0x430DB2 comment
주소는 유효한 명령어의 주소여야 합니다.
## GNU gdb (GDB) usage
호스트와 동기화:```
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>
* **rln**: 주어진 주소에 대해 IDB에서 심볼을 가져옵니다.
* **bbt**: 아름다운 백트레이스. **bt**와 유사하지만 디스어셈블러에서 심볼을 요청합니다.```
(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 ()
patch: 디스어셈블러에서 라이브 컨텍스트를 기반으로 바이트 패치
bx: 아름다운 표시. x와 유사하지만 심볼을 사용합니다. 심볼은 디스어셈블러에 의해 해석됩니다.
cc: 디스어셈블러에서 커서까지 계속 실행. 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 사용법
1. 호스트와 동기화```
lldb> process launch -s
lldb> sync
[sync] connecting to localhost
[sync] sync is now enabled with host localhost
[sync] event handler started
sync = synchronize with or the default value syncoff = stop synchronization cmt = add comment at current eip in IDA rcmt = reset comments at current eip in IDA fcmt = add a function comment for 'f = get_func(eip)' in IDA cmd = execute command 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
## OllyDbg 1.10 사용법
1. 플러그인 메뉴 또는 단축키를 사용하여 동기화를 활성화(``Alt+s``)하거나 비활성화(``Alt+u``)합니다.
## OllyDbg2 사용법
1. 플러그인 메뉴 또는 단축키를 사용하여 동기화를 활성화(``Ctrl+s``)하거나 비활성화(``Ctrl+u``)합니다.
OllyDbg2 API의 베타 상태로 인해 다음 기능만 구현되었습니다:
- 그래프 동기화 [단계별 실행 시 ``F7``; ``F8`` 사용]
- 주석 [``CTRL+;`` 사용]
- 레이블 [``CTRL+:`` 사용]
## x64dbg 사용법
1. 플러그인 메뉴 또는 명령어를 사용하여 동기화를 활성화("``!sync"``)하거나 비활성화("``!syncoff``")합니다.
2. 명령어 사용```
[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
> !insync = synchronize the selected instruction block in the disassembly window.
참고: 디스어셈블러(IDA/Ghidra)에서 !translate 명령어를 사용하면(Alt-F2 단축키) 디스어셈블러 창이 특정 주소로 "이동"합니다(x64dbg 명령줄에서 disasm 실행한 것과 동일).
완전한 디버깅 환경이 없거나 사용자 정의 도구를 사용하는 경우에도 ret-sync의 핵심 기능(디스어셈블러와의 위치 동기화, 심볼 해석)을 사용하고 싶을 수 있습니다. 이를 위해 최소한의 Python 라이브러리가 추출되었습니다.
아래 예제는 이벤트 기반 로깅/추적 도구의 출력을 탐색하는 스크립트와 함께 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()
# Extend
초기에는 동적 분석(디버거)에 중점을 두었지만, 물론 플러그인 세트를 확장하고 다른 도구와 통합하는 것이 가능합니다.
- **REVEN** Timeless Analysis and Debugging Platform (제공: [Tetrane](https://www.tetrane.com/))과의 통합:
- http://blog.tetrane.com/2015/02/reven-in-your-toolkit.html
- https://twitter.com/tetrane/status/1374768014193799175
- Assaf Carlsbad([@assaf_carlsbad](https://twitter.com/assaf_carlsbad))의 **EFI DXE Emulator**와의 통합:
- https://twitter.com/assaf_carlsbad/status/1242114356881641474
- https://github.com/assafcarlsbad/efi_dxe_emulator
기타 자료:
- "*정적 및 동적 바이너리 분석 결합 - ret-sync*", 저자: Jean-Christophe Delaunay
- https://www.synacktiv.com/ressources/bieresecu1_ret-sync_en.pdf
# TODO
- 물론.
# 알려진 버그/제한 사항
- Python 2.7/3.7, IDA 7.7(Windows, Linux 및 Mac OS X), Ghidra 10.1.1, Binary Ninja 3.0.3225-dev, GNU gdb(GDB) 8.1.0(Debian), lldb 310.2.37에서 테스트되었습니다.
- 양자 간에는 **인증/암호화가 전혀 없습니다**; 사용자의 책임입니다.
- 자기 수정 코드는 범위를 벗어납니다.
GDB 사용 시:
- 'return' 명령어 사용 시 중지 이벤트가 호출되지 않는 것으로 보입니다.
- 다중 스레드 디버깅에서 시그널에 문제가 있습니다.
WinDbg 사용 시:
- IDA 클라이언트 플러그인이 중단점이 계속 실행되도록 하는 명령 문자열('``g``')을 사용하더라도 알림을 받습니다. 이러한 이벤트가 너무 많으면 심각한 속도 저하가 발생할 수 있습니다. 제한적인 수정이 구현되었지만, 가장 좋은 해결책은 일시적으로 동기화를 끄는 것입니다.
- 경쟁 조건 가능성
Ghidra 사용 시:
- 디컴파일러 위젯에서 단축키가 예상대로 작동하지 않습니다.
IDA 사용 시:
- 큰 그래프의 경우 그래프 창 다시 그리기가 상당히 느립니다.
- Linux 환경에서 **ret-sync** 단축키 충돌이 발생합니다.
충돌:
- Logitech Updater 소프트웨어가 동일한 기본 포트(9100)를 사용하는 것으로 알려져 있습니다. 해결 방법은 전역 `.sync` 구성 파일을 사용하여 다른 포트를 정의하는 것입니다.```
[INTERFACE]
host=127.0.0.1
port=9234
ret-sync는 자유 소프트웨어입니다: 자유 소프트웨어 재단(Free Software Foundation)에서 발행한 GNU 일반 공중 사용 허가서(GNU General Public License) 버전 3 또는 (선택에 따라) 이후 버전의 조건에 따라 이를 재배포하거나 수정할 수 있습니다.
이 프로그램은 유용하게 사용될 수 있으리라는 희망으로 배포되지만, 어떠한 보증도 제공하지 않습니다. 상품성 또는 특정 목적에의 적합성에 대한 묵시적 보증조차도 없습니다. 자세한 내용은 GNU 일반 공중 사용 허가서를 참조하십시오.
이 프로그램과 함께 GNU 일반 공중 사용 허가서의 사본을 받았을 것입니다. 받지 못했다면 http://www.gnu.org/licenses/를 방문하십시오.
Binary Ninja 플러그인은 MIT 라이선스 하에 배포됩니다.
Bruce Dang, StalkR, @Ivanlef0u, Damien Aumaître, Sébastien Renaud, Kévin Szkudlapski, @m00dy, @saidelike, Xavier Mehrenberger, ben64, Raphaël Rigo, Jiss에게 그들의 친절, 도움, 피드백 및 생각에 감사드립니다. Ilfak Guilfanov, Igor Skochinsky, Arnaud Diederen에게 IDA 내부 및 뛰어난 지원에 대한 도움에 감사드립니다. Jordan Wiens와 Vector 35에게 감사드립니다. 마지막으로, 모든 기여자와 이슈/버그를 보고해 주신 모든 분들께도 감사드립니다.