No, Windows Loader is entirely safe and secure for us. Theree is no virut. Before uploading her,e I also checked it using the Antivirus tool for any malicious codes. However, it will still show you as a virus because these tools are blacklisted. In this way, if you are going to use I,t, then make sure to disable any antivirus or windows defender.
In addition to that, how should I add Arch to the Windows Bootloader, as I'm unsure of what I need to do with bcdedit, or if EasyBCD 2.2's compatibility with EFI is confirmed. Also, if anyone has any good program recommendations in lieu of EasyBCD, it would be appreciated.
However, in windows I can go to System recovery -> advanced startup -> troubleshoot -> advanced options -> UEFI firmware settings -> F9 Boot Menu and at this point it shows me 2 boot loaders: one for windows (at top) and one for ubuntu (2nd). I can select one or the other, but cannot change the order. If I select the ubuntu loader, it starts grub, shows me an option for windows as well as ubuntu, and will boot ubuntu if selected.
A loader is code that prepares other code for execution. Loaders take data
corresponding to a program or library and prepare it to be read, modified, and/or executed. This preparation process typically involves steps such as parsing a file containing the code to be run, metadata about that code, and other relevant bits of information such as the external services it might need from other parts of the operating system. Additionally, things like resolving external dependencies - or other, external bits of code the bit being prepared will rely upon, setting memory protections appropriately, and perhaps updating references (if the code is not position independent) will happen here.
Nearly all modern consumer-facing operating systems contain loaders. Loading occurs during the initialization of a process (when the primary application image is loaded), and also may occur in an ad-hoc fashion throughout program execution, as dynamic libraries (to include .dlls, .dylibs, and .sos, for example) are loaded and unloaded.
In the context of things like threat emulation, there is a strong desire to model trends present within the modern malware ecosystem - including the ability to operate in memory only. This presents a bit of a challenge: in Windows, for example, the operating system's built-in loader
only accepts binary files on disk. What we desire is a reflective loader
that will perform some of the same kinds of preparations that the native operating system's loader would handle, but without the requirement that the loaded binary reside on disk (note that some operating systems, such as MacOS, have facilities for executing directly in-memory natively).
The reflective_loadlibrary function accepts three arguments. First, it accepts
a loader_ctx, which contains a pointer to a structure we will use to manage contextual information that the loader will need as we implement it. Next, it accepts a buffer and its corresponding size, which represent the module that we wish to load. The function returns a LoaderStatus, which is a type we've created to help provide status results around success or failure as loader development progresses.
The Portable Executable (PE) format is a file format for executables, DLLs, Drivers, and some more exotic kinds of files on 32- and 64-bit versions of Windows. It contains all the information Windows needs to load and execute the specified module. Since we're re-implementing some of the Windows loader's functionality, we'll also need to parse PE files during the course of loading and executing.
For robustness, we'll want to verify that the buffer that our reflective loader receives is actually a PE file. A simple validation technique is to check that (a) the e_magic value is correct, and (b) that the RVA of the NT headers resides within the bounds of our buffer. The code snippet below illustrates how we might perform these checks.
The first field is a bit poorly named, as it is actually an RVA, coupled with a size. We will visit quite a few of these table entries as we progress through the loader development sections that follow.
While many allocator APIs exist in Windows, some special considerations must be applied to requesting memory for our loader. In particular, we have some special alignment and protection requirements (in general) that we will need to adhere to in order to ensure that our program will perform properly once loaded.
To keep things simple, we will start with VirtualAlloc, but keep in mind that other options exist, and may have different implications in terms of how our memory footprint looks forensically. So how much space should we get? In order to obtain that information, we should refer back to the IMAGE_OPTIONAL_HEADER structure from the last section, in particular, the SizeOfImage field. Thus, we can update our loader method as follows:
DisplayCAL (argyllcms) LUT loader can load calibration data to LUT at the highest precision available for that HW, so a video card with more that 8bit/entry LUTs and dithering at its output can show smooth gradients like a display with internal HW calibration.
I have provided a small project in the code download for this article that contains a main executable, ingenuously named Test, and three DLLs: TestDll, Forwarder, and Forwarded. The DLLs demonstrate different variations that illustrate some of the scenarios LdrpLoadDll will commonly encounter. See the Readme.txt file in the code download for important information about setting environment variables and predefined breakpoints.
Figure 3 shows some of the internal loader routines you will bump into when you pass one of the documented flags to LoadLibraryExW. If you concentrate for a moment on the typical situation (#1 in Figure 3), you will see that there are six subroutines called directly by LdrpLoadDll: LdrpCheckForLoadedDll, LdrpMapDll, LdrpWalkImportDescriptor, LdrpUpdateLoadCount, LdrpRunInitializeRoutines, and LdrpClearLoadInProgress. (I'll discuss the first four subroutines later in this article.) LdrpRunInitializeRoutines has already been described in Matt Pietrek's column, so I won't go into it here. LdrpClearLoadInProgress is briefly mentioned in that column as well.
Let's take a high-level look at the steps taken by LdrpLoadDll, which occur as follows:
You may think that the route through LdrpLoadDll has been relatively straight and uncomplicated so far. But there still may be a maze of passages ahead. Your attempt to load LdrpLoadDll may have generated the need for additional modules, and this is where LdrpWalkImportDescriptor comes in. (In order to better understand my pseudocode, it will help to have some knowledge of the PE header definitions found in WinNt.h, especially those relevant to imports and exports. You can take a look at "Inside Windows: An In-Depth Look into the Win32 Portable Executable File Format" by Matt Pietrek in the February 2002 issue of MSDN Magazine.
Your typical module load takes you through the twists and turns of LdrpWalkImportDescriptor. However, if you specify DONT_RESOLVE_DLL_REFERENCES in your call to LoadLibraryExW, then you will avoid the upcoming maze. You should read the SDK documentation carefully to make certain that this is what you want. There is also a mechanism, which I'll explain later, to help you avoid the loops and recursion that are part of LdrpSnapIAT and LdrpSnapThunk. But if you don't take either of these alternatives, then you need to know what happens with LdrpWalkImportDescriptor.
Orient yourself once again by reexamining Figure 3, locating LdrpWalkImportDescriptor. LdrpWalkImportDescriptor has two subroutines: LdrpLoadImportModule and LdrpSnapIAT. This does not seem so bad, but one tip-off that this code will soon become interesting is that there are four nesting levels in the routines for LdrpSnapIAT. The number and depth of nested functions is one metric that indicates the complexity of code. You should take note that recursion is possible in not one, but two locations in LdrpSnapIAT. You may recall that in the section on APIs exported by NTDLL.DLL I mentioned the apparent simplicity of the call to LdrpLoadDll and the fifth parameter that took a 0 or a 1. LdrpSnapIAT can also be recursive inside LdrpGetProcedureAddress. Finally, to make things even more complex than they already were, it's possible that a typical DLL may import other modules that start a cascade of additional library loads. The loader will need to loop through each module, checking to see if it needs to be loaded and then checking its dependencies.
With that in mind, let's take a look at the pseudocode found in LdrpWalkImportDescriptor.cpp. (If you are following along with the debugger, change the test program to load the Forwarded.DLL module and restart the debugger.) Execution starts with two calls to RtlImageDirectoryEntryToData to locate the Bound Imports Descriptor and the regular Import Descriptor tables. For the moment, ignore the call for that bound import thing except to notice that the code checks for its presence first. (I'll discuss binding later.) In Forwarded.DLL, LdrpWalkImportDescriptor detects two imported modules, User32.DLL and Kernel32.DLL, and now calls upon LdrpLoadImportModule for assistance.
LdrpLoadImportModule constructs a Unicode string for each DLL found in the import table and then employs LdrpCheckForLoadedDll, using the hash table in NTDLL that was mentioned earlier to see if they have already been loaded. Note that the call here is made with only the file name (no fully qualified path) and the process's search path. If you have ever had your application complain that it cannot find a DLL, you should realize that it may not be the loading module's fault. Check to see that all of its dependent modules can be found. If a module is found and already loaded, life is good because there is one less module to worry about. If it has not been loaded, then you've found an instance of recursion. A call to LdrpMapDll to bring the DLL into the process' address space is followed by a call to LdrpWalkImportDescriptor. Now you're in the middle of the twisting mazes I mentioned.