anti-reversing-techniques
マルウェアの解析回避技術、難読化、ソフトウェア保護手法を理解するためのスキルです。マルウェアのエvasion技術の分析、CTFチャレンジにおけるアンチデバッグ保護の実装、パックされたバイナリのリバースエンジニアリング、または仮想化環境を検出するセキュリティ研究ツールの構築時に活用できます。
description の原文を見る
Understand anti-reversing, obfuscation, and protection techniques encountered during software analysis. Use this skill when analyzing malware evasion techniques, when implementing anti-debugging protections for CTF challenges, when reverse engineering packed binaries, or when building security research tools that need to detect virtualized environments.
SKILL.md 本文
AUTHORIZED USE ONLY: このスキルはデュアルユース型のセキュリティ技術を含みます。バイパスおよび分析を進める前に:
- 認可の確認: ソフトウェア所有者からの明示的な書面による許可を得ているか、または合法的なセキュリティコンテキスト内で活動していることを確認してください (CTF、認可された侵入テスト、マルウェア分析、セキュリティ研究)
- スコープの文書化: あなたの活動が認可の範囲内に収まることを確認してください
- 法令遵守: ソフトウェア保護の無許可バイパスは法律違反である可能性があります (CFAA、DMCA 回避禁止条項など)
合法的な使用例: マルウェア分析、認可された侵入テスト、CTF 競技、学術的セキュリティ研究、所有またはライセンスを持つソフトウェアの分析
Anti-Reversing Techniques
認可されたソフトウェア分析、セキュリティ研究、およびマルウェア分析中に遭遇する保護メカニズムを理解します。この知識は、分析者が保護をバイパスして合法的な分析タスクを完了するのに役立ちます。
高度な技術については references/advanced-techniques.md を参照してください
Input / Output
提供するもの:
- バイナリパスまたはサンプル: 分析対象の実行可能ファイル、DLL、またはファームウェアイメージ
- プラットフォーム: Windows x86/x64、Linux、macOS、ARM — どのチェックが該当するかに影響します
- 目標: 動的分析のためのバイパス、保護タイプの識別、検出コードの構築、CTF の実装
このスキルが生成するもの:
- 保護の識別: 命名された技術 (例: RDTSC タイミングチェック、PEB BeingDebugged) とバイナリ内の位置
- バイパス戦略: 各チェックを無効化するための特定のパッチアドレス、フックポイント、またはツールコマンド
- 分析レポート: 各保護層、重大度、および推奨されるバイパスを列挙する構造化された調査結果
- コード成果物: Python/IDAPython スクリプト、GDB コマンドシーケンス、またはチェックのバイパスまたは実装用の C スタブ
Anti-Debugging Techniques
Windows Anti-Debugging
API-Based Detection
// IsDebuggerPresent
if (IsDebuggerPresent()) {
exit(1);
}
// CheckRemoteDebuggerPresent
BOOL debugged = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &debugged);
if (debugged) exit(1);
// NtQueryInformationProcess
typedef NTSTATUS (NTAPI *pNtQueryInformationProcess)(
HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
DWORD debugPort = 0;
NtQueryInformationProcess(
GetCurrentProcess(),
ProcessDebugPort, // 7
&debugPort,
sizeof(debugPort),
NULL
);
if (debugPort != 0) exit(1);
// Debug flags
DWORD debugFlags = 0;
NtQueryInformationProcess(
GetCurrentProcess(),
ProcessDebugFlags, // 0x1F
&debugFlags,
sizeof(debugFlags),
NULL
);
if (debugFlags == 0) exit(1); // 0 means being debugged
バイパス: x64dbg の ScyllaHide プラグインを使用します (すべての一般的なチェックを自動的にパッチします)。手動でバイパスする場合: IsDebuggerPresent の戻り値を 0 に強制し、PEB.BeingDebugged を 0 にパッチし、NtQueryInformationProcess をフックします。IDA では: ida_bytes.patch_byte(check_addr, 0x90)
PEB-Based Detection
// Direct PEB access
#ifdef _WIN64
PPEB peb = (PPEB)__readgsqword(0x60);
#else
PPEB peb = (PPEB)__readfsdword(0x30);
#endif
// BeingDebugged flag
if (peb->BeingDebugged) exit(1);
// NtGlobalFlag
// Debugged: 0x70 (FLG_HEAP_ENABLE_TAIL_CHECK |
// FLG_HEAP_ENABLE_FREE_CHECK |
// FLG_HEAP_VALIDATE_PARAMETERS)
if (peb->NtGlobalFlag & 0x70) exit(1);
// Heap flags
PDWORD heapFlags = (PDWORD)((PBYTE)peb->ProcessHeap + 0x70);
if (*heapFlags & 0x50000062) exit(1);
バイパス: x64dbg で gs:[60] (x64) または fs:[30] (x86) をダンプで追跡します。BeingDebugged (オフセット +2) を 0 に設定し、NtGlobalFlag (x64 ではオフセット +0xBC) をクリアします。
Timing-Based Detection
// RDTSC timing
uint64_t start = __rdtsc();
// ... some code ...
uint64_t end = __rdtsc();
if ((end - start) > THRESHOLD) exit(1);
// QueryPerformanceCounter
LARGE_INTEGER start, end, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
// ... code ...
QueryPerformanceCounter(&end);
double elapsed = (double)(end.QuadPart - start.QuadPart) / freq.QuadPart;
if (elapsed > 0.1) exit(1); // Too slow = debugger
// GetTickCount
DWORD start = GetTickCount();
// ... code ...
if (GetTickCount() - start > 1000) exit(1);
Python スクリプト — タイミングベースの anti-debug 検出スキャナー:
#!/usr/bin/env python3
"""Scan a binary for common timing-based anti-debug patterns."""
import re
import sys
PATTERNS = {
"RDTSC": rb"\x0f\x31", # RDTSC opcode
"RDTSCP": rb"\x0f\x01\xf9", # RDTSCP opcode
"GetTickCount": rb"GetTickCount\x00",
"QueryPerfCounter": rb"QueryPerformanceCounter\x00",
"NtQuerySysInfo": rb"NtQuerySystemInformation\x00",
}
def scan(path: str) -> None:
data = open(path, "rb").read()
print(f"Scanning: {path} ({len(data)} bytes)\n")
for name, pattern in PATTERNS.items():
hits = [m.start() for m in re.finditer(re.escape(pattern), data)]
if hits:
offsets = ", ".join(hex(h) for h in hits[:5])
print(f" [{name}] found at: {offsets}")
print("\nDone. Cross-reference offsets in IDA/Ghidra to find check logic.")
if __name__ == "__main__":
scan(sys.argv[1])
バイパス: ハードウェアブレークポイントを使用し (INT3 オーバーヘッドなし)、比較と条件付きジャンプを NOP、ハイパーバイザー経由で RDTSC をフリーズ、またはタイミング API をフックして一貫した値を返します。
Exception-Based Detection
// SEH: if debugger is attached it consumes the INT3 exception
// and execution falls through to exit(1) instead of the __except handler
__try { __asm { int 3 } }
__except(EXCEPTION_EXECUTE_HANDLER) { return; } // Clean: exception handled here
exit(1); // Dirty: debugger swallowed the exception
// VEH: register handler that self-handles INT3 (increments RIP past INT3)
// Debugger intercepts first, handler never runs → detected
LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ep) {
if (ep->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) {
ep->ContextRecord->Rip++;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
バイパス: x64dbg で、EXCEPTION_BREAKPOINT に対して「Pass exception to program」を設定します (Options → Exceptions → 0x80000003 を追加)。
Linux Anti-Debugging
// ptrace self-trace
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
// Already being traced
exit(1);
}
// /proc/self/status
FILE *f = fopen("/proc/self/status", "r");
char line[256];
while (fgets(line, sizeof(line), f)) {
if (strncmp(line, "TracerPid:", 10) == 0) {
int tracer_pid = atoi(line + 10);
if (tracer_pid != 0) exit(1);
}
}
// Parent process check
if (getppid() != 1 && strcmp(get_process_name(getppid()), "bash") != 0) {
// Unusual parent (might be debugger)
}
バイパス (LD_PRELOAD フック):
# hook.c: long ptrace(int request, ...) { return 0; }
# gcc -shared -fPIC -o hook.so hook.c
LD_PRELOAD=./hook.so ./target
GDB バイパスコマンドシーケンス:
# 1. Make ptrace(PTRACE_TRACEME) always return 0 (success)
catch syscall ptrace
commands
silent
set $rax = 0
continue
end
# 2. Bypass check after ptrace call: find "cmp rax, 0xffffffff; je <exit>"
# Clear ZF so the conditional jump is not taken:
# set $eflags = $eflags & ~0x40
# 3. Bypass /proc/self/status TracerPid check at the open() level
catch syscall openat
commands
silent
# If arg contains "status", patch the fd result to /dev/null equivalent
continue
end
# 4. Bypass parent process name check
set follow-fork-mode child
set detach-on-fork off
Anti-VM Detection
Hardware Fingerprinting
// CPUID-based detection
int cpuid_info[4];
__cpuid(cpuid_info, 1);
// Check hypervisor bit (bit 31 of ECX)
if (cpuid_info[2] & (1 << 31)) {
// Running in hypervisor
}
// CPUID brand string
__cpuid(cpuid_info, 0x40000000);
char vendor[13] = {0};
memcpy(vendor, &cpuid_info[1], 12);
// "VMwareVMware", "Microsoft Hv", "KVMKVMKVM", "VBoxVBoxVBox"
// MAC address prefix
// VMware: 00:0C:29, 00:50:56
// VirtualBox: 08:00:27
// Hyper-V: 00:15:5D
Registry/File Detection
// Windows registry keys
// HKLM\SOFTWARE\VMware, Inc.\VMware Tools
// HKLM\SOFTWARE\Oracle\VirtualBox Guest Additions
// HKLM\HARDWARE\ACPI\DSDT\VBOX__
// Files
// C:\Windows\System32\drivers\vmmouse.sys
// C:\Windows\System32\drivers\vmhgfs.sys
// C:\Windows\System32\drivers\VBoxMouse.sys
// Processes
// vmtoolsd.exe, vmwaretray.exe
// VBoxService.exe, VBoxTray.exe
Timing-Based VM Detection
// VM exits cause timing anomalies
uint64_t start = __rdtsc();
__cpuid(cpuid_info, 0); // Causes VM exit
uint64_t end = __rdtsc();
if ((end - start) > 500) {
// Likely in VM (CPUID takes longer)
}
バイパス: ベアメタル環境を使用し、VM を強化 (ゲストツールを削除し、MAC をランダム化し、アーティファクトファイルを削除)、バイナリの検出ブランチをパッチ、または FLARE-VM/REMnux を強化された設定で使用します。
高度な VM 検出 (RDTSC デルタキャリブレーション、VMware バックドアポート、ハイパーバイザーリーフ列挙、ゲストドライバーアーティファクトチェック) については、references/advanced-techniques.md を参照してください。
Code Obfuscation
Control Flow Obfuscation
Control Flow Flattening
// Original
if (cond) {
func_a();
} else {
func_b();
}
func_c();
// Flattened
int state = 0;
while (1) {
switch (state) {
case 0:
state = cond ? 1 : 2;
break;
case 1:
func_a();
state = 3;
break;
case 2:
func_b();
state = 3;
break;
case 3:
func_c();
return;
}
}
分析アプローチ:
- 状態変数を識別
- 状態遷移をマップ
- 元のフローを再構築
- ツール: D-810 (IDA)、SATURN
Opaque Predicates
int x = rand();
if ((x * x) >= 0) { real_code(); } // Always true → junk_code() is dead
if ((x*(x+1)) % 2 == 1) { junk(); } // Always false → consecutive product is even
分析アプローチ: シンボリック実行を介して不変式を識別 (angr、Triton)、または既知の opaque フォームをパターンマッチして削除します。
Data Obfuscation
String Encryption
// XOR encryption
char decrypt_string(char *enc, int len, char key) {
char *dec = malloc(len + 1);
for (int i = 0; i < len; i++) {
dec[i] = enc[i] ^ key;
}
dec[len] = 0;
return dec;
}
// Stack strings
char url[20];
url[0] = 'h'; url[1] = 't'; url[2] = 't'; url[3] = 'p';
url[4] = ':'; url[5] = '/'; url[6] = '/';
// ...
分析アプローチ:
# FLOSS for automatic string deobfuscation
floss malware.exe
# IDAPython string decryption
def decrypt_xor(ea, length, key):
result = ""
for i in range(length):
byte = ida_bytes.get_byte(ea + i)
result += chr(byte ^ key)
return result
API Obfuscation
// Dynamic API resolution
typedef HANDLE (WINAPI *pCreateFileW)(LPCWSTR, DWORD, DWORD,
LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
HMODULE kernel32 = LoadLibraryA("kernel32.dll");
pCreateFileW myCreateFile = (pCreateFileW)GetProcAddress(
kernel32, "CreateFileW");
// API hashing
DWORD hash_api(char *name) {
DWORD hash = 0;
while (*name) {
hash = ((hash >> 13) | (hash << 19)) + *name++;
}
return hash;
}
// Resolve by hash comparison instead of string
分析アプローチ: ハッシュアルゴリズムを識別し、既知の API 名ハッシュのデータベースを構築し、IDA の HashDB プラグインを使用するか、デバッガーで実行して、バイナリがランタイムで呼び出しを解決するのを待ちます。
Instruction-Level Obfuscation
; Dead code insertion — semantically inert but pollutes disassembly
push ebx / mov eax, 1 / pop ebx / xor ecx, ecx / add ecx, ecx
; Instruction substitution — same semantics, different encoding
xor eax, eax → sub eax, eax | mov eax, 0 | and eax, 0
mov eax, 1 → xor eax, eax; inc eax | push 1; pop eax
高度な anti-disassembly トリック (重複する命令、ジャンク バイト挿入、自己変更コード、ROP as obfuscation) については、references/advanced-techniques.md を参照してください。
Bypass Strategies Summary
General Principles
- 保護を理解する: どの技術が使用されているかを識別
- チェックを見つける: バイナリの保護コードを特定
- パッチまたはフック: チェックを常に成功するように変更
- 適切なツールを使用: ScyllaHide、x64dbg プラグイン
- 調査結果を文書化: バイパスされた保護についてメモを保持
Tool Recommendations
Anti-debug bypass: ScyllaHide, TitanHide
Unpacking: x64dbg + Scylla, OllyDumpEx
Deobfuscation: D-810, SATURN, miasm
VM analysis: VMAttack, NoVmp, manual tracing
String decryption: FLOSS, custom scripts
Symbolic execution: angr, Triton
Ethical Considerations
この知識は次の目的にのみ使用すべきです:
- 認可されたセキュリティ研究
- マルウェア分析 (防御的)
- CTF 競技
- 合法的な目的のための保護の理解
- 教育目的
決してバイパス保護を使用しないでください: ソフトウェア海賊行為、無許可アクセス、または悪意のある目的のため。
Troubleshooting
検出技術は x86 では機能しますが ARM では機能しません
RDTSC と CPUID は x86 のみです。ARM では、MRS x0, PMCCNTR_EL0 (カーネル PMU アクセスが必要) または clock_gettime(CLOCK_MONOTONIC) を使用します。PEB/TEB は ARM には存在しません — /proc/self/status (Linux) または task_info (macOS) に置き換えます。プラットフォーム固有の API を使用して検出ロジックを再構築します。
合法的なデバッガーまたは分析ツールでの誤検出
タイミングチェックは Process Monitor または AV フックが syscall レイテンシーを増加させると発火します。起動時にしきい値をキャリブレートします: ガード付きパスを 3 回測定し、mean + 3*stddev を使用します。ptrace チェックの場合、終了する前に /proc/<pid>/comm 経由で TracerPid comm 名を確認します — デバッガーではなく関連性のない監視ツールである可能性があります。
バイパスパッチが実行続行ではなくクラッシュを引き起こします
条件付きジャンプを NOP する前に、「検出された」ブランチを完全にトレースします。後で必要なヒープ状態を初期化または解放する場合、ジャンプをパッチするとそのセットアップをスキップして状態を破損します。代わりに、比較オペランドを予想される「クリーン」値にパッチするか、x64dbg のブレークポイントで「Set condition to always false」を使用してバイトを変更しないようにします。
Related Skills
binary-analysis-patterns— ELF/PE/Mach-O の静的および動的分析ワークフローmemory-forensics— プロセスメモリ取得、アーティファクト抽出、およびライブ分析protocol-reverse-engineering— カスタムバイナリプロトコルおよび暗号化ネットワークトラフィックのデコード
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- wshobson
- リポジトリ
- wshobson/agents
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/wshobson/agents / ライセンス: MIT
関連スキル
secure-code-guardian
認証・認可の実装、ユーザー入力の保護、OWASP Top 10の脆弱性対策が必要な場合に使用します。bcrypt/argon2によるパスワードハッシング、パラメータ化ステートメントによるSQLインジェクション対策、CORS/CSPヘッダーの設定、Zodによる入力検証、JWTトークンの構築などのカスタムセキュリティ実装に対応します。認証、認可、入力検証、暗号化、OWASP Top 10対策、セッション管理、セキュリティ強化全般で活用できます。ただし、構築済みのOAuth/SSO統合や単独のセキュリティ監査が必要な場合は、より特化したスキルの検討をお勧めします。
claude-authenticity
APIエンドポイントが本物のClaudeによって支えられているか(ラッパーやプロキシ、偽装ではないか)を、claude-verifyプロジェクトを模した9つの重み付きルールベースチェックで検証できます。また、Claudeの正体を上書きしているプロバイダーから注入されたシステムプロンプトも抽出します。完全に自己完結しており、httpx以外の追加パッケージは不要です。Claude APIキーまたはエンドポイントを検証したい場合、サードパーティのClaudeサービスが本物か確認したい場合、APIプロバイダーのClaude正当性を監査したい場合、複数モデルを並行してテストしたい場合、またはプロバイダーが注入したシステムプロンプトを特定したい場合に使用できます。
anth-security-basics
Anthropic Claude APIのセキュリティベストプラクティスを適用し、キー管理、入力値の検証、プロンプトインジェクション対策を実施します。APIキーの保護、Claudeに送信する前のユーザー入力検証、コンテンツセーフティガードレールの実装が必要な場合に活用できます。「anthropic security」「claude api key security」「secure anthropic」「prompt injection defense」といったフレーズでトリガーされます。
x-ray
x-ray.mdプレ監査レポートを生成します。概要、強化された脅威モデル(プロトコルタイプのプロファイリング、Gitの重み付け攻撃面分析、時間軸リスク分析、コンポーザビリティ依存関係マッピング)、不変条件、統合、ドキュメント品質、テスト分析、開発者・Gitの履歴をカバーしています。「x-ray」「audit readiness」「readiness report」「pre-audit report」「prep this protocol」「protocol prep」「summarize this protocol」のキーワードで実行されます。
semgrep
Semgrepスタティック分析スキャンを実行し、カスタム検出ルールを作成します。Semgrepでのコードスキャン、セキュリティ脆弱性の検出、カスタムYAMLルールの作成、または特定のバグパターンの検出が必要な場合に使用します。重要:ユーザーが「バグをスキャンしたい」「コード品質を確認したい」「脆弱性を見つけたい」「スタティック分析」「セキュリティlint」「コード監査」または「コーディング標準を適用したい」と尋ねた場合も、Semgrepという名称を明記していなくても、このスキルを使用してください。Semgrepは30以上の言語に対応したパターンベースのコードスキャンに最適なツールです。
ghost-bits-cast-attack
Java「ゴーストビッツ」/キャストアタック プレイブック(Black Hat Asia 2026)。16ビット文字が8ビットバイトに暗黙的に縮小されるJavaサービスへの攻撃時に使用します。WAF/IDSを回避して、SQLインジェクション、デシリアライゼーション型RCE、ファイルアップロード(Webシェル)、パストトラバーサル、CRLF インジェクション、リクエストスマグリング、SMTPインジェクションを実行できます。Tomcat、Spring、Jetty、Undertow、Vert.x、Jackson、Fastjson、Apache Commons BCEL、Apache HttpClient、Angus Mail、JDK HttpServer、Lettuce、Jodd、XMLWriterに影響し、WAFバイパスにより多くの「パッチ済み」CVEを再度有効化します。