Several scripts are included to generate offsets for SystemInformer's kphdyn.xml, adding your own "struct_offset", or even "func_offset" to it (can be customized via kphdyn.yaml).
wget https://raw.githubusercontent.com/winsiderss/systeminformer/refs/heads/master/kphlib/kphdyn.xmlcurl -O https://raw.githubusercontent.com/winsiderss/systeminformer/refs/heads/master/kphlib/kphdyn.xmlpowershell -Command "Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/winsiderss/systeminformer/refs/heads/master/kphlib/kphdyn.xml' -OutFile kphdyn.xml"Requirements are managed by pyproject.toml:
uv syncSystem dependencies (for signify library, required on Linux):
-
Ubuntu/Debian:
sudo apt-get update sudo apt-get install -y libssl-dev
-
CentOS/RHEL/Fedora:
sudo yum install -y openssl-devel # or on newer versions: sudo dnf install -y openssl-devel -
Fix oscrypto issue -
Error detecting the version of libcrypto:uv pip install -I "git+https://github.com/wbond/oscrypto.git"
Downloads PE files and their corresponding PDB symbol files from Microsoft Symbol Server
based on entries from kphdyn.xml
uv run download_symbols.py [-xml="path/to/kphdyn.xml"] [-symboldir="path/to/symbols"] [-arch=amd64] [-version=10.0.10240.16393] [-symbol_server="https://msdl.microsoft.com/download/symbols"] [-fast]export KPHTOOLS_XML="path/to/kphdyn.xml"
export KPHTOOLS_SYMBOLDIR="path/to/symbols"set KPHTOOLS_XML=path/to/kphdyn.xml
set KPHTOOLS_SYMBOLDIR=path/to/symbolsuv run download_symbols.py -fast -symboldir="C:\\Symbols"C:\Symbols\amd64\ntoskrnl.exe.10.0.10240.16393\{sha256}\ntoskrnl.exe
C:\Symbols\amd64\ntoskrnl.exe.10.0.10240.16393\{sha256}\ntkrnlmp.pdb
...others
Where {sha256} is the lowercase SHA256 hash of the PE file (e.g., 68d5867b5e66fce486c863c11cf69020658cadbbacbbda1e167766f236fefe78).
dump_symbols.py is the primary analysis entry point.
uv run dump_symbols.py [-symboldir="path/to/symbols"] [-configyaml="config.yaml"] [-version=10.0.26100.8246] [-arch=amd64] [-debug]The script scans <symboldir>/<arch>/<file>.<version>/<sha256>/, resolves symbols into {symbol}.yaml, and writes them next to the corresponding PE/PDB files.
LLM fallback options are shared by preprocessor scripts that declare LLM_DECOMPILE:
uv run dump_symbols.py \
-llm_model=gpt-5.4 \
-llm_apikey=sk-xxxxxxxxxxxxxxxx \
-llm_baseurl=https://api.example.com/v1 \
-llm_temperature=0.2 \
-llm_effort=medium \
-llm_fake_as=codexThe same values can be provided by .env or environment variables:
KPHTOOLS_LLM_MODEL=gpt-5.4
KPHTOOLS_LLM_APIKEY=sk-xxxxxxxxxxxxxxxx
KPHTOOLS_LLM_BASEURL=https://api.example.com/v1
KPHTOOLS_LLM_TEMPERATURE=0.2
KPHTOOLS_LLM_EFFORT=high
KPHTOOLS_LLM_FAKE_AS=codexWhen -llm_fake_as=codex is set, the LLM helper uses a direct /responses SSE transport instead of /competitions; -llm_baseurl should point at the OpenAI-compatible /v1 base URL.
generate_reference_yaml.py creates a single reference YAML at:
ida_preprocessor_scripts/references/<module>/<func_name>.<arch>.yaml
Attach to an existing MCP session:
uv run generate_reference_yaml.py -func_name="ExReferenceCallBackBlock"Auto-start idalib-mcp for a specific binary:
uv run generate_reference_yaml.py \
-func_name="ExReferenceCallBackBlock" \
-auto_start_mcp \
-binary="symbols/amd64/ntoskrnl.exe.10.0.26100.1/{sha256}/ntoskrnl.exe"Check the generated YAML:
func_vais credibledisasm_codeis non-empty and includes any available commentsdisasm_codeincludes discontinuous function chunks when IDA associates them with the same functionprocedureis present; it may be an empty string if Hex-Rays is unavailable
Attach the reference to a preprocessor script with prompt:
LLM_DECOMPILE = [
(
"AlpcAttributes",
"_ALPC_PORT->PortAttributes",
"prompt/call_llm_decompile.md",
"references/ntoskrnl/AlpcpDeletePort.{arch}.yaml",
),
]The tuple fields are (artifact_symbol_name, llm_query_name, prompt_path, reference_yaml_path). artifact_symbol_name selects the YAML artifact to generate, while llm_query_name is the exact text inserted into the LLM prompt. Then pass it into preprocess_common_skill(..., llm_decompile_specs=LLM_DECOMPILE). The LLM response parser currently supports found_call, found_gv, and found_struct_offset; direct function and global-variable addresses are resolved from the returned instruction address through IDA MCP.
update_symbols.py is now a YAML-to-XML exporter.
uv run update_symbols.py [-xml="kphdyn.xml"] [-symboldir="path/to/symbols"] [-configyaml="config.yaml"] -syncfileIf a symbol YAML is missing or unresolved, update_symbols.py exports:
0xffffforuint160xffffffffforuint32
HTTP server that handles file uploads, validates PE files and digital signatures, and stores files in the symbol directory structure.
Note: On Linux systems (Ubuntu/Debian/CentOS), you must install OpenSSL development libraries before running this server. See Requirements section above.
The server will:
- Accept POST requests to
/uploadendpoint - Validate uploaded files (must be PE files)
- Verify FileDescription must be "NT Kernel & System"
- Verify Authenticode signature (Signer must be "Microsoft Windows", Issuer must be "Microsoft Windows Production PCA 2011")
- Extract OriginalFilename and FileVersion from FileResource
- Determine architecture (x86/amd64/arm64) from PE header
- Store files to:
{symboldir}/{arch}/{FileName}.{FileVersion}/{FileSHA256}/{FileName} - Write the HTTP POST upload code yourself (or ask LLM agent).
- Check nginx / CDN for https support
Example:
- If
-symboldir="C:/Symbols",arch=amd64,FileName=ntoskrnl.exe,FileVersion=10.0.22621.741 - File will be stored at:
C:/Symbols/amd64/ntoskrnl.exe.10.0.22621.741/8025c442b39a5e8f0ac64045350f0f1128e24f313fa1e32784f9854334188df3/ntoskrnl.exe
uv run upload_server.py [-symboldir="path/to/symbols"] [-port=8000]export KPHTOOLS_SYMBOLDIR="C:/Symbols"
export KPHTOOLS_SERVER_PORT=8000set KPHTOOLS_SYMBOLDIR=C:/Symbols
set KPHTOOLS_SERVER_PORT=8000curl "http://localhost:8000/exists?filename=ntoskrnl.exe&arch=amd64&fileversion=10.0.26100.7462&sha256=710cf711b95c30f4fe78ac15026e2aa8c0bc96c2f72b15a09903818219e6c85a"
Found:
{"success": true, "message": "File existence checked", "filename": "ntoskrnl.exe", "arch": "amd64", "fileversion": "10.0.26100.7462", "sha256": "710cf711b95c30f4fe78ac15026e2aa8c0bc96c2f72b15a09903818219e6c85a", "exists": true, "path": "amd64/ntoskrnl.exe.10.0.26100.7462/710cf711b95c30f4fe78ac15026e2aa8c0bc96c2f72b15a09903818219e6c85a/ntoskrnl.exe", "file_size": 12993992}
Not found:
{"success": true, "message": "File existence checked", "filename": "ntoskrnl.exe", "arch": "amd64", "fileversion": "10.0.26100.7462", "sha256": "710cf711b95c30f4fe78ac15026e2aa8c0bc96c2f72b15a09903818219e6c85a", "exists": false, "path": "amd64/ntoskrnl.exe.10.0.26100.7462/710cf711b95c30f4fe78ac15026e2aa8c0bc96c2f72b15a09903818219e6c85a/ntoskrnl.exe", "file_size": 12993992}
curl -X POST -H "Content-Type: application/octet-stream" --data-binary "@C:/Windows/System32/ntoskrnl.exe" http://localhost:8000/upload
Content-Type: application/octet-streamis expected- File size limit: 20MB
- If the target file already exists, it will not be overwritten
- Header "X-File-Compressed: gzip" supported. with this header given, client should gzip the ntoskrnl payload before uploading.
curl "http://localhost:8000/health"
curl "http://localhost:8000/"
{"status": "healthy"}
- First run may takes hours downloading PE and PDB files.
- A typical run takes ~20 mins
- Output file:
kphdyn.xml - All steps are running via Windows Command Prompt
@echo Download latest kphdyn.xml from upstream
powershell -Command "Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/winsiderss/systeminformer/refs/heads/master/kphlib/kphdyn.xml' -OutFile kphdyn.official.xml"
copy kphdyn.official.xml kphdyn.xml /y@echo Sync unmanaged ntoskrnl to kphdyn.xml
uv run update_symbols.py -xml="%WORKSPACE%\kphdyn.xml" -symboldir="%WORKSPACE%\symbols" -syncfile@echo Download ntoskrnl exe and pdb, this may takes hours for the first run
uv sync
uv run download_symbols.py -xml="%WORKSPACE%\kphdyn.xml" -symboldir="%WORKSPACE%\symbols" -fast@echo Analyze symbols and dump YAML artifacts
uv run dump_symbols.py -symboldir="%WORKSPACE%\symbols" -configyaml="%WORKSPACE%\config.yaml"@echo Update kphdyn.xml with offsets from YAML artifacts
uv run update_symbols.py -xml="%WORKSPACE%\kphdyn.xml" -symboldir="%WORKSPACE%\symbols" -configyaml="%WORKSPACE%\config.yaml"