{"id":22211994,"url":"https://github.com/mcountryman/min-sized-rust-windows","last_synced_at":"2025-04-13T00:42:32.098Z","repository":{"id":44759752,"uuid":"315756836","full_name":"mcountryman/min-sized-rust-windows","owner":"mcountryman","description":":crab: 464b rust binary on windows","archived":false,"fork":false,"pushed_at":"2024-10-28T13:14:34.000Z","size":91,"stargazers_count":230,"open_issues_count":3,"forks_count":8,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-13T00:42:28.290Z","etag":null,"topics":["rust","windows"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcountryman.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}},"created_at":"2020-11-24T21:29:33.000Z","updated_at":"2025-04-03T20:25:39.000Z","dependencies_parsed_at":"2024-12-03T02:47:21.914Z","dependency_job_id":null,"html_url":"https://github.com/mcountryman/min-sized-rust-windows","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/mcountryman%2Fmin-sized-rust-windows","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcountryman%2Fmin-sized-rust-windows/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcountryman%2Fmin-sized-rust-windows/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcountryman%2Fmin-sized-rust-windows/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcountryman","download_url":"https://codeload.github.com/mcountryman/min-sized-rust-windows/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650417,"owners_count":21139672,"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":["rust","windows"],"created_at":"2024-12-02T20:46:23.605Z","updated_at":"2025-04-13T00:42:32.066Z","avatar_url":"https://github.com/mcountryman.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Minimum Binary Size Windows\n[![CI](https://github.com/mcountryman/min-sized-rust-windows/actions/workflows/ci.yml/badge.svg)](https://github.com/mcountryman/min-sized-rust-windows/actions/workflows/ci.yml)\n\nThe smallest hello world I could get on win10 x64 in rust. This isn't something meant to \nbe used in production, more of a challenge.  I'm in no ways an expert and \n[I have seen windows binaries get smaller on windows](https://github.com/pts/pts-tinype). [2]\nIf you can go smaller let me know how you did it :grin:\n\n### Results\n`464b` :sunglasses:\n\n```powershell\n❯ cargo +nightly install anonlink\n❯ anonlink\n❯ cargo +nightly run --release\nHello World!\n\n❯ cargo +nightly build --release \u0026\u0026 (Get-Item \".\\target\\release\\min-sized-rust-windows.exe\").Length\n   Compiling min-sized-rust-windows v0.1.0 (**\\min-sized-rust-windows)\n    Finished release [optimized] target(s) in 1.33s\n464\n```\n\n### Strategies\nI'm excluding basic strategies here such as enabling lto and setting `opt-level = 'z'`. [0]\n\n* [`no_std`](https://github.com/johnthagen/min-sized-rust#removing-libstd-with-no_std)\n* [`no_main`](https://github.com/johnthagen/min-sized-rust#remove-corefmt-with-no_main-and-careful-usage-of-libstd)\n* Merge `.rdata` and `.pdata` sections into `.text` section linker flag. [1]\n  * Using the LINK.exe [`/MERGE`](https://docs.microsoft.com/en-us/cpp/build/reference/merge-combine-sections?view=msvc-160)     \n    flag found at the bottom of `main.rs`.\n  * Section definitions add more junk to the final output, and I _believe_ they have a \n    min-size.  For this example we really don't care about readonly data (`.rdata`) or \n    exception handlers (`.pdata`) so we \"merge\" these empty sections into the `.text` \n    sections.\n* No imports.\n  * To avoid having an extra `.idata` section (more bytes and cannot be merged into \n    `.text` section using `LINK.exe`) we do the following.\n  * Resolve stdout handle from `PEB`'s process parameters (thanks ChrisSD). [3][4]\n  * Invoke `NtWriteFile`/`ZwWriteFile` using syscall `0x80`. [5][6]\n    1. This is undocumented behaviour in windows, syscalls change over time. [5]\n    2. I can't guarantee this will work on your edition of windows.. it's tested on\n       my local machine (W10) and on GH actions (windows-2022 and windows-2019) server\n       editions.\n* Custom `LINK.exe` stub.\n  * A custom built stub created to remove `Rich PE` header. More information can be found [here](https://bytepointer.com/articles/the_microsoft_rich_header.htm).\n  * Credits to @Frago9876543210 for finding, and implementing this.\n* Drop debug info in pe header.\n  * Add `/EMITPOGOPHASEINFO /DEBUG:NONE` flags.\n  * Credits to @Frago9876543210 for finding, and implementing this.\n\n    \n### Future\n* Using strategies shown in [[2]](https://github.com/pts/pts-tinype) we _could_ post process\n  the exe and merge headers to get closer to the 600-500b mark although we start straying\n  away from the goal of this project.\n* Provided the call signature of `ZwWriteFile` I could use `build.rs` to make a script to\n  dynamically resolve the syscall number from `ntdll` using something like [iced-x86](https://crates.io/crates/iced-x86).\n* Go pure assembly (drop type definitions for PEB).\n      \n### References\n0. https://github.com/johnthagen/min-sized-rust\n1. www.catch22.net/tuts/win32/reducing-executable-size#use-the-right-linker-settings\n2. https://github.com/pts/pts-tinype\n3. https://news.ycombinator.com/item?id=25266892 (Thank you anonunivgrad \u0026 ChrisSD!)\n4. https://processhacker.sourceforge.io/doc/struct___r_t_l___u_s_e_r___p_r_o_c_e_s_s___p_a_r_a_m_e_t_e_r_s.html\n5. https://j00ru.vexillium.org/syscalls/nt/64/\n6. https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntwritefile\n\n### Credits\n* @Frago9876543210 - Brought binary size from `760b` -\u003e `600b` :grin:\n* @Frago9876543210 - Brought binary size from `600b` -\u003e `560b` :grin:\n* @ironhaven - Brought binary size from `560b` -\u003e `536b` 😁\n* @StackOverflowExcept1on - Brought binary size from `536b` -\u003e `464b` 😁\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcountryman%2Fmin-sized-rust-windows","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcountryman%2Fmin-sized-rust-windows","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcountryman%2Fmin-sized-rust-windows/lists"}