{"id":16767923,"url":"https://github.com/jrudolph/bootpgm","last_synced_at":"2025-04-10T19:21:15.258Z","repository":{"id":26736150,"uuid":"30193770","full_name":"jrudolph/bootpgm","owner":"jrudolph","description":"Demonstration of a Windows Boot Program using Window's Native API","archived":false,"fork":false,"pushed_at":"2019-09-11T20:12:01.000Z","size":898,"stargazers_count":32,"open_issues_count":1,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-10T18:16:57.760Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","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/jrudolph.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}},"created_at":"2015-02-02T15:36:14.000Z","updated_at":"2025-01-23T13:41:57.000Z","dependencies_parsed_at":"2022-09-01T19:00:25.300Z","dependency_job_id":null,"html_url":"https://github.com/jrudolph/bootpgm","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/jrudolph%2Fbootpgm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrudolph%2Fbootpgm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrudolph%2Fbootpgm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrudolph%2Fbootpgm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jrudolph","download_url":"https://codeload.github.com/jrudolph/bootpgm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248281382,"owners_count":21077423,"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":[],"created_at":"2024-10-13T06:10:21.248Z","updated_at":"2025-04-10T19:21:15.229Z","avatar_url":"https://github.com/jrudolph.png","language":"C++","readme":"# Windows Boot Program And Native API Kit\n\n**Note: All of this information is from 2007 and may long be outdated**\n\nA Windows boot program is a piece of software which executes while Windows is booting. \nInformation about how to write such a program is very incomplete. For a university project \nI collected several pieces of information on this topic I'd like to share.\n\nAn example of a boot program is autocheck the tool which checks the hard disk for errors right at the start of Windows - remember this blue screen just before the logon box appears? \n\nTo write such a program you can only use the NT Native API. The native api consists of all the functions the kernel \"exports\" to user mode programs. Windows applications normally use the API of the Win32 subsystem (kernel32.dll, user32.dll, gdi32.dll...) which itself uses the native API to speak to the kernel. At the time a boot program is executing no subsystem is available so one has to fall back to the Native API.\n\n## How to build the sample boot program (worked in 2007...)\n * Clone the latest sources\n * Install the Windows DDK\n * Start the Windows DDK Command Line Environment\n * cd to the sources\n * use `build-interactive.bat` or simply `build -wg` to build the boot program\n\n## Screenshots\n![Screenshot 1](https://github.com/jrudolph/bootpgm/blob/master/doc/screenshot1.png)\n![Screenshot 2](https://github.com/jrudolph/bootpgm/blob/master/doc/screenshot2.png)\n![Screenshot 3](https://github.com/jrudolph/bootpgm/blob/master/doc/screenshot3.png)\n\n## Paper \u0026 Presentation\n * [Paper (German)](https://github.com/jrudolph/bootpgm/blob/master/doc/winnapi-paper.pdf?raw=true)\n * [Presentation (German)](https://github.com/jrudolph/bootpgm/blob/master/doc/winnapi.pdf?raw=true)\n\n## More Information \u0026 Links\n * Sysinternals' [Inside Native Applications](https://docs.microsoft.com/en-us/sysinternals/learn/inside-native-applications)\n * Gary Nebbett's \u003ca href=\"http://www.amazon.de/gp/product/1578701996/ref=as_li_tl?ie=UTF8\u0026camp=1638\u0026creative=19454\u0026creativeASIN=1578701996\u0026linkCode=as2\u0026tag=virtvoid-21\u0026linkId=RGN3TH74V47EXNWI\"\u003eWindows NT/2000 Native API Reference\u003c/a\u003e (affiliate link)\n * Sven Schreiber's \u003ca href=\"http://www.amazon.de/gp/product/0201721872/ref=as_li_tl?ie=UTF8\u0026camp=1638\u0026creative=19454\u0026creativeASIN=0201721872\u0026linkCode=as2\u0026tag=virtvoid-21\u0026linkId=DWDLWZLDJUHP2IAQ\"\u003eUndocumented Windows 2000 Secrets, w. CD-ROM: A Programmer's Cookbook\u003c/a\u003e (affiliate link) or the [PDF Version](https://users.du.se/~hjo/cs/common/books/Undocumented%20Windows%202000%20Secrets/sbs-w2k-preface.pdf)\n * NTInternals' [Undocumented NT Functions for Microsoft Windows NT/2000] (http://undocumented.ntinternals.net/)\n * Microsoft Windows Internals \u003ca href=\"http://www.amazon.de/gp/product/0735625301/ref=as_li_tl?ie=UTF8\u0026camp=1638\u0026creative=19454\u0026creativeASIN=0735625301\u0026linkCode=as2\u0026tag=virtvoid-21\u0026linkId=KM2PRWRZ23EEACPN\"\u003eWindows® Internals, Fifth Edition (PRO-Developer)\u003c/a\u003e (affiliate link)\n * A [thread](http://www.osronline.com/showThread.cfm?link=9504) on OSR's forum\n * [Syscall Table and comparison of different Windows versions](http://j00ru.vexillium.org/ntapi/)\n * Petter Nordahl's site about the [Offline Nt Password \u0026 Registry Editor](https://pogostick.net/~pnh/ntpasswd/) with some interesting information regarding the structure of the SAM\n * Bruce Ediger's comment about [Windows NT, Secret APIs and the Consequences](http://www.stratigery.com/nt.sekrits.html)\n * [Native shell — a command prompt for native mode](http://hex.pp.ua/nt-native-applications-shell-eng.php)\n\n# Additional Information\n\n## Windows Native API\n\nWindows has many ways to access system functions. The normal programmer would just use the methods exported by the dynamic link libraries kernel32.dll, user32.dll and others. They belong to a user-mode API called Win32. Windows was designed to have many of those user-mode APIs called '''Subsystems'''. There were or are Win32, POSIX and Os/2 subsystems. Every subsystem is an API and a runtime environment an application can use to access the system functions of the OS.\n\nBut how do these subsystems access the kernel?\n\nThe answer is: through ntdll. Ntdll is a native dynamic link library providing direct links to kernel mode functions. A program which only uses this API is called a native program and a flag in the executable header marks that fact (see the MS linker's `/SUBSYSTEM` parameter). The subsystems themselves are native programs, of course.\n\nAlso see [Wikipedia's article about the Native API](http://en.wikipedia.org/wiki/Native_API).\n\n### Boot programs and the native API\nBoot programs always have to use the native API and link against ntdll. That is because of the fact that other subsystems are just not available at the time a boot program gets executed. A corrollar: boot programs can't use the normal runtime library because it references Win32 APIs for various tasks. Therefore ntdll.dll exports several common runtime functions boot programs and other native programs can use.\n\n### The registry at boot-time\n\nAt the time a boot program is executed the registry is not yet initialized. Machine/system and machine/hardware are loaded because they need to be loaded for Windows to find the drivers. The SAM at machine\\SAM and the machine\\software are not yet loaded. If you have to read values from this keys you have to plug the keys into the registry (`NtLoadKey`) from the corresponding file. Don't forget to unload the keys (`NtUnloadKey`) afterwards because Windows fails with a bluescreen afterwards if it finds hives mapped when it does not expect them to be.\n\n### Writing to Registry at boot-time\n\nWriting to Registry is even more difficult: The Registry is read-only at boot-time. The causes for this are not known to me but I guess it's because of security issues and they wanted to stop some faulty driver to wreak havoc in the registry even before Windows has booted.\n\nThere is a variable in the Windows Configuration Manager which controls if the Registry can be flushed to disk. It is called `CmpNoWrite`. You may use the kernel debugger to lookup the value...\n\nSo the registry is not writeable at boot-time.\n\nWhat are the solutions for this problem?\n * Unset the flag using the Kernel Debugger. This works but this is not a very automatic solution. It is not portable as well since `CmpNoWrite` is at another position in the kernel everytime the kernel is built.\n * Unset the flag in the boot program from user-mode using a hack. (see [function `showNoWrite`](https://github.com/jrudolph/bootpgm/blob/master/win32/experimental.cpp#L235)). The same issues regarding portability apply.\n * Use `NtInitializeRegistry` to initialize the registry like smss.exe would do it after executing the boot program. That call loads the software and SAM hives and marks the Registry as writable. You don't even have to flush the registry to disk since the changes are persistent nevertheless after booting. That is because the registry can only be initialized once. If you call `NtInitializeRegistry`, the regular call from smss.exe will fail but Windows will start anyway. It is unclear if that works all the time, during our testing it seemed to work always. *A side note: I found this fact about how to make the registry writable in a usenet post from 1997 but it still works...*\n\n## C++ exceptions in native programs\n\nThis native api program/library uses C++-features like classes in many\nplaces. This seems to work without problems so far.\nIt would be appropriate to use C++ exceptions as well. This will not\nwork, however. At least not without some serious effort. C++ exceptions are working\nthrough subtle mechanisms of Windows, the C++ compiler *and* the\nruntime library all together.\n\nTo use exception handling one has to enable the specific options in\nthe compiler. You can use this lines in your SOURCES to enable it:\n\n```\nUSE_NATIVE_EH=1\nUSE_RTTI=1\n```\n\nIf we don't link a runtime library linking will error with unresolved\nexternals like `__CxxFrameHandler` and others.\n\nSince we cannot use Win32 dlls in a native program we cannot link\nagainst the standard runtime library (msvcrt). So the right choice seems to be the\nuse of the staticly linkable runtime library libc. This does not work\neither. Even libc contains uncountable references to functions defined\nin kernel32 and user32. We cannot link to them, of course.\n\nSo your choices are:\n * reimplement C++ exception handling on top of the native (API) features\n provided by Windows and the compiler\n * use structured exception handling as documented by Microsoft, this\n will not work in functions relying on automatic object deconstruction\n * don't use exceptions at all (that was my choice)\n\nSee also:\n * [Reversing Microsoft Visual C++ Part I: Exception Handling](http://www.openrce.org/articles/full_view/21)\n * [How a C++ compiler implements exception handling](http://www.codeproject.com/Articles/2126/How-a-C-compiler-implements-exception-handling)\n * [The Exception Model](http://blogs.msdn.com/cbrumme/archive/2003/10/01/51524.aspx)\n * [A Crash Course in SEH](http://www.microsoft.com/msj/0197/exception/exception.aspx)\n * [New Vectored Exception Handling in Windows XP](http://msdn.microsoft.com/msdnmag/issues/01/09/hood/default.aspx)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjrudolph%2Fbootpgm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjrudolph%2Fbootpgm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjrudolph%2Fbootpgm/lists"}