{"id":18745662,"url":"https://github.com/washi1337/spyglass","last_synced_at":"2025-10-12T09:08:38.143Z","repository":{"id":66989336,"uuid":"195642035","full_name":"Washi1337/SpyGlass","owner":"Washi1337","description":"Remote process hooking library for .NET","archived":false,"fork":false,"pushed_at":"2019-08-01T20:09:02.000Z","size":579,"stargazers_count":75,"open_issues_count":0,"forks_count":16,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-12T21:51:47.388Z","etag":null,"topics":["dotnet","hook-framework","remote"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Washi1337.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-07-07T11:15:32.000Z","updated_at":"2025-02-18T08:55:07.000Z","dependencies_parsed_at":"2023-03-15T15:30:16.707Z","dependency_job_id":null,"html_url":"https://github.com/Washi1337/SpyGlass","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Washi1337/SpyGlass","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washi1337%2FSpyGlass","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washi1337%2FSpyGlass/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washi1337%2FSpyGlass/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washi1337%2FSpyGlass/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Washi1337","download_url":"https://codeload.github.com/Washi1337/SpyGlass/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Washi1337%2FSpyGlass/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279010959,"owners_count":26084836,"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","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["dotnet","hook-framework","remote"],"created_at":"2024-11-07T16:19:06.390Z","updated_at":"2025-10-12T09:08:38.136Z","avatar_url":"https://github.com/Washi1337.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"SpyGlass\n========\n\nSpyGlass is a hooking library that allows for hooking inside remote processes. The API is an event driven framework, allowing .NET developers easily inspect and alter the behaviour of the target process without having to write lots of code.\n\nFeatures\n========\n- Hook anywhere in any process, even if the process is running on a different (virtual) machine.\n    - Useful if the target application is malware and needs to be isolated from anything else.\n- View and edit register values in the callback.\n- View and edit memory in the callback.\n- Various convenience methods, such as:\n    - Getting the address of a procedure in a remote process.\n\nShowcase\n========\n\nInspecting the arguments of a MessageBoxA call\n----------------------------------------------\n\n![Left: Master, Right: Slave](doc/img/screenshot2.png)\n\nThe image above showcases a simple hooking application (on the right) that monitors a remote process running inside a virtual machine (on the left) that calls `MessageBoxA` at some point. We can use SpyGlass to hook this function remotely, and inspect the arguments. \n\n- Check out the [source code](src/Examples/MessageBox).\n- To reproduce, run the following command in the VM:\n    ```\n    SpyGlass.Bootstrapper.x86.exe SpyGlass.Injection.x86.dll MessageBoxTest.exe\n    ```\n    And on the master machine, run:\n    ```\n    MessageBoxHook.exe \u003cip-address\u003e 12345\n    ```\n\nChanging stack values on the fly\n--------------------------------\n\n![Left: Master, Right: Slave](doc/img/screenshot1.png)\n\nIn this case, the function `DummyMethod` in the slave process takes three arguments, and simply adds them together. This function is originally called with three arguments: `0x1337`, `0x1338` and `0x1339`. However, the master process hooked this function, and modified the first parameter from `0x1337` to `0x1234` in the callback.\n\n- Check out the [source code](src/Examples/DummyExample).\n- To reproduce, run the following command in the VM:\n    ```\n    SpyGlass.Bootstrapper.x86.exe SpyGlass.Injection.x86.dll SpyGlass.DummyTarget.exe\n    ```\n    And on the master machine, run:\n    ```\n    SpyGlass.Sample.x86.exe \u003cip-address\u003e 12345\n    ```\n\nFAQ\n===\n\nHow do I write my own hooks?\n----------------------------\nTo write your own master process and/or bootstrapper, see the [quick starters guide](doc/QuickStart.md).\n\nHow does it work?\n-----------------\nHere's a quick summary of how the library works internally:\n\n**How does the remoting part work?**\n1. Target (slave) process is injected with a dynamically loaded library (dll). \n2. Library spawns a new thread.\n3. Thread opens a TCP connection with the master process and starts listening for commands.\n\n**How does the hooking process work?**\n1. At the target address, we disassemble the instructions up to the point we have read at least 5 bytes of assembly code.\n2. Construct a trampoline that ...\n    - ... makes sure all registers (including the stack and program counters) are put in a safe spot.\n    - ... calls the callback in a **__stdcall** fashion.\n    - ... executes the disassembled instructions in step 1.\n    - ... jumps back to the instruction after the place of the hook.\n3. Insert a `call` to the trampoline at the position of the hook.\n4. Report to the master process on events.\n\nFor details go [here](doc/HowItWorks.md).\n\nOh no I broke the library! What do I do now?\n-------------------------------------------\nFirst thing you have to remember is that I don't write bugs, only interesting new features. Make sure you are not just misusing a feature. With great power comes great responsibility!\n\nIf you still believe you have found a bug, please go to the [issue tracker](https://github.com/Washi1337/SpyGlass/issues/).\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwashi1337%2Fspyglass","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwashi1337%2Fspyglass","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwashi1337%2Fspyglass/lists"}