{"id":13422821,"url":"https://github.com/patois/HexraysToolbox","last_synced_at":"2025-03-15T12:30:52.770Z","repository":{"id":41103590,"uuid":"272186275","full_name":"patois/HexraysToolbox","owner":"patois","description":"Hexrays Toolbox - Find code patterns within the Hexrays ctree","archived":false,"fork":false,"pushed_at":"2023-06-20T18:40:34.000Z","size":253,"stargazers_count":435,"open_issues_count":0,"forks_count":42,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-10-28T00:01:26.816Z","etag":null,"topics":["ast","bug-finding","code-comparison","code-pattern-matching","code-similarity","ctree","decompiler","hex-rays","hexrays","hexrays-decompiler","hexrays-toolbox","ida-pro","idapython","idapython-script","loops","pattern-matching","plagiarism-detection","reverse-engineering","variant-analysis","vulnerability-scanner"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patois.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-06-14T11:14:38.000Z","updated_at":"2024-10-13T12:57:54.000Z","dependencies_parsed_at":"2022-07-12T18:17:23.457Z","dependency_job_id":"4b4a10d5-40e3-4fec-82bc-9c57197f63f2","html_url":"https://github.com/patois/HexraysToolbox","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patois%2FHexraysToolbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patois%2FHexraysToolbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patois%2FHexraysToolbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patois%2FHexraysToolbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patois","download_url":"https://codeload.github.com/patois/HexraysToolbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243731050,"owners_count":20338763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","bug-finding","code-comparison","code-pattern-matching","code-similarity","ctree","decompiler","hex-rays","hexrays","hexrays-decompiler","hexrays-toolbox","ida-pro","idapython","idapython-script","loops","pattern-matching","plagiarism-detection","reverse-engineering","variant-analysis","vulnerability-scanner"],"created_at":"2024-07-30T23:00:58.438Z","updated_at":"2025-03-15T12:30:52.367Z","avatar_url":"https://github.com/patois.png","language":"Python","readme":"# HexRays Toolbox\r\n\r\nHexRays Toolbox (hxtb) is a powerful set of IDAPython scripts that can be used to find and locate code patterns in binaries, independent from their underlying processor architecture.\r\n\r\n## Use Cases\r\n\r\n- scan binary files for vulnerabilities and variants\r\n- locate code patterns from previously reverse engineered executables in newly decompiled code\r\n- malware variant analysis\r\n- find code similarities across several binaries (i.e. for proving \"code theft\", license violations, ...)\r\n- find code patterns from binaries compiled for architecture A in binaries compiled for architecture B\r\n- probably a lot more...\r\n\r\nThe query illustrated by the animation below is an example for how a vulnerability that affected WhatsApp for Android (CVE-2019-3568, libwhatsapp.so) can be located using HexRays Toolbox. This is done by formulating a desired code pattern that is to be located using an IDAPython lambda function. Find the example script ![here](./examples/).\r\n\r\n![toolbox animated gif](./rsrc/toolbox.gif?raw=true)\r\n\r\n## Requirements\r\n\r\nA valid IDA license and a valid HexRays decompiler license per target architecture is required. \r\n\r\n## Usage\r\n\r\nThere are several ways of using Hexrays Toolbox, each with a varying degree of flexibility.\r\n\r\n- run queries on behalf of [hxtb_shell](#hxtb-shell), an interactive GUI\r\n- custom IDAPython [scripting](#Scripting)\r\n- ```interactive.py```, a script that adds [convenience functions](./interactive/interactive.py) to be used with the IDA command line interface\r\n- ```automation.py```, a script that processes and runs hxtb queries on a given set of files in [batch mode](./automation/batch.py)\r\n\r\n### hxtb-shell\r\nExecuting the included ```hxtb_shell.py``` script from within IDA opens a GUI window that can be used to develop, load and run hxtb queries. The screenshot below shows what a query loaded with hxtb-shell may look like.\r\n\r\n![hxtb shell](./rsrc/hxtbshell.png?raw=true)\r\n\r\nhxtb-shell also accepts Python expressions that are created by the [HRDevHelper](https://github.com/patois/HRDevHelper) plugin's context viewer. They can be copied from it and directly pasted into the hxtb-shell GUI.\r\n\r\n![HRDevHelper context viewer](https://github.com/patois/HRDevHelper/blob/master/rsrc/hrdevctx.png?raw=true)\r\n\r\n___\r\n\r\nFurther example queries that can be loaded with hxtb-shell can be found in the ```hxtbshell_queries``` sub-folder included with HexRays Toolbox.\r\n\r\n### Scripting\r\n\r\nLoading ```hxtb.py``` with IDA (Alt-F7) makes functions such as ```find_expr()``` and ```find_item()``` available to both the IDAPython CLI and the script interpreter (Shift-F2). Among others, these functions can be used to run queries on the currently loaded IDA database. Please check out some of the examples shown [below](#Examples).\r\n\r\n```\r\n    find_item(ea, q)\r\n    find_expr(ea, q)\r\n\r\n    Positional arguments:\r\n        ea:         address of a valid function within\r\n                    the current database\r\n        q:          lambda function\r\n                    custom lambda function with the following arguments:\r\n                    1. cfunc: cfunc_t\r\n                    2. i/e:   cinsn_t/cexpr_t\r\n    Returns:\r\n        list of query_result_t objects\r\n\r\n    Example:\r\n        find_expr(here(), lambda cf, e: e.op is cot_call)\r\n    \r\n        -\u003e finds and returns all function calls within a current function.\r\n        The returned data is a list of query_result_t objects (see hxtb.py).\r\n\r\n        The returned list can be passed to an instance of the ic_t class,\r\n        which causes the data to be displayed by a chooser as follows:\r\n\r\n        from idaapi import *\r\n        import hxtb\r\n        hxtb.ic_t(find_expr(here(), lambda cf,e:e.op is cot_call))\r\n\r\n\r\n    Please find the cfunc_t, citem_t, cinsn_t and cexpr_t structures\r\n    within hexrays.hpp for further help and details.\r\n```\r\n\r\n## Examples\r\n\r\n### List expressions that compare anything to zero (\"x == 0\")\r\n```\r\n         cot_eq\r\n         /   \\\r\n      x /     \\ y\r\n(anything)  cot_num --- n.numval() == 0\r\n```\r\n``` python\r\nfrom idaapi import *\r\nfrom hxtb import find_expr\r\nquery = lambda cfunc, e: e.op is cot_eq and e.y.op is cot_num and e.y.numval() == 0\r\nr = find_expr(here(), query)\r\nfor e in r:\r\n    print(e)\r\n```\r\n### List (direct) function calls\r\n```\r\n        cot_call\r\n         / \r\n      x /\r\n cot_obj\r\n```\r\n``` python\r\nfrom idaapi import *\r\nfrom hxtb import find_expr\r\nquery = lambda cfunc, e: e.op is cot_call and e.x.op is cot_obj\r\nr = find_expr(here(), query)\r\nfor e in r:\r\n    print(e)\r\n```\r\n![list of calls ](./rsrc/calls.png?raw=true)\r\n### List memcpy calls where \"dst\" argument is on stack\r\n```\r\n        cot_call --- arg1 is cot_var\r\n         /           arg1 is on stack\r\n      x /\r\n cot_obj --- name(obj_ea) == 'memcpy'\r\n```\r\n``` python\r\nfrom idaapi import *\r\nfrom hxtb import find_expr\r\nr = []\r\nquery = lambda cfunc, e: (e.op is cot_call and\r\n           e.x.op is cot_obj and\r\n           get_name(e.x.obj_ea) == 'memcpy' and\r\n           len(e.a) == 3 and\r\n           e.a[0].op is cot_var and\r\n           cfunc.lvars[e.a[0].v.idx].is_stk_var())\r\nfor ea in Functions():\r\n    r += find_expr(ea, query)\r\nfor e in r:\r\n    print(e)\r\n```\r\n### List calls to sprintf(str, fmt, ...) where fmt contains \"%s\"\r\n```\r\n        cot_call --- arg2 ('fmt') contains '%s'\r\n         /\r\n      x /\r\n cot_obj --- name(obj_ea) == 'sprintf'\r\n```\r\n``` python\r\nfrom idaapi import *\r\nfrom hxtb import find_expr\r\nr = []\r\nquery = lambda cfunc, e: (e.op is cot_call and\r\n    e.x.op is cot_obj and\r\n    get_name(e.x.obj_ea) == 'sprintf' and\r\n    len(e.a) \u003e= 2 and\r\n    e.a[1].op is cot_obj and\r\n    is_strlit(get_flags(get_item_head(e.a[1].obj_ea))) and\r\n    b'%s' in get_strlit_contents(e.a[1].obj_ea, -1, 0, STRCONV_ESCAPE))\r\nfor ea in Functions():\r\n    r += find_expr(ea, query)\r\nfor e in r:\r\n    print(e)\r\n```\r\n### Show all instructions using signed operators in a list view\r\n``` python\r\nfrom idaapi import *\r\nfrom hxtb import ic_t\r\nquery = lambda cfunc, e: (e.op in\r\n            [cot_asgsshr, cot_asgsdiv,\r\n            cot_asgsmod, cot_sge,\r\n            cot_sle, cot_sgt,\r\n            cot_slt, cot_sshr,\r\n            cot_sdiv, cot_smod])\r\nic_t(query)\r\n```\r\n![list of signed operators](./rsrc/signed_ops.png?raw=true)\r\n### Show all \"if\" statements in a list view\r\n``` python\r\nfrom idaapi import *\r\nfrom hxtb import ic_t\r\nic_t(lambda cf, i: i.op is cit_if)\r\n```\r\n![list of if statements](./rsrc/if_stmt.png?raw=true)\r\n### Find all loop statements within current db, display result in a list view\r\n``` python\r\nfrom idaapi import *\r\nfrom hxtb import ic_t, query_db\r\nic_t(query_db(lambda cf,i: is_loop(i.op)))\r\n```\r\n![list of loops](./rsrc/loops.png?raw=true)\r\n### Show potential memory copy operations in a list view\r\n``` python\r\nfrom hxtb import ic_t, query_db, find_child_expr\r\nfrom ida_hexrays import *\r\n\r\n\r\nfind_copy_query = lambda cfunc, i: (i.op is cot_asg and\r\n                                i.x.op is cot_ptr and\r\n                                i.y.op is cot_ptr)\r\n\r\nfind_loop_query = lambda cfunc, i: (is_loop(i.op) and\r\n                            find_child_expr(cfunc, i, find_copy_query))\r\n\r\n\r\nic_t(query_db(find_loop_query))\r\n```\r\n![list of copy loops](./rsrc/copy_loop.png?raw=true)\r\n","funding_links":[],"categories":["IDA Plugins","Python","Python (1887)"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatois%2FHexraysToolbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatois%2FHexraysToolbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatois%2FHexraysToolbox/lists"}