From 5684623164134bde72e75ffaa35259546d55f20c Mon Sep 17 00:00:00 2001 From: belliash Date: Wed, 17 May 2023 15:17:58 +0200 Subject: [PATCH] Upgrade LLVM and rewrite exetool in C --- build-linux.sh | 5 +- scripts/exetool | 79 --------------------------- tools/exetool.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 82 deletions(-) delete mode 100755 scripts/exetool create mode 100644 tools/exetool.c diff --git a/build-linux.sh b/build-linux.sh index 4c079a4..5179fc8 100755 --- a/build-linux.sh +++ b/build-linux.sh @@ -28,7 +28,7 @@ CMAKEVCS="https://gitlab.kitware.com/cmake/cmake.git" # LLVM Settings LLVMDIR="${SRCDIR}/llvm" -LLVMTAG="llvmorg-16.0.0" +LLVMTAG="llvmorg-16.0.4" LLVMVCS="https://github.com/llvm/llvm-project.git" # Make Settings @@ -533,14 +533,13 @@ xtchain_build() for EXEC in dlltool ld objdump; do ln -sf ../${GENERIC}/bin/${EXEC}-wrapper ${BINDIR}/bin/${ARCH}-w64-mingw32-${EXEC} done - for EXEC in windres xtcspecc; do + for EXEC in exetool windres xtcspecc; do if [ ! -e ${BINDIR}/bin/${EXEC} ]; then gcc ${WRKDIR}/tools/${EXEC}.c -o ${BINDIR}/bin/${EXEC} fi ln -sf ${EXEC} ${BINDIR}/bin/${ARCH}-w64-mingw32-${EXEC} done done - cp ${WRKDIR}/scripts/exetool ${BINDIR}/bin/ cp ${WRKDIR}/scripts/xtclib ${BINDIR}/lib/xtchain/ cp ${WRKDIR}/scripts/xtchain ${BINDIR}/ } diff --git a/scripts/exetool b/scripts/exetool deleted file mode 100755 index 732d501..0000000 --- a/scripts/exetool +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import struct - -if len(sys.argv) < 3: - print("XTChain ExeTool for modifying PE/COFF image subsystem\nNot sufficient parametrs. '[PE/COFF Image File]' '[SubSystem]'") - sys.exit(1) - -ImageFile = sys.argv[1] -Subsystem = sys.argv[2].upper() - -# Set proper subsystem -if Subsystem == "UNKNOWN": - ImageSubsystem = 0x00 -elif Subsystem == "NT_NATIVE": - ImageSubsystem = 0x01 -elif Subsystem == "WINDOWS_GUI": - ImageSubsystem = 0x02 -elif Subsystem == "WINDOWS_CLI": - ImageSubsystem = 0x03 -elif Subsystem == "WINDOWS_CE_OLD": - ImageSubsystem = 0x04 -elif Subsystem == "OS2_CUI": - ImageSubsystem = 0x05 -elif Subsystem == "POSIX_CUI": - ImageSubsystem = 0x07 -elif Subsystem == "NATIVE_WINDOWS": - ImageSubsystem = 0x08 -elif Subsystem == "WINDOWS_CE_GUI": - ImageSubsystem = 0x09 -elif Subsystem == "EFI_APPLICATION": - ImageSubsystem = 0x0A -elif Subsystem == "EFI_BOOT_SERVICE_DRIVER": - ImageSubsystem = 0x0B -elif Subsystem == "EFI_RUNTIME_DRIVER": - ImageSubsystem = 0x0C -elif Subsystem == "EFI_ROM": - ImageSubsystem = 0x0D -elif Subsystem == "XBOX": - ImageSubsystem = 0x0E -elif Subsystem == "WINDOWS_BOOT_APPLICATION": - ImageSubsystem = 0x10 -elif Subsystem == "XT_NATIVE_KERNEL": - ImageSubsystem = 0x14 -elif Subsystem == "XT_NATIVE_APPLICATION": - ImageSubsystem = 0x15 -elif Subsystem == "XT_NATIVE_DRIVER": - ImageSubsystem = 0x16 -elif Subsystem == "XT_DYNAMIC_LIBRARY": - ImageSubsystem = 0x17 -elif Subsystem == "XT_APPLICATION_CLI": - ImageSubsystem = 0x18 -elif Subsystem == "XT_APPLICATION_GDI": - ImageSubsystem = 0x19 -else: - print("Invalid subsystem privided") - exit(2) - -# Open PE/COFF image file -PeImage = open(sys.argv[1], "r+b") - -# Get PE header -PeImage.seek(0x3C) -(PeHeader,)=struct.unpack("H", PeImage.read(2)) - -# Get PE signature -PeImage.seek(PeHeader) -(PeSignature,)=struct.unpack("I", PeImage.read(4)) -if PeSignature != 0x4550: - print("Invalid or corrupted PE header") - -# Set new image subsystem -PeImage.seek(PeHeader + 0x5C) -print("Setting subsystem to " + str(ImageSubsystem)) -PeImage.write(struct.pack("H", ImageSubsystem)) - -# Close PE/COFF image file -PeImage.close() diff --git a/tools/exetool.c b/tools/exetool.c new file mode 100644 index 0000000..93a4577 --- /dev/null +++ b/tools/exetool.c @@ -0,0 +1,142 @@ +/** + * PROJECT: XTchain + * LICENSE: See COPYING.md in the top level directory + * FILE: tools/exetool.c + * DESCRIPTION: Portable Executable (PE) utility for changing subsystem + * DEVELOPERS: Rafal Kupiec + */ + +#include "xtchain.h" + +typedef struct _PE_SUBSYSTEM +{ + int Identifier; + char *Name; +} PE_SUBSYSTEM, *PPE_SUBSYSTEM; + +static PE_SUBSYSTEM SubSystems[] = { + {0x01, "NT_NATIVE"}, + {0x02, "WINDOWS_GUI"}, + {0x03, "WINDOWS_CLI"}, + {0x04, "WINDOWS_CE_OLD"}, + {0x05, "OS2_CUI"}, + {0x07, "POSIX_CUI"}, + {0x08, "NATIVE_WINDOWS"}, + {0x09, "WINDOWS_CE_GUI"}, + {0x0A, "EFI_APPLICATION"}, + {0x0B, "EFI_BOOT_SERVICE_DRIVER"}, + {0x0C, "EFI_RUNTIME_DRIVER"}, + {0x0D, "EFI_ROM"}, + {0x0E, "XBOX"}, + {0x10, "WINDOWS_BOOT_APPLICATION"}, + {0x14, "XT_NATIVE_KERNEL"}, + {0x15, "XT_NATIVE_APPLICATION"}, + {0x16, "XT_NATIVE_DRIVER"}, + {0x17, "XT_DYNAMIC_LIBRARY"}, + {0x18, "XT_APPLICATION_CLI"}, + {0x19, "XT_APPLICATION_GDI"} +}; + +int getSubSystemID(char *Name) +{ + int Index; + int SubSystemsCount; + PPE_SUBSYSTEM SubSystem; + + /* Count number of subsystems avaialble */ + SubSystemsCount = sizeof(SubSystems) / sizeof(PE_SUBSYSTEM); + + /* Find subsystem */ + for(Index = 0; Index < SubSystemsCount; Index++) + { + SubSystem = &SubSystems[Index]; + if(strcmp(SubSystem->Name, Name) == 0) + { + /* Subsystem found, return its ID */ + return SubSystem->Identifier; + } + } + + /* No valid subsystem found */ + return 0x00; +} + +int main(int argc, char *argv[]) +{ + FILE *ExeFile; + unsigned char Signature[4]; + unsigned int HeaderOffset; + unsigned short SubSystem; + int NewSubSystem; + + /* Check for proper number of arguments */ + if(argc != 3) + { + printf("Usage: %s \n", argv[0]); + return 1; + } + + /* Open the EXE file in binary mode */ + ExeFile = fopen(argv[1], "r+b"); + if(ExeFile == NULL) + { + /* Failed to open PE file */ + printf("ERROR: Unable to open file %s\n", argv[1]); + return 1; + } + + /* Verify that the input file has a valid DOS header */ + fread(Signature, sizeof(unsigned char), 4, ExeFile); + if(Signature[0] != 'M' || Signature[1] != 'Z') + { + /* Invalid DOS header */ + printf("ERROR: %s is not a valid EXE file\n", argv[1]); + fclose(ExeFile); + return 1; + } + + /* Verify that the input file has a valid PE header */ + fseek(ExeFile, 0x3C, SEEK_SET); + fread(&HeaderOffset, sizeof(unsigned int), 1, ExeFile); + fseek(ExeFile, HeaderOffset, SEEK_SET); + fread(Signature, sizeof(unsigned char), 4, ExeFile); + if(Signature[0] != 'P' || Signature[1] != 'E' || Signature[2] != 0 || Signature[3] != 0) + { + /* Invalid PE header */ + printf("Error: %s is not a valid PE file\n", argv[1]); + fclose(ExeFile); + return 1; + } + + /* Seek to the offset of the SubSystem field in the optional header */ + fseek(ExeFile, HeaderOffset + 0x5C, SEEK_SET); + + /* Read the current SubSystem value */ + fread(&SubSystem, sizeof(unsigned short), 1, ExeFile); + printf("Original SubSystem: 0x%04X\n", SubSystem); + + /* Parse the new SubSystem value from the command line argument */ + NewSubSystem = getSubSystemID(argv[2]); + if(NewSubSystem == 0) + { + /* Invalid SubSystem provided */ + printf("Error: %s is not a valid PE SubSystem\n", argv[2]); + return 1; + } + + /* Print new SubSystem identifier */ + printf("New SubSystem: 0x%04X\n", NewSubSystem); + + /* Seek back to the SubSystem field in the optional header */ + fseek(ExeFile, -sizeof(unsigned short), SEEK_CUR); + + /* Write the new SubSystem value */ + fwrite(&NewSubSystem, sizeof(unsigned short), 1, ExeFile); + + /* Close the file */ + fclose(ExeFile); + + /* Finished successfully */ + printf("SubSystem successfully modified!\n"); + return 0; +}