Skip to content

Commit

Permalink
First version of dxil signing tool
Browse files Browse the repository at this point in the history
  • Loading branch information
gwihlidal committed Sep 14, 2018
1 parent 0b8c29e commit f6942b4
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 15 deletions.
7 changes: 1 addition & 6 deletions .gitignore
@@ -1,6 +1 @@
CMakeCache.txt
CMakeFiles
CMakeScripts
Makefile
cmake_install.cmake
install_manifest.txt
build
2 changes: 1 addition & 1 deletion CMakeLists.txt
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.10)
project(dxil-signing)

set(CMAKE_CXX_STANDARD 17)
Expand Down
0 dxil/extras/dxcapi.h → dxcapi.h 100755 → 100644
File renamed without changes.
File renamed without changes.
0 dxil/x64/dxil.dll → dxil.dll 100755 → 100644
File renamed without changes.
Binary file removed dxil/extras/x64/dxcompiler.lib
Binary file not shown.
Binary file removed dxil/x64/dxc.exe
Binary file not shown.
146 changes: 138 additions & 8 deletions main.cpp
@@ -1,19 +1,149 @@
#include <iostream>
#include <windows.h>
#include <wrl/client.h>
#include "CLI11.hpp"
#include "dxcapi.h"

using Microsoft::WRL::ComPtr;

int main(int argc, const char* argv[])
{
CLI::App app{"DXIL Signing Utility"};
CLI::App app{ "DXIL Signing Utility" };

std::string input_file = "";
app.add_option("-i,--input", input_file, "Input unsigned dxil file")->required();

std::string output_file = "";
app.add_option("-o,--output", output_file, "Output signed dxil file")->required();

CLI11_PARSE(app, argc, argv);

std::cout << "Loading input file: " << input_file << std::endl;

FILE* input_fh = fopen(input_file.c_str(), "rb");
if (input_fh == nullptr)
{
std::cout << "Failed to open input file" << std::endl;
exit(1);
}

fseek(input_fh, 0, SEEK_END);
size_t input_size = ftell(input_fh);
fseek(input_fh, 0, SEEK_SET);

std::vector<uint8_t> input_data;
input_data.resize(input_size);
size_t bytes_read = fread(input_data.data(), 1, input_data.size(), input_fh);
fclose(input_fh);

if (bytes_read != input_data.size())
{
std::cout << "Failed to read input file" << std::endl;
exit(1);
}

HMODULE dxil_module = ::LoadLibrary("dxil.dll");
if (dxil_module == nullptr)
{
std::cout << "Failed to load dxil.dll" << std::endl;
exit(1);
}

DxcCreateInstanceProc dxil_create_func = (DxcCreateInstanceProc)GetProcAddress(dxil_module, "DxcCreateInstance");
if (dxil_create_func == nullptr)
{
std::cout << "Failed to get dxil create proc" << std::endl;
exit(1);
}

HMODULE dxc_module = ::LoadLibrary("dxcompiler.dll");
if (dxc_module == nullptr)
{
std::cout << "Failed to load dxcompiler.dll" << std::endl;
exit(1);
}

DxcCreateInstanceProc dxc_create_func = (DxcCreateInstanceProc)GetProcAddress(dxc_module, "DxcCreateInstance");
if (dxc_create_func == nullptr)
{
std::cout << "Failed to get dxc create proc" << std::endl;
exit(1);
}

ComPtr<IDxcLibrary> library;
dxc_create_func(CLSID_DxcLibrary, __uuidof(IDxcLibrary), (void**)&library);

ComPtr<IDxcBlobEncoding> containerBlob;
library->CreateBlobWithEncodingFromPinned((BYTE*)input_data.data(), (UINT32)input_data.size(), 0 /* binary, no code page */, containerBlob.GetAddressOf());

ComPtr<IDxcValidator> validator;
if (FAILED(dxc_create_func(CLSID_DxcValidator, __uuidof(IDxcValidator), (void**)&validator)))
{
std::cout << "Failed to create validator instance" << std::endl;
exit(1);
}

ComPtr<IDxcOperationResult> result;
if (FAILED(validator->Validate(containerBlob.Get(), DxcValidatorFlags_InPlaceEdit, &result)))
{
std::cout << "Failed to validate dxil container" << std::endl;
exit(1);
}

HRESULT validateStatus;
if (FAILED(result->GetStatus(&validateStatus)))
{
std::cout << "Failed to get dxil validate status" << std::endl;
exit(1);
}

if (FAILED(validateStatus))
{
std::cout << "The dxil container failed validation" << std::endl;

std::string errorString;

ComPtr<IDxcBlobEncoding> printBlob, printBlobUtf8;
result->GetErrorBuffer(&printBlob);

library->GetBlobAsUtf8(printBlob.Get(), printBlobUtf8.GetAddressOf());
if (printBlobUtf8)
{
errorString = reinterpret_cast<const char*>(printBlobUtf8->GetBufferPointer());
}

std::cout << "Error: " << std::endl << errorString << std::endl;

exit(2);
}

ComPtr<IDxcBlob> validatedBlob;
if (FAILED(result->GetResult(&validatedBlob)))
{
std::cout << "Failed to get validated dxil blob" << std::endl;
exit(1);
}

validator = nullptr;

std::string input_file = "";
app.add_option("-i,--input", input_file, "Input unsigned dxil file")->required();
std::cout << "Saving output file: " << output_file << std::endl;

std::string output_file = "";
app.add_option("-o,--output", output_file, "Output signed dxil file")->required();
FILE* output_fh = fopen(output_file.c_str(), "wb");
if (output_fh == nullptr)
{
std::cout << "Failed to create output file" << std::endl;
exit(1);
}

CLI11_PARSE(app, argc, argv);
size_t bytes_written = fwrite(validatedBlob->GetBufferPointer(), 1, validatedBlob->GetBufferSize(), output_fh);
fclose(output_fh);

std::cout << "Loading input file: " << input_file << std::endl;
if (bytes_written != validatedBlob->GetBufferSize())
{
std::cout << "Failed to write output file" << std::endl;
exit(1);
}

std::cout << "Saving output file: " << output_file << std::endl;
::FreeLibrary(dxc_module);
::FreeLibrary(dxil_module);
}
Binary file added simple.dxil
Binary file not shown.
4 changes: 4 additions & 0 deletions simple.hlsl
@@ -0,0 +1,4 @@
float4 main() : SV_TARGET0
{
return float4(0, 1, 0, 1);
}
5 changes: 5 additions & 0 deletions vs2017.bat
@@ -0,0 +1,5 @@
@echo off
mkdir build
cd build
cmake ../. -G "Visual Studio 15 Win64"
cd ../

0 comments on commit f6942b4

Please sign in to comment.