Install
$ agentstack add skill-hlnd2t-cs2-vibesignatures-generate-signature-for-globalvar ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Generate Signature for Global Variable
Generate a unique hex byte signature that locates an instruction accessing a global variable using fully programmatic wildcard detection and validation — no manual byte analysis required.
Core Concept
Since global variable addresses change between binary updates, we don't signature the GV itself. Instead, we:
- Find an instruction that references the global variable (mov/lea/cmp/etc.)
- Generate a signature to locate that instruction
- At runtime, parse the instruction to resolve the actual GV address
RIP-Relative Addressing (x86-64)
In x86-64, most global variable accesses use RIP-relative addressing:
GV_Address = Instruction_Address + Instruction_Length + RIP_Offset
Where:
Instruction_Address= address found by pattern scanInstruction_Length= total bytes of the instruction (opcode + ModR/M + offset)RIP_Offset= signed 32-bit displacement (last 4 bytes of instruction)
Prerequisites
- Global variable address.
qword_XXXXXXfor example. - IDA Pro MCP connection
Method
1. Generate and Validate Signature (Single Step)
Use a single py_eval call that:
- Discovers candidate instructions accessing the GV via
DataRefsTo - Verifies each candidate resolves to the target GV via RIP-relative displacement
- Collects instruction stream with auto-wildcarding for each candidate
- Tracks instruction boundaries so prefixes always cover complete instructions
- Progressively tests at each instruction boundary via binary search
- Outputs the shortest unique signature with full metadata
Note: If you already know the GV-accessing instruction address, set target_inst = . If you know the containing function, set target_func = .
mcp__ida-pro-mcp__py_eval code="""
import idaapi, ida_bytes, idautils, ida_ua, ida_segment, json
def main():
target_gv =
target_inst = None # Set to instruction address if known, e.g. 0x1804F3DF3
target_func = None # Set to function address to restrict search, e.g. 0x1804F3DA0
min_sig_bytes = 8
max_sig_bytes = 96
max_instructions = 64
max_candidates = 32
# --- Binary search wrapper (IDA 9.0+ find_bytes -> older bin_search fallback) ---
def raw_bin_search(ea, max_ea, data, mask, flags=0):
if hasattr(ida_bytes, 'find_bytes'):
return ida_bytes.find_bytes(data, ea, range_end=max_ea, mask=mask, flags=flags)
return ida_bytes.bin_search(ea, max_ea, data, mask, len(data), flags)
# --- Search bounds ---
seg = ida_segment.get_segm_by_name(".text")
if seg:
search_start, search_end = seg.start_ea, seg.end_ea
else:
search_start, search_end = idaapi.cvar.inf.min_ea, idaapi.cvar.inf.max_ea
def resolve_disp_off(insn_ea, insn, raw):
cand_offsets = set()
for op in insn.ops:
if int(op.type) == int(idaapi.o_void):
continue
offb = int(getattr(op, 'offb', 0))
offo = int(getattr(op, 'offo', 0))
if offb > 0 and offb + 4 0 and offo + 4 0 and offb 0 and offo = 2 and (raw[1] & 0xF0) == 0x80:
for i in range(2, insn.size):
wild.add(i)
elif 0x70 = max_candidates:
break
fl = ida_bytes.get_full_flags(ref)
if not ida_bytes.is_code(fl):
continue
try_candidate(ref)
if best is not None:
break
if best:
best["gv_va"] = hex(target_gv)
best["gv_rva"] = hex(target_gv - idaapi.get_imagebase())
best["gv_inst_offset"] = 0
best["status"] = "success"
print(json.dumps(best))
else:
print(json.dumps({
"gv_va": hex(target_gv),
"candidates_tried": candidates_tried,
"error": "no unique gv-access signature found",
"status": "failed"
}))
main()
"""
Result handling:
status == "success"→ Usegv_sigand metadata directlystatus == "failed"→ See Step 2
2. Iterate if Needed
If Step 1 returns status: "failed":
- Increase
max_sig_bytes(e.g., to 192) and re-run Step 1 - Specify a different
target_functo find more candidates - Re-run until unique
3. Continue with Unfinished Tasks
If we are called by a task from a task list / parent SKILL, restore and continue with the unfinished tasks.
Output Format
Provide the following information for runtime GV resolution:
Required Output Fields
- gv_sig: Space-separated hex bytes with
??for wildcards - gvsigva: The virtual address that the signature matches
- gvinstoffset: Always
0(signature starts at the GV-accessing instruction) - gvinstlength: Total length of the GV-accessing instruction (from output metadata)
- gvinstdisp: Position of the 4-byte RIP-relative offset within the instruction (from output metadata)
Example Output
gv_sig: "48 8B 1D ?? ?? ?? ?? 48 85 DB 0F 84 ?? ?? ?? ?? BD FF FF 00 00"
gv_sig_va: 0x1804f3df3 # The virtual address that the signature matches
gv_inst_offset: 0 # GV instruction starts at signature start
gv_inst_length: 7 # 48 8B 1D XX XX XX XX = 7 bytes
gv_inst_disp: 3 # Displacement offset start at position 3 (after 48 8B 1D)
Runtime Resolution Formula
At runtime, after pattern scan finds the signature at address scan_result:
// C++ example
uint8_t* inst_addr = scan_result + inst_offset;
int32_t rip_offset = *(int32_t*)(inst_addr + inst_disp);
void* gv_address = inst_addr + inst_length + rip_offset;
# Python example
import struct
inst_addr = scan_result + inst_offset
rip_offset = struct.unpack('<i', memory[inst_addr + inst_disp : inst_addr + inst_disp + 4])[0]
gv_address = inst_addr + inst_length + rip_offset
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: HLND2T
- Source: HLND2T/CS2_VibeSignatures
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.