Rizin
unix-like reverse engineering framework and cli tools
rzshell_which.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # SPDX-FileCopyrightText: 2021 ret2libc <sirmy15@gmail.com>
3 # SPDX-License-Identifier: LGPL-3.0-only
4 
5 import argparse
6 import glob
7 import os
8 import sys
9 import subprocess
10 
11 import yaml
12 from cmd_descs_util import CD_TYPE_OLDINPUT, compute_cname, get_handler_cname
13 
14 
15 def get_yaml_files(basedir):
16  for file in glob.glob(os.path.join(basedir, "*.yaml")):
17  yield file
18 
19 
20 def find_entry(commands, rzcommand):
21  for c in commands:
22  if "subcommands" in c and isinstance(c["subcommands"], list):
23  e = find_entry(c["subcommands"], rzcommand)
24  if e is not None:
25  return e
26  if "subcommands" in c and isinstance(c["subcommands"], str):
27  # This cd is only a group pointing to another file,
28  # the handler cname will be fetched from there.
29  return None
30 
31  if c["name"] == rzcommand:
32  return c
33 
34  return None
35 
36 
38  name = e["cname"]
39  if "handler" in e and e["handler"]:
40  name = e["handler"]
41 
42  if "type" in e and e["type"] == CD_TYPE_OLDINPUT:
43  return f"rz_{name}"
44 
45  return f"rz_{name}_handler"
46 
47 
48 def find_c_name_handler(basedir, rzcommand):
49  for f in get_yaml_files(basedir):
50  with open(f, "r", encoding="utf8") as of:
51  y = yaml.safe_load(of)
52  e = find_entry(y["commands"], rzcommand)
53  if e is not None:
54  cname = e.get("cname", compute_cname(e["name"]))
55  return get_handler_cname(
56  e.get("type", None), e.get("handler", None), cname
57  )
58 
59  return None
60 
61 
63  return " ".join(
64  [arg if '"' not in arg and "*" not in arg else f"'{arg}'" for arg in args]
65  )
66 
67 
68 def main():
69  parser = argparse.ArgumentParser(
70  description="Find the C handler of a rizin command"
71  )
72  parser.add_argument(
73  "--cmddescs-dir",
74  default=os.path.join("librz", "core", "cmd_descs"),
75  type=str,
76  help="Path to the cmd_descs directory containing the *.yaml files",
77  )
78  parser.add_argument(
79  "-g",
80  "--grep",
81  action="store_true",
82  help="Run the grep command directly instead of just showing it",
83  )
84  parser.add_argument("rzcommand", type=str, help="Name of the rizin command")
85 
86  args = parser.parse_args()
87  c_name = find_c_name_handler(args.cmddescs_dir, args.rzcommand)
88  CRED = "\033[91m"
89  CEND = "\033[0m"
90  if c_name is None:
91  print(
92  f"Command {args.rzcommand} does not exist or it is not converted to rzshell yet."
93  )
94  grep_cmd = ["git", "grep", "-n", f'"{args.rzcommand}"', "librz/core/cmd"]
95  print(
96  f"Some old commands may be found like this: {CRED}{format_shell_command(grep_cmd)}{CEND}"
97  )
98  else:
99  print(f"Rizin Command: {CRED}{args.rzcommand}{CEND}")
100  print(f"C handler: {CRED}{c_name}{CEND}")
101  grep_cmd = ["git", "grep", "-nWG", f"^[^[:blank:]].*{c_name}(", "*.c"]
102  print(f"Git command to get it: {CRED}{format_shell_command(grep_cmd)}{CEND}")
103 
104  if args.grep:
105  print("--------")
106  sys.exit(subprocess.run(grep_cmd, check=False).returncode)
107 
108 
109 if __name__ == "__main__":
110  main()
def compute_cname(name)
def get_handler_cname(ty, handler, cname)
def get_yaml_files(basedir)
def format_shell_command(args)
def find_entry(commands, rzcommand)
def get_c_handler_name_from_entry(e)
def find_c_name_handler(basedir, rzcommand)