{"id":44316653,"url":"https://github.com/vswarte/broadsword","last_synced_at":"2026-02-11T05:13:00.091Z","repository":{"id":75675452,"uuid":"601027232","full_name":"vswarte/broadsword","owner":"vswarte","description":"All the shit I didn't want to write twice","archived":false,"fork":false,"pushed_at":"2024-04-04T03:44:04.000Z","size":2222,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-05T01:27:19.584Z","etag":null,"topics":["game-hacking","memory-hacking"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vswarte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-02-13T07:59:24.000Z","updated_at":"2024-04-05T01:27:19.585Z","dependencies_parsed_at":"2024-02-04T18:27:33.320Z","dependency_job_id":"9ac43871-9018-4cd9-a2ee-a892c2158f64","html_url":"https://github.com/vswarte/broadsword","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vswarte/broadsword","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vswarte%2Fbroadsword","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vswarte%2Fbroadsword/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vswarte%2Fbroadsword/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vswarte%2Fbroadsword/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vswarte","download_url":"https://codeload.github.com/vswarte/broadsword/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vswarte%2Fbroadsword/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29327139,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T03:52:29.695Z","status":"ssl_error","status_checked_at":"2026-02-11T03:52:23.094Z","response_time":97,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["game-hacking","memory-hacking"],"created_at":"2026-02-11T05:12:59.473Z","updated_at":"2026-02-11T05:13:00.075Z","avatar_url":"https://github.com/vswarte.png","language":"Rust","readme":"# Broadsword\r\nA set of shitty memory hacking tools.\r\n\r\n**What does this do?**\r\nI wrote it to do some heavy lifting around common tasks like logging vftables and finding\r\nbyte signatures in process memory.\r\n\r\n\r\n**How do I use this?**\r\nYou want to include this in a DLL that is then injected into a process (like a game or Excel). Then you can\r\nutilize the function below to do whatever makes your edits to a process tick.\r\n\r\n## DLL bootstrapping\r\nSmall macro to generate the DllMain. It automatically guards against invokes from thread creation and such:\r\n```rust\r\nuse broadsword::dll;\r\n\r\n#[dll::entrypoint]\r\npub fn entry(module_base: usize) -\u003e bool {\r\n  // Usual DllMain DLL_PROCESS_ATTACH stuff\r\n}\r\n```\r\n\r\n## Scanner\r\n### Single-threaded scans\r\nExample:\r\n```rust\r\nuse broadsword::scanner::Pattern;\r\nuse broadsword::scanner::simple::scan;\r\n\r\nlet pattern = Pattern::from_pattern_str(\"B7 [?? CF D8 ??] 0A ?? 27\").unwrap();\r\n\r\n// Scannable is a \u0026'static [u8] in which the pattern will be matched\r\nlet result = scan(scannable, \u0026pattern).unwrap();\r\n```\r\n\r\n### Multi-threaded scans\r\nSplits up the search array into N chunks, where N is the amount of available parallelism. It runs a simple scanner\r\nper thread on the chunk assigned to the thread.\r\n\r\n#### Default (automatic thread count)\r\nExample:\r\n\r\n```rust\r\nuse broadsword::scanner::Pattern;\r\nuse broadsword::scanner::threaded::scan;\r\n\r\nlet pattern = Pattern::from_pattern_str(\"B7 [?? CF D8 ??] 0A ?? 27\").unwrap();\r\nlet result = scan(scannable, \u0026pattern, None);\r\n```\r\n\r\n#### Manual thread count\r\nExample:\r\n```rust\r\nuse broadsword::scanner::Pattern;\r\nuse broadsword::scanner::threaded::scan;\r\n\r\nlet pattern = Pattern::from_pattern_str(\"B7 [?? CF D8 ??] 0A ?? 27\").unwrap();\r\nlet result = scan(scannable, \u0026pattern, Some(4));\r\n```\r\n\r\n### Multiple matches\r\nYou can also use the scanners to match all occurrences of a pattern:\r\n\r\n```rust\r\nuse broadsword::scanner::Pattern;\r\nuse broadsword::scanner::simple::scan_all as simple_scan_all;\r\nuse broadsword::scanner::threaded::scan_all as threaded_scan_all;\r\n\r\nlet pattern = Pattern::from_pattern_str(\"B7 [?? CF D8 ??] 0A ?? 27\").unwrap();\r\nlet simple_result = simple_scan_all(scannable, \u0026pattern);\r\nlet threaded_result = threaded_scan_all(scannable, \u0026pattern, None);\r\n```\r\n\r\n### Captures\r\nBoth scanners also have the ability of capturing bytes from the occurrences by using the `[00 00 00 00]` notation where \r\nthe square brackets indicate what should be captured.\r\n\r\n```rust\r\nuse broadsword::scanner::Pattern;\r\nuse broadsword::scanner::threaded::scan;\r\n\r\nlet pattern = Pattern::from_pattern_str(\"B7 [?? CF D8 ??] 0A ?? 27\").unwrap();\r\nlet result = scan(scannable, \u0026pattern, Some(4));\r\n\r\nassert_eq!(result.captures[0].location, 867777);\r\nassert_eq!(result.captures[0].bytes, vec![0xc6, 0xcf, 0xd8, 0x11]);\r\n```\r\n\r\n## Windows Modules\r\n\r\n### Finding a module\r\n`get_module_handle` gives us the base for a module based on the module name.\r\n```rust\r\nuse broadsword::runtime::get_module_handle;\r\n\r\nlet game_base: usize = get_module_handle(\"eldenring.exe\");\r\n```\r\n\r\n### Finding a symbol in a module\r\n`get_module_symbol` finds a function by examining the IAT.\r\n```rust\r\nuse broadsword::runtime::get_module_symbol;\r\n\r\nlet create_file_w_ptr: usize = get_module_symbol(\"kernel32\", \"CreateFileW\");\r\n```\r\n\r\n### Finding the module a pointer belongs to\r\n`get_module_symbol` finds a function by examining the IAT.\r\n```rust\r\nuse broadsword::runtime::Module;\r\nuse broadsword::runtime::get_module_pointer_belongs_to;\r\n\r\nlet some_module: Module = get_module_pointer_belongs_to(0x123456).unwrap();\r\nlet module_name: String = some_module.name;\r\nlet module_memory_range: Range\u003cusize\u003e = some_module.memory_range;\r\n```\r\n\r\n### Finding the range of a section within a module\r\n`get_module_symbol` finds a function by examining the section table.\r\n```rust\r\nuse broadsword::runtime::Module;\r\nuse broadsword::runtime::get_module_section_range;\r\n\r\nlet range: Range\u003cusize\u003e = get_module_section_range(\"eldenring.exe\", \".text\").unwrap();\r\n```\r\n\r\n## RTTI\r\n\r\n### Instance class names\r\nWe use `get_rtti_instance_classname` to retrieve the RTTI classname from a class instance.\r\n```rust\r\nuse broadsword::runtime::get_rtti_instance_classname;\r\n\r\nlet ptr: usize = 0x123456;\r\nlet class_name: Option\u003cString\u003e = get_rtti_instance_classname(ptr);\r\n```\r\n\r\n### Vftable class names\r\n`get_rtti_classname` will give use the name too, but it expects the vftable pointer directly\r\ninstead of a pointer to a class instance.\r\n```rust\r\nuse broadsword::runtime::get_rtti_classname;\r\n\r\nlet ptr: usize = 0x123456;\r\nlet class_name: Option\u003cString\u003e = get_rtti_classname(ptr);\r\n```\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvswarte%2Fbroadsword","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvswarte%2Fbroadsword","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvswarte%2Fbroadsword/lists"}