mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-17 15:44:18 +08:00
pe: add dll characteristic linker options
Add PE linker switches to set and clear DYNAMIC_BASE, NX_COMPAT, HIGH_ENTROPY_VA and TERMINAL_SERVER_AWARE without changing x86/x64 defaults. HIGH_ENTROPY_VA is limited to 64-bit PE targets and implies DYNAMIC_BASE; clearing DYNAMIC_BASE also clears HIGH_ENTROPY_VA. When DYNAMIC_BASE is requested for an executable, emit base relocations and clear RELOCS_STRIPPED so Windows ASLR can relocate the image. Keep the existing ARM64 default hardening flags.
This commit is contained in:
parent
37b7247796
commit
1a54e47dda
40
libtcc.c
40
libtcc.c
@ -1406,6 +1406,20 @@ succ:
|
||||
|
||||
static void args_parser_add_file(TCCState *s, const char* filename, int filetype);
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
static void tcc_pe_set_dll_characteristics(TCCState *s, unsigned flags)
|
||||
{
|
||||
s->pe_dll_characteristics |= flags;
|
||||
s->pe_dll_characteristics_clear &= ~flags;
|
||||
}
|
||||
|
||||
static void tcc_pe_clear_dll_characteristics(TCCState *s, unsigned flags)
|
||||
{
|
||||
s->pe_dll_characteristics &= ~flags;
|
||||
s->pe_dll_characteristics_clear |= flags;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set linker options */
|
||||
static int tcc_set_linker(TCCState *s, const char *optarg)
|
||||
{
|
||||
@ -1475,7 +1489,31 @@ static int tcc_set_linker(TCCState *s, const char *optarg)
|
||||
s->znodelete = 1;
|
||||
#ifdef TCC_TARGET_PE
|
||||
} else if (link_option(&o, "large-address-aware")) {
|
||||
s->pe_characteristics |= 0x20;
|
||||
s->pe_characteristics |= PE_IMAGE_FILE_LARGE_ADDRESS_AWARE;
|
||||
} else if (link_option(&o, "dynamicbase")) {
|
||||
tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_DYNAMIC_BASE);
|
||||
} else if (link_option(&o, "disable-dynamicbase|no-dynamicbase")) {
|
||||
tcc_pe_clear_dll_characteristics(s,
|
||||
PE_DLLCHARACTERISTICS_DYNAMIC_BASE |
|
||||
PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA);
|
||||
} else if (link_option(&o, "nxcompat")) {
|
||||
tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_NX_COMPAT);
|
||||
} else if (link_option(&o, "disable-nxcompat|no-nxcompat")) {
|
||||
tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_NX_COMPAT);
|
||||
} else if (link_option(&o, "high-entropy-va")) {
|
||||
# if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
||||
tcc_pe_set_dll_characteristics(s,
|
||||
PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
|
||||
PE_DLLCHARACTERISTICS_DYNAMIC_BASE);
|
||||
# else
|
||||
goto err;
|
||||
# endif
|
||||
} else if (link_option(&o, "disable-high-entropy-va|no-high-entropy-va")) {
|
||||
tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA);
|
||||
} else if (link_option(&o, "tsaware")) {
|
||||
tcc_pe_set_dll_characteristics(s, PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE);
|
||||
} else if (link_option(&o, "disable-tsaware|no-tsaware")) {
|
||||
tcc_pe_clear_dll_characteristics(s, PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE);
|
||||
} else if (link_option(&o, "file-alignment=")) {
|
||||
s->pe_file_align = strtoul(o.arg, &end, 16);
|
||||
} else if (link_option(&o, "stack=")) {
|
||||
|
||||
@ -386,6 +386,15 @@ Set type for PE (Windows) executables.
|
||||
@item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]
|
||||
Modify executable layout.
|
||||
|
||||
@item -Wl,-[dynamicbase | nxcompat | high-entropy-va | tsaware]
|
||||
@item -Wl,-[no-dynamicbase | no-nxcompat | no-high-entropy-va | no-tsaware]
|
||||
@item -Wl,-[disable-dynamicbase | disable-nxcompat | disable-high-entropy-va | disable-tsaware]
|
||||
Set or clear PE (Windows) executable header hardening flags. The
|
||||
@option{-Wl,-high-entropy-va} option is supported on x86-64 and ARM64 PE
|
||||
targets and implies @option{-Wl,-dynamicbase}. Clearing dynamicbase also
|
||||
clears high-entropy-va. When @option{-Wl,-dynamicbase} is used for an
|
||||
executable, TCC also enables base relocation emission for Windows ASLR.
|
||||
|
||||
@item -Wl,-Bsymbolic
|
||||
Set DT_SYMBOLIC tag.
|
||||
|
||||
|
||||
11
tcc.h
11
tcc.h
@ -727,6 +727,15 @@ struct sym_attr {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
#define PE_IMAGE_FILE_RELOCS_STRIPPED 0x0001
|
||||
#define PE_IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
|
||||
#define PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020
|
||||
#define PE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
|
||||
#define PE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
|
||||
#define PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
|
||||
#endif
|
||||
|
||||
struct TCCState {
|
||||
unsigned char verbose; /* if true, display some information during compilation */
|
||||
unsigned char nostdinc; /* if true, no standard headers are added */
|
||||
@ -939,6 +948,8 @@ struct TCCState {
|
||||
/* PE info */
|
||||
int pe_subsystem;
|
||||
unsigned pe_characteristics;
|
||||
unsigned pe_dll_characteristics;
|
||||
unsigned pe_dll_characteristics_clear;
|
||||
unsigned pe_file_align;
|
||||
unsigned pe_stack_size;
|
||||
addr_t pe_imagebase;
|
||||
|
||||
40
tccpe.c
40
tccpe.c
@ -238,16 +238,16 @@ typedef struct _IMAGE_BASE_RELOCATION {
|
||||
#define IMAGE_SIZEOF_BASE_RELOCATION 8
|
||||
|
||||
#ifndef IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
|
||||
#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020
|
||||
#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
|
||||
#endif
|
||||
#ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
||||
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
|
||||
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE PE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
||||
#endif
|
||||
#ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT
|
||||
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
|
||||
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT PE_DLLCHARACTERISTICS_NX_COMPAT
|
||||
#endif
|
||||
#ifndef IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
|
||||
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
|
||||
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
|
||||
#endif
|
||||
|
||||
#define IMAGE_REL_BASED_ABSOLUTE 0
|
||||
@ -275,6 +275,21 @@ typedef struct _IMAGE_BASE_RELOCATION {
|
||||
#endif /* ndef IMAGE_NT_SIGNATURE */
|
||||
/* ----------------------------------------------------------- */
|
||||
|
||||
static WORD pe_get_dll_characteristics(TCCState *s1)
|
||||
{
|
||||
unsigned v = 0;
|
||||
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
v = PE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
|
||||
PE_DLLCHARACTERISTICS_DYNAMIC_BASE |
|
||||
PE_DLLCHARACTERISTICS_NX_COMPAT |
|
||||
PE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
|
||||
#endif
|
||||
v |= s1->pe_dll_characteristics;
|
||||
v &= ~s1->pe_dll_characteristics_clear;
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifndef IMAGE_FILE_MACHINE_ARM64
|
||||
#define IMAGE_FILE_MACHINE_ARM64 0xAA64
|
||||
#endif
|
||||
@ -725,14 +740,7 @@ static int pe_write(struct pe_info *pe)
|
||||
0x00000200, /*DWORD SizeOfHeaders; */
|
||||
0x00000000, /*DWORD CheckSum; */
|
||||
0x0002, /*WORD Subsystem; */
|
||||
#if defined(TCC_TARGET_ARM64)
|
||||
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
|
||||
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |
|
||||
IMAGE_DLLCHARACTERISTICS_NX_COMPAT |
|
||||
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE,
|
||||
#else
|
||||
0x0000, /*WORD DllCharacteristics; */
|
||||
#endif
|
||||
0x00100000, /*DWORD SizeOfStackReserve; */
|
||||
0x00001000, /*DWORD SizeOfStackCommit; */
|
||||
0x00100000, /*DWORD SizeOfHeapReserve; */
|
||||
@ -853,11 +861,14 @@ static int pe_write(struct pe_info *pe)
|
||||
pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
|
||||
pe_header.opthdr.ImageBase = pe->imagebase;
|
||||
pe_header.opthdr.Subsystem = pe->subsystem;
|
||||
pe_header.opthdr.DllCharacteristics = pe_get_dll_characteristics(s1);
|
||||
if (s1->pe_stack_size)
|
||||
pe_header.opthdr.SizeOfStackReserve = s1->pe_stack_size;
|
||||
if (PE_DLL == pe->type)
|
||||
pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
|
||||
pe_header.filehdr.Characteristics |= s1->pe_characteristics;
|
||||
if (pe->reloc)
|
||||
pe_header.filehdr.Characteristics &= ~PE_IMAGE_FILE_RELOCS_STRIPPED;
|
||||
|
||||
if (pe->coffsym) {
|
||||
pe_add_coffsym(pe);
|
||||
@ -1280,11 +1291,8 @@ static int pe_assign_addresses (struct pe_info *pe)
|
||||
Section *s;
|
||||
TCCState *s1 = pe->s1;
|
||||
|
||||
if (PE_DLL == pe->type
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
|| PE_EXE == pe->type || PE_GUI == pe->type
|
||||
#endif
|
||||
)
|
||||
if (PE_DLL == pe->type ||
|
||||
(pe_get_dll_characteristics(s1) & PE_DLLCHARACTERISTICS_DYNAMIC_BASE))
|
||||
pe->reloc = new_section(s1, ".reloc", SHT_PROGBITS, 0);
|
||||
//pe->thunk = new_section(s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user