• Stars
    star
    444
  • Rank 98,300 (Top 2 %)
  • Language
    C
  • Created over 9 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A project for allowing EDK-II Development with Visual Studio

Synopsis

VisualUEFI is

  • A Solution and set of Visual Studio Project Files to allow building the official EDK-II (including OpenSSL 1.1.0e) without the use of inf files, python and 50 other build tools, a custom dependency tracker and build system, and twenty other custom pieces of code. The EDK-II and OpenSSL are present as submodules, directly from the official TianoCore Tree, and no changes are done to them.

  • A Solution and couple of Visual Studio Project Files to show four UEFI sample components: An UEFI Application and associated UEFI Boot Driver, the EDK-II Sample FtdiUsbSerialDxe Driver, and the EDK-II Sample Cryptest Application which uses OpenSSL 1.1.0e. The code is 100% EDK-II compatible, but built with VisualUEFI instead.

  • A working and FAST copy of QEMU64 2.10 for Windows, with a fairly recent UEFI 2.6 OVMF Secure Boot ROM which includes SMM support and an actual protected flash for enrolling PK/KEK/DB/DBX keys. These will updated on an ongoing basis as needed. This is integrated with the Visual Studio Sample Solution so that pressing F5 will spin up the instance for testing.

If you would like to know more about my research or work, I invite you check out my blog at http://www.alex-ionescu.com as well as my training & consulting company, Winsider Seminars & Solutions Inc., at http://www.windows-internals.com.

Code Example

Here is a very simple example of a UEFI application communicating with a UEFI driver protocol. This sample is part of VisualUefi.

//
// Basic UEFI Libraries
//
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>

//
// Boot and Runtime Services
//
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>

//
// Custom Driver Protocol
//
#include "../UefiDriver/drvproto.h"
EFI_GUID gEfiSampleDriverProtocolGuid = EFI_SAMPLE_DRIVER_PROTOCOL_GUID;

//
// We run on any UEFI Specification
//
extern CONST UINT32 _gUefiDriverRevision = 0;

//
// Our name
//
CHAR8 *gEfiCallerBaseName = "UefiApplication";

EFI_STATUS
EFIAPI
UefiUnload (
    IN EFI_HANDLE ImageHandle
    )
{
    //
    // This code should be compiled out and never called
    //
    ASSERT(FALSE);
}

EFI_STATUS
EFIAPI
UefiMain (
    IN EFI_HANDLE ImageHandle,
    IN EFI_SYSTEM_TABLE* SystemTable
    )
{
    EFI_STATUS efiStatus;
    SHELL_FILE_HANDLE fileHandle;
    UINT8 buffer[4];
    UINTN readSize;
    EFI_SAMPLE_DRIVER_PROTOCOL* sampleProtocol;

    // 
    // Print stuff out 
    // 
    fileHandle = NULL;
    Print(L"Hello World! My handle is %lx and System Table is at %p\n",
          ImageHandle, SystemTable);

    //
    // Initialize the shell library
    //
    efiStatus = ShellInitialize();
    if (EFI_ERROR(efiStatus))
    {
        Print(L"Failed to initialize shell: %lx\n", efiStatus);
        goto Exit;
    }

    //
    // Open ourselves
    //
    efiStatus = ShellOpenFileByName(L"fs1:\\UefiApplication.efi",
                                    &fileHandle,
                                    EFI_FILE_MODE_READ,
                                    0);
    if (EFI_ERROR(efiStatus))
    {
        Print(L"Failed to open ourselves: %lx\n", efiStatus);
        fileHandle = NULL;
        goto Exit;
    }

    //
    // Read 4 bytes at the top (MZ header)
    //
    readSize = sizeof(buffer);
    efiStatus = ShellReadFile(fileHandle, &readSize, &buffer);
    if (EFI_ERROR(efiStatus))
    {
        Print(L"Failed to read ourselves: %lx\n", efiStatus);
        goto Exit;
    }

    //
    // Print it
    //
    Print(L"Data: %lx\n", *(UINT32*)buffer);

    // 
    // Check if the sample driver is loaded 
    // 
    efiStatus = gBS->LocateProtocol(&gEfiSampleDriverProtocolGuid, NULL, &sampleProtocol);
    if (EFI_ERROR(efiStatus))
    {
        Print(L"Failed to locate our driver: %lx\n", efiStatus);
        goto Exit;
    }

    // 
    // Print the value and exit 
    // 
    Print(L"Sample driver is loaded: %lx\n", sampleProtocol->SampleValue);

Exit:
    //
    // Close our file handle
    //
    if (fileHandle != NULL)
    {
        ShellCloseFile(&fileHandle);
    }

    //
    // Sample complete!
    //
    return efiStatus;
}

Motivation

Although EDK-II's build subsystem supports Visual Studio, it doesn't work with "in-IDE" building. Instead, special .inf files and other templates are used to define projects, and a custom build composed of multiple 3rd party tools must be ran -- including dependencies on Python, Ruby, and Perl. For developers already familiar with Visual Studio's project files/MSBUILD, as well as the IDE it offers, this can be cumbersome and limiting, slowing down the ability to quickly jump into UEFI development. Additionally, the EDK-II's default "test" environment is to build a Windows "NT32" layer around your application and running it as a command line executable. While this might work for very simple applications, it doesn't reliably provide an environment for testing DXE drivers, runtime services, and more.

VisualUefi aims to bridge these gaps by compiling 100% unmodified EDK-II libraries with a proper Visual Studio build environment, adding some VisualUefi-specific glue to support building within Visual Studio without 3rd party tools, and includes the latest QEMU and OVMF w/ SecureBoot packages for bare-metal testing of UEFI, without relying on Windows emulation.

Installation

At first install NASM (https://www.nasm.us/) and check, that environment variable NASM_PREFIX is correctly set to NASM installation path. No other 3rd party tools are needed.

Than you should be able to open the EDK-II.SLN file and build without any issues in either Visual Studio 2015 or 2017. WDK is not needed.

Once the EDK-II libraries are built, you should be able to open the SAMPLES.SLN file and build the samples, which will create UefiApplication.efi, UefiDriver.efi, Cryptest.efi, and FtdiUsbSerialDxe.efi

Documentation

Please refer to EDK-II/TianoCore for all documentation/help regarding EDK-II.

Tests

You can press F5 (Run/Debug) from within the Sample Solution, which should spin up the QEMU instance with 512MB of RAM, and your release directory as a virtual file system accessible through fs1:

You can then try loading the driver as follows:

* load fs1:\UefiDriver.efi

You can verify its presence by using either of these commands:

* drivers (Should display "Sample Driver")
* devtree (Should show a few "Sample Device" entries)

You can also launch the sample application, which should find the driver:

* fs1:\UefiApplication.efi

Contributors

Please use the GitHub issue tracker to submit any bugs/requests/etc.

For other feedback, you can reach me on Twitter at @aionescu

License

  • For the "samples" and "edk-ii" directory, the following license applies:

      Copyright (c) 2015-2017, Alex Ionescu. All rights reserved.
      This program and the accompanying materials are licensed and made available under
      the terms and conditions of the BSD License which accompanies this distribution. 
      The full text of the license may be found at
      http://opensource.org/licenses/bsd-license.php
    
  • For the "debugger" directory, the following license applies:

      The following points clarify the QEMU license:
    
      1) QEMU as a whole is released under the GNU General Public License,
      version 2.
    
      2) Parts of QEMU have specific licenses which are compatible with the
      GNU General Public License, version 2. Hence each source file contains
      its own licensing information.  Source files with no licensing information
      are released under the GNU General Public License, version 2 or (at your
      option) any later version.
    
      As of July 2013, contributions under version 2 of the GNU General Public
      License (and no later version) are only accepted for the following files
      or directories: bsd-user/, linux-user/, hw/misc/vfio.c, hw/xen/xen_pt*.
    
      3) The Tiny Code Generator (TCG) is released under the BSD license
         (see license headers in files).
    
      4) QEMU is a trademark of Fabrice Bellard.
    
      Fabrice Bellard and the QEMU team
    
  • The "edk2" submodule has its own licensing information, please read it.

More Repositories

1

SimpleVisor

SimpleVisor is a simple, portable, Intel VT-x hypervisor with two specific goals: using the least amount of assembly code (10 lines), and having the smallest amount of VMX-related code to support dynamic hyperjacking and unhyperjacking (that is, virtualizing the host state from within the host). It works on Windows and UEFI.
C
1,607
star
2

lxss

Fun with the Windows Subsystem for Linux (WSL/LXSS)
C++
831
star
3

SpecuCheck

SpecuCheck is a Windows utility for checking the state of the software mitigations and hardware against CVE-2017-5754 (Meltdown), CVE-2017-5715 (Spectre v2), CVE-2018-3260 (Foreshadow), and CVE-2018-3639 (Spectre v4)
C
559
star
4

winipt

The Windows Library for Intel Process Trace (WinIPT) is a project that leverages the new Intel Processor Trace functionality exposed by Windows 10 Redstone 5 (1809), through a set of libraries and a command-line tool.
C
341
star
5

minlzma

The Minimal LZMA (minlzma) project aims to provide a minimalistic, cross-platform, highly commented, standards-compliant C library (minlzlib) for decompressing LZMA2-encapsulated compressed data in LZMA format within an XZ container, as can be generated with Python 3.6, 7-zip, and xzutils
C
332
star
6

faxhell

A Bind Shell Using the Fax Service and a DLL Hijack
C
317
star
7

Simpleator

Simpleator ("Simple-ator") is an innovative Windows-centric x64 user-mode application emulator that leverages several new features that were added in Windows 10 Spring Update (1803), also called "Redstone 4", with additional improvements that were made in Windows 10 October Update (1809), aka "Redstone 5".
C++
313
star
8

hdk

(unofficial) Hyper-Vยฎ Development Kit
C
209
star
9

HookingNirvana

Recon 2015 Presentation from Alex Ionescu
C
205
star
10

PrintDemon

PrintDemon is a PoC for a series of issues in the Windows Print Spooler service, as well as potetial misuses of the functionality.
C
196
star
11

clfs-docs

Unofficial Common Log File System (CLFS) Documentation
143
star
12

tpmtool

The TpmTool utility is a simple cross-platform tool for accessing TPM2.0 Non-Volatile (NV) Spaces (Index Values) on compliant systems, with zero dependencies on any TPM2.0 stack. It provides the ability to enumerate, create, delete, query, and lock NV indices, as well as to read and write data stored in them.
C++
133
star
13

wnfun

WNF Utilities 4 Newbies (WNFUN)
Python
87
star
14

hazmat5

Local OXID Resolver (LCLOR) : Research and Tooling
C++
31
star
15

Blackwood-4NT

Blackwood 4NT -- Grand Slam Authentication for Windows NT (10)
26
star
16

smctool

SMC Utility for Apple Macintosh Computers
13
star