refactorings

This commit is contained in:
Oscar Krause
2025-04-11 20:19:58 +02:00
parent 5ab2e0db11
commit c8cd51a9f5
7 changed files with 9 additions and 0 deletions

55
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,55 @@
# SPDX-License-Identifier: GPL-2.0-or-later
cmake_minimum_required(VERSION 3.5)
project(gridd-unlock-patcher CXX)
include(ExternalProject)
include(cmake/FetchCPM.cmake)
CPMAddPackage(
NAME LIEF_SRC
GITHUB_REPOSITORY lief-project/LIEF
GIT_TAG 0.16.4
DOWNLOAD_ONLY YES
)
if (LIEF_SRC_ADDED)
set(LIEF_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/LIEF")
set(LIEF_INSTALL_DIR "${LIEF_PREFIX}")
set(LIEF_INCLUDE_DIRS "${LIEF_PREFIX}/include")
set(LIEF_LIBRARIES
"${LIEF_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}LIEF${CMAKE_STATIC_LIBRARY_SUFFIX}"
)
set(LIEF_CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DLIEF_EXAMPLES=off
-DLIEF_ENABLE_JSON=off
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
)
ExternalProject_Add(LIEF
PREFIX "${LIEF_PREFIX}"
SOURCE_DIR ${LIEF_SRC_SOURCE_DIR}
INSTALL_DIR ${LIEF_INSTALL_DIR}
CMAKE_ARGS ${LIEF_CMAKE_ARGS}
BUILD_BYPRODUCTS ${LIEF_LIBRARIES}
UPDATE_COMMAND ""
)
endif()
message(STATUS "LIEF include directory: ${LIEF_INCLUDE_DIRS}")
message(STATUS "LIEF library: ${LIEF_LIBRARIES}")
add_executable(gridd-unlock-patcher gridd-unlock-patcher.cpp)
add_dependencies(gridd-unlock-patcher LIEF)
target_include_directories(gridd-unlock-patcher PRIVATE ${LIEF_INCLUDE_DIRS})
target_link_libraries(gridd-unlock-patcher PRIVATE ${LIEF_LIBRARIES})
set_target_properties(gridd-unlock-patcher PROPERTIES LINK_FLAGS_RELEASE -s)
install(TARGETS gridd-unlock-patcher)

11
src/build.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
if [ "$1" == "clean" ] || [ "$1" == "rebuild" ]; then
rm -rf build gridd-unlock-patcher
fi
if [ "$1" == "rebuild" ] || [ "$1" != "clean" ]; then
mkdir -p build; cd build
cmake -DCMAKE_BUILD_TYPE=Release .. && make -j$(nproc) && mv gridd-unlock-patcher ..
cd ..
fi

24
src/cmake/FetchCPM.cmake Normal file
View File

@@ -0,0 +1,24 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
set(CPM_DOWNLOAD_VERSION 0.40.8)
set(CPM_HASH_SUM "78ba32abdf798bc616bab7c73aac32a17bbd7b06ad9e26a6add69de8f3ae4791")
if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()
# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)
include(${CPM_DOWNLOAD_LOCATION})

View File

@@ -0,0 +1,137 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <LIEF/ELF.hpp>
#include "nls-root_ca-certificates.hpp"
using namespace LIEF::ELF;
FILE *gridd_filep = NULL;
uint8_t *gridd_data = NULL;
FILE *cert_fp = NULL;
void *user_root_ca = NULL;
void usage(char *program_name)
{
printf("Usage: %s [OPTIONS]\n", program_name);
printf("\n"
" -h\n"
" -g <nvidia-gridd binary>\n"
" -c <root CA certificate>\n"
"\n");
}
int parse_args(int argc, char *argv[])
{
int opt;
while ((opt = getopt(argc, argv, "hg:c:")) != -1) {
// Required parameter is in global "optarg"
switch (opt) {
case '?':
/* fall through */
case 'h':
usage(argv[0]);
return -1;
case 'g':
gridd_filep = fopen(optarg, "rb+");
break;
case 'c':
cert_fp = fopen(optarg, "rb");
break;
}
}
if (gridd_filep == NULL || cert_fp == NULL) {
usage(argv[0]);
return -1;
}
return 0;
}
void cleanup(void)
{
if (user_root_ca)
free(user_root_ca);
if (gridd_data)
free(gridd_data);
if (cert_fp)
fclose(cert_fp);
if (gridd_filep)
fclose(gridd_filep);
}
int main(int argc, char *argv[])
{
struct stat gridd_fp_stats, cert_fp_stats;
size_t status;
if (parse_args(argc, argv) == -1) {
cleanup();
return -1;
}
/* Find the hardcoded certificates */
// Read the nvidia-gridd binary
fstat(fileno(gridd_filep), &gridd_fp_stats);
gridd_data = (uint8_t *)malloc(gridd_fp_stats.st_size);
assert(gridd_data != NULL);
status = fread((void *)gridd_data, gridd_fp_stats.st_size, 1, gridd_filep);
assert(status > 0);
// Parse the ELF
std::vector<uint8_t> gridd_vec(gridd_data, gridd_data + gridd_fp_stats.st_size);
auto gridd_bin = Parser::parse(gridd_vec);
auto s_rodata = gridd_bin->get_section(".rodata");
auto s_data = gridd_bin->get_section(".data");
// There are two hardcoded certificates
size_t cert_one_offset = s_rodata->search(gridd_hardcoded_cert_one);
size_t cert_two_offset = s_rodata->search(gridd_hardcoded_cert_two);
printf("Found the two hardcoded NLS certificates at 0x%x and 0x%x.\n", cert_one_offset, cert_two_offset);
/* Validate the size of the provided root CA */
fstat(fileno(cert_fp), &cert_fp_stats);
// FIXME: Align up to cover the padding?
size_t total_cert_size = cert_two_offset + (strlen(gridd_hardcoded_cert_two) + 1) - cert_one_offset;
if (cert_fp_stats.st_size > total_cert_size) {
printf("The provided certificate (size %d) is larger than the available space (size %d)!\n",
cert_fp_stats.st_size, total_cert_size);
cleanup();
return -1;
}
/* Patch in the provided certificate */
// Read the provided root CA
user_root_ca = malloc(cert_fp_stats.st_size);
assert(user_root_ca != NULL);
status = fread(user_root_ca, cert_fp_stats.st_size, 1, cert_fp);
assert(status > 0);
// Overwrite the first certificate, NULL the second
uint8_t *cert_start = gridd_data + s_rodata->offset() + cert_one_offset;
memcpy((void *)cert_start, user_root_ca, cert_fp_stats.st_size);
memset((void *)(cert_start + cert_fp_stats.st_size), 0, total_cert_size - cert_fp_stats.st_size);
printf("Replaced the hardcoded certificates with the provided one.\n");
// Erase the XREF to the second certificate
size_t cert_xrefs_array = s_data->offset() + s_data->search(s_rodata->virtual_address() + cert_one_offset);
memset((void *)(gridd_data + cert_xrefs_array + sizeof(uint64_t)), 0, sizeof(uint64_t));
printf("Fixed up the list of certificates. Done!\n");
// Write the nvidia-gridd binary
FILE *test = fopen("gridd_bin", "wb");
fwrite((void *)gridd_data, gridd_fp_stats.st_size, 1, test);
fclose(test);
cleanup();
return 0;
}

View File

@@ -0,0 +1,73 @@
const char *gridd_hardcoded_cert_one =
"-----BEGIN CERTIFICATE-----\n"
"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\n"
"bBj+W2v1REPS\n"
"-----END CERTIFICATE-----";
const char *gridd_hardcoded_cert_two =
"-----BEGIN CERTIFICATE-----\n"
"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\n"
"JQ6S82i+o497\n"
"-----END CERTIFICATE-----";