When to use / when not to use
- Use: the first step when you have just obtained an unknown sample; determine the file's true type and architecture; hash evidence before starting any analysis; entropy assessment of whether it is packed/encrypted
- Do not use: when the file type is already determined and you only need to dig deeper into the structure (go directly to the corresponding format skill [[re-format-pe]] / [[re-format-elf]] / [[re-format-macho]]); when you only need function logic (go to the decompilation skill)
- Do not use: when the sample is already confirmed to be packed and the goal is directly unpacking (go to the [[re-anti-analysis]] domain)
Tool preparation
Verify all tools before use. Refer to the highest principle in [[re-analyze/platform-tips]] (static analysis may skip the sandbox, but anything involving execution must always be sandboxed).
file —— file type determination
- Linux:
apt install file/dnf install file/pacman -S file(included in most distributions) - macOS:
brew install file(built in at /usr/bin/file) - Windows/WSL: use the Linux version inside WSL; on native Windows use the file bundled with Git for Windows or a third-party version
- Verification:
file --version
sha256sum / md5sum —— hash evidence
- Linux: included in coreutils (if not,
apt install coreutils/dnf install coreutils/pacman -S coreutils) - macOS: built in, use
shasum -a 256ormd5 - Windows/WSL: the Linux version inside WSL; on native Windows PowerShell:
Get-FileHash -Algorithm SHA256 - Verification:
sha256sum --version
strings —— key string extraction
- Linux: included in binutils (
apt install binutils/dnf install binutils/pacman -S binutils) - macOS:
brew install binutils(commands have theg-prefix, e.g.gstrings) orllvm-objdump --strings - Windows: Sysinternals
strings64.exe(choco:choco install sysinternals), or the Linux version inside WSL - Verification:
strings --version(Linux)/gstrings --version(macOS brew)
objdump / readelf —— architecture and header information confirmation
- Linux:
apt install binutils/dnf install binutils/pacman -S binutils - macOS:
brew install binutils(gobjdump) orbrew install llvm(llvm-objdump) - WSL: the Linux version can be used directly
- Verification:
objdump -V/readelf --version
xxd —— hexadecimal viewing
- Linux:
apt install xxd/dnf install vim-common/pacman -S xxd - macOS:
brew install xxd - WSL: the Linux version
- Verification:
xxd -v
ent / python —— entropy calculation
ent:apt install ent(Debian/Ubuntu); dnf/pacman have no official package → use the python approach- python (cross-platform fallback, recommended):
pip install --userNo dependencies needed, write a script directly or use a one-line command:python3 - <<'EOF' import math, collections data = open('sample.bin', 'rb').read() c = collections.Counter(data); n = len(data) e = -sum((v/n) * math.log2(v/n) for v in c.values()) print(f"entropy={e:.3f} bits/byte ({len(data)} bytes)") EOF - Verification: for
/dev/zerothe output entropy is ≈ 0.000, for a random file ≈ 7.9+
Operating steps
Execute in order, and record the result of each step.
-
file determines the format:
file sample.binRecord the Magic, format (PE32/PE32+, ELF 32/64-bit LSB, Mach-O arm64…), and architecture. The file conclusion cannot be fully trusted—magic numbers can be forged, so cross-validate with objdump afterward:
objdump -f sample.bin # 打印头信息与架构For ELF-like files, add
readelf -h sample.binto view the Machine field. -
Hash evidence (do this before touching the file):
sha256sum sample.bin > sample.sha256 md5sum sample.binSave the output as
sample.sha256, write it into the analysis notes. Any later modification to the file (patch/unpacked artifact) must be comparable against the original hash.- Packed sample: record the five-piece baseline before unpacking—after confirming it is packed (switch to [[re-anti-analysis]]) and before starting to unpack, record in addition to SHA256:PE timestamp(TimeDateStamp)、EP RVA(AddressOfEntryPoint)、section hash(VirtualSize of each section and data hash),import table(DLL names + imported API list,
objdump -p/ pefile export). Comparing this baseline before and after unpacking is the basis for judging "whether an analyzable state has been reached" ([[re-unpack-simple]] / [[re-unpack-advanced]]).
- Packed sample: record the five-piece baseline before unpacking—after confirming it is packed (switch to [[re-anti-analysis]]) and before starting to unpack, record in addition to SHA256:PE timestamp(TimeDateStamp)、EP RVA(AddressOfEntryPoint)、section hash(VirtualSize of each section and data hash),import table(DLL names + imported API list,
-
strings extracts key strings:
strings -n 6 sample.bin | head -100- Look for: readable filenames/URLs/paths,
flag/key/secret, error messages (leaking internal function names), Go/Rust runtime signatures (runtime.main、_ZN...) - Chinese environment: by default
stringsonly takes ASCII; usestrings -e l sample.binfor UTF-16 strings (little-endian 16-bit); for GBK Chinese strings firstxxd sample.bin | headvisually inspect the encoding then decide - When output is huge first
-n 6filter out short strings, then combine withgrep -iE 'http|flag|key|secret|dll|\.so'
- Look for: readable filenames/URLs/paths,
-
Entropy assessment:
ent sample.bin # 或 python 一行脚本(见工具准备)- Entropy > 7.0 bits/byte: suspected packing/encryption/compression → next handle via the [[re-anti-analysis]] path
- Entropy 4.5-7.0: mixed content, a common range for normal executables, continue
- Entropy < 4.5: mostly plaintext data/uncompressed code
- Per-section assessment is more accurate: use
objdump -hor pefile to compute entropy per section (a packer's signature is extremely high entropy in certain sections)
-
Security features and compiler identification:
readelf -h sample.bin | grep Type # ET_EXEC 通常为非 PIE;ET_DYN 可能是 PIE 或共享对象 readelf -d sample.bin | grep -i FLAGS_1 # FLAGS_1 含 PIE(DF_1_PIE)才是 PIE 可执行文件 readelf -l sample.bin | grep -A1 GNU_STACK # 栈含 E 权限=缺 NX readelf -l sample.bin | grep GNU_RELRO # 存在=RELRO 开启(Full 再查 BIND_NOW) readelf -s sample.bin | grep __stack_chk_fail # 有=canary 开启 strings sample.bin | grep -iE 'GCC:|clang version|Microsoft Visual' # 编译器特征- Compiler identification assists later judgment: MSVC commonly
__security_cookie, GCC/Clang commonly__stack_chk_fail(canary form differs) - Cryptographic constant detection goes to [[re-crypto-id]] (AES S-box / TEA delta fingerprints)
- Security features are written into the sections summary of the output contract, for reference by [[re-vuln]] / reporting
- Compiler identification assists later judgment: MSVC commonly
-
Decide the next step:
- Normal format + normal entropy → [[re-format-pe]] / [[re-format-elf]] / [[re-format-macho]] (by type)
- Abnormal entropy / suspicious section names (UPX0/.aspack) → go to [[re-anti-analysis]] to first confirm packing
- If the goal is dynamic behavior → in-sandbox [[re-tracing]] + [[re-gdb]] (see the highest principle of [[re-analyze/platform-tips]])
-
Output contract: output a structured summary per [[re-analyze/analysis-contract]] —Core fields(target_id / sha256 / evidence / findings / unverified)+ File-domain extension fields(arch / format / entropy / sections / imports_exports / strings_refs / security features), as input for the next stage (format / decompilation / sandbox) without rescanning. For non-file targets (protocols/models/devices), produce the contract per the corresponding domain fields (see [[re-analyze/analysis-contract]] §3.2), without applying file-domain fields.
Cross-domain combination
- [[re-binary-core]]: workflow step 2 always invokes this skill
- [[re-malware]] / [[re-firmware]] / [[re-mobile]] / [[re-ctf]]: the first step each gateway takes on a sample is reconnaissance
- This skill's conclusion (RE_TRIAGE result) determines subsequent format skill selection and is a mandatory prerequisite before all dynamic analysis
Common pitfalls and traps
- High entropy ≠ necessarily packed: compressed data (compressed sections inside UPX packers, zlib resource sections) also has entropy >7; judge in combination with section names and the import table, do not characterize based on entropy value alone
- strings Chinese environment encoding: Chinese strings are often GBK or UTF-16LE, by default
stringsoutputs garbled text/loses them — specify the encoding via the-eparameter, and if necessaryxxdvisually inspect - Hash first before touching the file: before any analysis, first sha256 for evidence; dynamic execution will contaminate the sample file, and without the original hash there is no basis for comparison
- For large files, full strings output can reach hundreds of MB → first
-nset a minimum length andheadtruncate - Tool error ≠ file corruption: Symptom—
file/readelf/objdumpreports an error or output is interrupted on the sample; Cause—the adversarial sample forges header fields (abnormal section header size, absurd program header count, missing dynamic section), causing the parser to fail, not because the file is actually corrupted; Countermeasure—first usexxdto manually verify the key header fields (e_lfanew / e_shoff / e_shnum / e_shentsize), manually repair them according to the real values, and then parse again; do not discard the sample as garbage - Not recording a baseline before unpacking → no basis for comparison: Symptom—after unpacking, you find that the EP has changed, sections have been added or removed, and the import table has become dynamic calls, making it impossible to tell whether this is normal packer behavior or an unpacking error; Cause—no baseline of the PE header / sections / import table was recorded before unpacking; Countermeasure—before starting, record the five-piece set according to step 2 (SHA256 / PE timestamp / EP RVA / section hash / import table), and after unpacking compare each item to determine success or failure
- Visible strings ≠ the answer (decoy flag): Symptom—
stringsdirectly shows a flag/key/critical string, but submitting it is incorrect; Cause—high-difficulty samples deliberately place decoys in positions where "analysts are most likely to see them and not suspect them" (DOS stub, resource section, obvious strings), while the real answer is hidden in the protocol logic/encrypted data; Countermeasure—strings are only clues, not conclusions; cross-validation is required (code references, protocol logic, comparison of multiple copies);the easier a position is to see, the more suspicious it is, especially when a "flag format" string appears in the DOS stub (inside the PE header), it is basically a trap