X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=1.6 required=5.0 tests=AWL,BAYES_50,J_CHICKENPOX_13,J_CHICKENPOX_210,J_CHICKENPOX_23,J_CHICKENPOX_24,J_CHICKENPOX_25,J_CHICKENPOX_26,J_CHICKENPOX_27,J_CHICKENPOX_28,J_CHICKENPOX_29,J_CHICKENPOX_36,J_CHICKENPOX_74,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: sourceware.org Message-ID: <49AE191D.2000307@cwilson.fastmail.fm> Date: Wed, 04 Mar 2009 01:01:01 -0500 From: Charles Wilson User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.19) Gecko/20081209 Thunderbird/2.0.0.19 Mnenhy/0.7.6.666 MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: [1.7] rebaseall doesn't solve the problem References: <499F6682 DOT 1090204 AT cwilson DOT fastmail DOT fm> <20090224100616 DOT GC6035 AT calimero DOT vinschen DOT de> <49A85971 DOT 6070300 AT cwilson DOT fastmail DOT fm> <20090228104337 DOT GG19887 AT calimero DOT vinschen DOT de> <49A986B4 DOT 2080501 AT cwilson DOT fastmail DOT fm> <20090228201625 DOT GA8503 AT calimero DOT vinschen DOT de> <49A9AA0C DOT 9020904 AT cwilson DOT fastmail DOT fm> <20090301102035 DOT GB10046 AT calimero DOT vinschen DOT de> <49AE18D8 DOT 3010009 AT cwilson DOT fastmail DOT fm> In-Reply-To: <49AE18D8.3010009@cwilson.fastmail.fm> Content-Type: multipart/mixed; boundary="------------010900040303050304040906" Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com --------------010900040303050304040906 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Charles Wilson wrote: > Corinna Vinschen wrote: > >> Can you tweak the tool so I can test that next week? > > Attached, It helps when you actually attach the file. -- Chuck --------------010900040303050304040906 Content-Type: text/plain; name="peflags.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="peflags.c" /* * Copyright (c) 2009 Charles Wilson * Based on rebase.c by Jason Tishler * Significant contributions by Dave Korn * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * A copy of the GNU General Public License can be found at * http://www.gnu.org/ */ #include #include #include #include #include #include #include #include #include #include #include typedef struct { const char *name; int len; int value; } definfoflag; #define C(name) { #name, sizeof(#name) - 1, name } #define CF(name,flag) { #name, sizeof(#name) - 1, flag } static const definfoflag dllchrctnames[] = { /* Accept a few handy abbreviations. */ CF(dynbase, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE), CF(forceinteg, IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY), CF(nxcompat, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT), CF(noisolation, IMAGE_DLLCHARACTERISTICS_NO_ISOLATION), CF(noseh, IMAGE_DLLCHARACTERISTICS_NO_SEH), CF(nobind, IMAGE_DLLCHARACTERISTICS_NO_BIND), CF(wdmdriver, IMAGE_DLLCHARACTERISTICS_WDM_DRIVER), CF(tsaware, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE), /* And the full names as defined in the PE specification. */ C(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE), C(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY), C(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT), C(IMAGE_DLLCHARACTERISTICS_NO_ISOLATION), C(IMAGE_DLLCHARACTERISTICS_NO_SEH), C(IMAGE_DLLCHARACTERISTICS_WDM_DRIVER), C(IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE), { 0, 0, 0 }, }; static const definfoflag imgfilechrctnames[] = { /* Accept a few handy abbreviations. */ CF(wstrim, IMAGE_FILE_AGGRESIVE_WS_TRIM), CF(bigaddr, IMAGE_FILE_LARGE_ADDRESS_AWARE), CF(sepdbg, IMAGE_FILE_DEBUG_STRIPPED), /* debug info in separate .dbg file */ /* And the full names as defined in the PE specification. */ C(IMAGE_FILE_RELOCS_STRIPPED), C(IMAGE_FILE_EXECUTABLE_IMAGE), C(IMAGE_FILE_LINE_NUMS_STRIPPED), C(IMAGE_FILE_LOCAL_SYMS_STRIPPED), C(IMAGE_FILE_AGGRESIVE_WS_TRIM), C(IMAGE_FILE_LARGE_ADDRESS_AWARE), C(IMAGE_FILE_BYTES_REVERSED_LO), C(IMAGE_FILE_32BIT_MACHINE), C(IMAGE_FILE_DEBUG_STRIPPED), C(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP), C(IMAGE_FILE_NET_RUN_FROM_SWAP), C(IMAGE_FILE_SYSTEM), C(IMAGE_FILE_DLL), C(IMAGE_FILE_UP_SYSTEM_ONLY), C(IMAGE_FILE_BYTES_REVERSED_HI), { 0, 0, 0 }, }; typedef struct { void *ptr; int size; int value; char *symbol; int inited; const definfoflag *flagnames; } definfo; #define D(var,symbol,def) {&var,sizeof(var), def, symbol, 0, 0} #define DF(var,symbol,def,flags) {&var,sizeof(var), def, symbol, 0, flags} #define DEFAULT_SHOW_DLL_CHARACTERISTICS IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE |\ IMAGE_DLL_CHARACTERISTICS_NX_COMPAT |\ IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE #define DEFAULT_SHOW_IMG_CHARACTERISTICS 0x0 static uint16_t ImgFileCharacteristicsSET; static uint16_t ImgFileCharacteristicsCLR; static uint16_t ImgFileCharacteristicsSHOW; static uint16_t DllCharacteristicsSET; static uint16_t DllCharacteristicsCLR; static uint16_t DllCharacteristicsSHOW; #define SHOWSTR "show__" static definfo init[] = { DF(ImgFileCharacteristicsSET, "__img_file_characteristics_set__", 0x0, imgfilechrctnames), DF(ImgFileCharacteristicsCLR, "__img_file_characteristics_clr__", 0x0, imgfilechrctnames), DF(ImgFileCharacteristicsSHOW, "__img_file_characteristics_" SHOWSTR, DEFAULT_SHOW_IMG_CHARACTERISTICS, imgfilechrctnames), DF(DllCharacteristicsSET, "__dll_characteristics_set__", 0x0, dllchrctnames), DF(DllCharacteristicsCLR, "__dll_characteristics_clr__", 0x0, dllchrctnames), DF(DllCharacteristicsSHOW, "__dll_characteristics_" SHOWSTR, DEFAULT_SHOW_DLL_CHARACTERISTICS, dllchrctnames), { NULL, 0, 0, NULL, 0, 0 } }; #define OPTION_SET_IMAGE_FILE_CHARACTERISTICS 150 #define OPTION_CLR_IMAGE_FILE_CHARACTERISTICS OPTION_SET_IMAGE_FILE_CHARACTERISTICS+1 #define OPTION_SHOW_IMAGE_FILE_CHARACTERISTICS OPTION_CLR_IMAGE_FILE_CHARACTERISTICS+1 #define OPTION_SET_DLL_CHARACTERISTICS OPTION_SHOW_IMAGE_FILE_CHARACTERISTICS+1 #define OPTION_CLR_DLL_CHARACTERISTICS OPTION_SET_DLL_CHARACTERISTICS+1 #define OPTION_SHOW_DLL_CHARACTERISTICS OPTION_CLR_DLL_CHARACTERISTICS+1 #define OPTION_FLAG_HELP OPTION_SHOW_DLL_CHARACTERISTICS+1 static struct option long_options[] = { {"dynbase", required_argument, NULL, 'd'}, {"tsaware", required_argument, NULL, 't'}, {"nxcompat", required_argument, NULL, 'n'}, {"filelist", required_argument, NULL, 'T'}, {"set-image-characteristics", required_argument, NULL, OPTION_SET_IMAGE_FILE_CHARACTERISTICS}, {"clr-image-characteristics", required_argument, NULL, OPTION_CLR_IMAGE_FILE_CHARACTERISTICS}, {"show-image-characteristics", required_argument, NULL, OPTION_SHOW_IMAGE_FILE_CHARACTERISTICS}, {"set-dll-characteristics", required_argument, NULL, OPTION_SET_DLL_CHARACTERISTICS}, {"clr-dll-characteristics", required_argument, NULL, OPTION_CLR_DLL_CHARACTERISTICS}, {"show-dll-characteristics", required_argument, NULL, OPTION_SHOW_DLL_CHARACTERISTICS}, {"flag-help", no_argument, NULL, OPTION_FLAG_HELP}, {"verbose", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {NULL, no_argument, NULL, 0} }; static const definfoflag *find_pe_flag_name (const char *name, const definfoflag *flagnames); static definfo *find_pe_name (const char *name); static void set_pe_name (const char *name, long val); static void set_pe_by_flagname (const char *name, const char *flagname); static char is_flag_sep (char x); static void set_pe_value_from_flags (const char *name); static void short_usage (FILE *f); static void help (FILE *f); static void help_flags (FILE *f); static void version (FILE *f); int do_mark (const char *pathname); int get_characteristics(const char *pathname, uint16_t* pe_img_file_characteristics, uint16_t* pe_dll_characteristics); int set_pe_img_file_characteristics(const char *pathname, uint16_t pe_img_file_characteristics); int set_pe_dll_characteristics(const char *pathname, uint16_t pe_dll_characteristics); static int pe_get16 (int fd, off_t offset, uint16_t* value); static int pe_get32 (int fd, off_t offset, uint32_t* value); static int pe_set16 (int fd, off_t offset, uint16_t value); static char *symbolic (long flags, const char *name); static void append_and_decorate (char **str, int is_set, const char *name, int len); static int strendswith (const char *str, const char *prefix); static void *xmalloc (size_t num); #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) void parse_args (int argc, char *argv[]); int string_to_bool (const char *string, int *value); int string_to_ulong (const char *string, unsigned long *value); FILE *file_list_fopen (const char *file_list); char *file_list_fgets (char *buf, int size, FILE *file); int file_list_fclose (FILE *file); int args_index = 0; int verbose = 0; const char *file_list = 0; const char *stdin_file_list = "-"; int main (int argc, char *argv[]) { int i = 0; parse_args (argc, argv); /* Operate on files in file list, if specified. */ if (file_list) { int status = 0; char filename[MAX_PATH + 2]; FILE *file = file_list_fopen (file_list); if (!file) exit (2); while (file_list_fgets (filename, MAX_PATH + 2, file)) { if ((status = do_mark (filename)) != 0) break; } file_list_fclose (file); if (status != 0) exit (2); } /* Operate on files listed as command line arguments. */ for (i = args_index; i < argc; i++) { const char *filename = argv[i]; if (do_mark (filename) != 0) exit (2); } exit (0); } int do_mark (const char *pathname) { int mark_any = FALSE; int has_relocs; int is_executable; int is_dll; uint16_t old_img_characteristics; uint16_t new_img_characteristics; uint16_t old_dll_characteristics; uint16_t new_dll_characteristics; int i; /* Skip if file does not exist */ if (access (pathname, F_OK) == -1) { fprintf (stderr, "%s: skipped because nonexistent\n", pathname); return 0; } /* determine if we are actually to write anything. Skip entries in init[] that are display oriented */ for (i = 0; init[i].ptr; i++) if (!strendswith (init[i].symbol, SHOWSTR)) mark_any |= init[i].inited; if (mark_any) { /* Skip if not writable. */ if (access (pathname, W_OK) == -1) { fprintf (stderr, "%s: skipped because not writable\n", pathname); return 0; } } if (get_characteristics (pathname, &old_img_characteristics, &old_dll_characteristics) != 0) { fprintf (stderr, "%s: skipped because could not read file characteristics\n", pathname); return 0; } new_img_characteristics = old_img_characteristics; new_img_characteristics |= ImgFileCharacteristicsSET; new_img_characteristics &= ~ImgFileCharacteristicsCLR; new_dll_characteristics = old_dll_characteristics; new_dll_characteristics |= DllCharacteristicsSET; new_dll_characteristics &= ~DllCharacteristicsCLR; is_executable = ((new_img_characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) > 0); is_dll = ((new_img_characteristics & IMAGE_FILE_DLL) > 0); has_relocs = ((new_img_characteristics & IMAGE_FILE_RELOCS_STRIPPED) == 0); /* validation and warnings about things that are problematic, but that we are not explicitly changing */ if (!has_relocs) { if (verbose && (new_dll_characteristics & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE) && (old_dll_characteristics & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE)) { fprintf (stderr, "Warning: file has no relocation info but has dynbase set (%s).\n", pathname); } } if (!is_executable || is_dll) { if (verbose && (new_dll_characteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) && (old_dll_characteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE)) { fprintf (stderr, "Warning: file is non-executable but has tsaware set (%s).\n", pathname); } } if (mark_any) { /* validation and warnings about things we are changing */ if (!has_relocs) { if ( (new_dll_characteristics & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE) && !(old_dll_characteristics & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE)) { fprintf (stderr, "Warning: setting dynbase on file with no relocation info (%s).\n", pathname); } } if (!is_executable || is_dll) { if ( (new_dll_characteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) && !(old_dll_characteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE)) { fprintf (stderr, "Warning: setting tsaware on non-executable (%s).\n", pathname); } } /* setting */ if (new_img_characteristics != old_img_characteristics) if (set_pe_img_file_characteristics (pathname, new_img_characteristics) != 0) { fprintf (stderr, "Error: could not update image file characteristics (%s)\n", pathname); return 1; } if (new_dll_characteristics != old_dll_characteristics) if (set_pe_dll_characteristics (pathname, new_dll_characteristics) != 0) { fprintf (stderr, "Error: could not update dll characteristics (%s)\n", pathname); return 1; } } /* Display image characteristics. */ if (verbose || !mark_any) { printf ("%s: ", pathname); if (ImgFileCharacteristicsSHOW) { if (old_img_characteristics != new_img_characteristics) { char * oldImgSymbolic = symbolic(old_img_characteristics,"__img_file_characteristics_" SHOWSTR); char * newImgSymbolic = symbolic(new_img_characteristics,"__img_file_characteristics_" SHOWSTR); printf ("image-characteristics(0x%04x%s==>0x%04x%s) ", old_img_characteristics,oldImgSymbolic, new_img_characteristics,newImgSymbolic); free (oldImgSymbolic); free (newImgSymbolic); } else { char * oldImgSymbolic = symbolic(old_img_characteristics,"__img_file_characteristics_" SHOWSTR); printf ("image-characteristics(0x%04x%s) ", old_img_characteristics,oldImgSymbolic); free (oldImgSymbolic); } } else { if (old_img_characteristics != new_img_characteristics) printf ("image-characteristics(0x%04x==>0x%04x) ", old_img_characteristics, new_img_characteristics); else printf ("image-characteristics(0x%04x) ", old_img_characteristics); } if (DllCharacteristicsSHOW) { if (old_dll_characteristics != new_dll_characteristics) { char * oldDllSymbolic = symbolic(old_dll_characteristics,"__dll_characteristics_" SHOWSTR); char * newDllSymbolic = symbolic(new_dll_characteristics,"__dll_characteristics_" SHOWSTR); printf ("dll-characteristics(0x%04x%s==>0x%04x%s) ", old_dll_characteristics,oldDllSymbolic, new_dll_characteristics,newDllSymbolic); free (oldDllSymbolic); free (newDllSymbolic); } else { char * oldDllSymbolic = symbolic(old_dll_characteristics,"__dll_characteristics_" SHOWSTR); printf ("dll-characteristics(0x%04x%s) ", old_dll_characteristics,oldDllSymbolic); free (oldDllSymbolic); } } else { if (old_dll_characteristics != new_dll_characteristics) printf ("dll-characteristics(0x%04x==>0x%04x) ", old_dll_characteristics, new_dll_characteristics); else printf ("dll-characteristics(0x%04x) ", old_dll_characteristics); } } return 0; } static char * symbolic (long flags, const char *name) { int i; long already_marked = 0; definfo *someVar = find_pe_name (name); char * rVal = NULL; for (i = 0; someVar->flagnames[i].name; i++) { if (someVar->value & someVar->flagnames[i].value & ~already_marked) { append_and_decorate (&rVal, (flags & someVar->flagnames[i].value), someVar->flagnames[i].name, someVar->flagnames[i].len); already_marked |= someVar->flagnames[i].value; } } if (rVal) { size_t len = strlen (rVal); char *tmp = XMALLOC (char, len + 3); *tmp = '['; memcpy (tmp+1, rVal, len); tmp[len+1] = ']'; tmp[len+2] = '\0'; free (rVal); rVal = tmp; } return rVal; } static void append_and_decorate (char **str, int is_set, const char *name, int len) { char *tmp; int slen; if (!*str) { *str = XMALLOC (char, len + 2); (*str)[0] = (is_set ? '+' : '-'); memcpy ((*str)+1, name, len); (*str)[len+1] = '\0'; return; } else { slen = strlen (*str); tmp = XMALLOC (char, slen + 2 + len + 1); memcpy (tmp, *str, slen); free (*str); *str = tmp; tmp = *str + slen; *tmp++ = ','; *tmp++ = (is_set ? '+' : '-'); memcpy (tmp, name, len); tmp[len] = '\0'; } } static void * xmalloc (size_t num) { void *p = (void *) malloc (num); if (!p) { fputs ("Memory exhausted", stderr); exit (2); } return p; } static int strendswith (const char *str, const char *prefix) { size_t slen = strlen (str); size_t plen = strlen (prefix); if (slen < plen) return 0; return (strncmp (str + (slen - plen), prefix, plen) == 0); } void parse_args (int argc, char *argv[]) { int c; int bool_value; while (1) { int option_index = 0; c = getopt_long (argc, argv, "d:t:n:T:vhV", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': help (stdout); exit (0); break; case 'V': version (stdout); exit (0); break; case OPTION_FLAG_HELP: help_flags (stdout); exit (0); break; case 'd': if (string_to_bool (optarg, &bool_value) != 0) { fprintf (stderr, "Invalid argument for %s: %s\n", long_options[option_index].name, optarg); short_usage (stderr); exit (1); } if (bool_value) set_pe_by_flagname ("__dll_characteristics_set__", "dynbase"); else set_pe_by_flagname ("__dll_characteristics_clr__", "dynbase"); break; case 'n': if (string_to_bool (optarg, &bool_value) != 0) { fprintf (stderr, "Invalid argument for %s: %s\n", long_options[option_index].name, optarg); short_usage (stderr); exit (1); } if (bool_value) set_pe_by_flagname ("__dll_characteristics_set__", "nxcompat"); else set_pe_by_flagname ("__dll_characteristics_clr__", "nxcompat"); break; case 't': if (string_to_bool (optarg, &bool_value) != 0) { fprintf (stderr, "Invalid argument for %s: %s\n", long_options[option_index].name, optarg); short_usage (stderr); exit (1); } if (bool_value) set_pe_by_flagname ("__dll_characteristics_set__", "tsaware"); else set_pe_by_flagname ("__dll_characteristics_clr__", "tsaware"); break; case 'T': file_list = optarg; break; case 'v': verbose = TRUE; break; case OPTION_SET_IMAGE_FILE_CHARACTERISTICS: set_pe_value_from_flags ("__img_file_characteristics_set__"); break; case OPTION_CLR_IMAGE_FILE_CHARACTERISTICS: set_pe_value_from_flags ("__img_file_characteristics_clr__"); break; case OPTION_SHOW_IMAGE_FILE_CHARACTERISTICS: set_pe_value_from_flags ("__img_file_characteristics_" SHOWSTR); break; case OPTION_SET_DLL_CHARACTERISTICS: set_pe_value_from_flags ("__dll_characteristics_set__"); break; case OPTION_CLR_DLL_CHARACTERISTICS: set_pe_value_from_flags ("__dll_characteristics_clr__"); break; case OPTION_SHOW_DLL_CHARACTERISTICS: set_pe_value_from_flags ("__dll_characteristics_" SHOWSTR); break; case '?': break; default: short_usage (stderr); exit (1); break; } } args_index = optind; /* now, iterate thru init[] and apply the accumulated values to the global variables */ for (c = 0; init[c].ptr; c++) { long val = init[c].value; if (init[c].size == sizeof (short)) *(short *) init[c].ptr = val; else if (init[c].size == sizeof (int)) *(int *) init[c].ptr = val; else if (init[c].size == sizeof (long)) *(long *) init[c].ptr = val; else abort (); } } int string_to_bool (const char *string, int *value) { unsigned long number = 0; if (!string || !*string) return 1; if (string_to_ulong (string, &number) != 0) { size_t len = strlen (string); if ( (len == 4 && strcasecmp (string, "true") == 0) ||(len == 3 && strcasecmp (string, "yes") == 0) ||(len == 1 && strcasecmp (string, "t") == 0) ||(len == 1 && strcasecmp (string, "y") == 0)) { *value = TRUE; } else if ( (len == 5 && strcasecmp (string, "false") == 0) ||(len == 2 && strcasecmp (string, "no") == 0) ||(len == 1 && strcasecmp (string, "f") == 0) ||(len == 1 && strcasecmp (string, "n") == 0)) { *value = FALSE; } else { return 1; } } else { *value = (number != 0); } return 0; } int string_to_ulong (const char *string, unsigned long *value) { unsigned long number = 0; char * endp; errno = 0; /* null or empty input */ if (!string || !*string) return 1; number = strtoul (string, &endp, 0); /* out of range */ if (ERANGE == errno) return 1; /* no valid numeric input */ if (endp == string) return 1; /* non-numeric trailing characters */ if (*endp != '\0') return 1; *value = number; return 0; } int get_characteristics(const char *pathname, uint16_t* pe_img_file_characteristics, uint16_t* pe_dll_characteristics) { uint32_t pe_header_offset, opthdr_ofs; int status = 1; int fd, size; uint32_t pe_sig; fd = open (pathname, O_RDONLY|O_BINARY); if (fd == -1) goto done; if (pe_get32 (fd, 0x3c, &pe_header_offset) != 0) goto done; opthdr_ofs = pe_header_offset + 4 + 20; pe_sig = 0; if (pe_get32 (fd, pe_header_offset, &pe_sig) != 0) goto done; if (pe_sig != IMAGE_NT_SIGNATURE) goto done; if (pe_get16 (fd, pe_header_offset + 4 + 18, pe_img_file_characteristics) != 0) goto done; if (pe_get16 (fd, opthdr_ofs + 70, pe_dll_characteristics) != 0) goto done; status = 0; done: close (fd); return status; } int set_pe_img_file_characteristics(const char *pathname, uint16_t pe_img_file_characteristics) { uint32_t pe_header_offset; int status = 1; int fd, size; /* no extra checking of file's contents below, because get_characteristics already did that */ fd = open (pathname, O_RDWR|O_BINARY); if (fd == -1) goto done; if (pe_get32 (fd, 0x3c, &pe_header_offset) != 0) goto done; if (pe_set16 (fd, pe_header_offset + 4 + 18, pe_img_file_characteristics) != 0) { fprintf (stderr, "CATASTROPIC ERROR: attempt to write to file failed! %s could be corrupted; HALTING.\n", pathname); close (fd); exit(2); } status = 0; done: close (fd); return status; } int set_pe_dll_characteristics(const char *pathname, uint16_t pe_dll_characteristics) { uint32_t pe_header_offset, opthdr_ofs; int status = 1; int fd, size; /* no extra checking of file's contents below, because get_characteristics already did that */ fd = open (pathname, O_RDWR|O_BINARY); if (fd == -1) goto done; if (pe_get32 (fd, 0x3c, &pe_header_offset) != 0) goto done; opthdr_ofs = pe_header_offset + 4 + 20; if (pe_set16 (fd, opthdr_ofs + 70, pe_dll_characteristics) != 0) { fprintf (stderr, "CATASTROPIC ERROR: attempt to write to file failed! %s could be corrupted; HALTING.\n", pathname); close (fd); exit(2); } status = 0; done: close (fd); return status; } static int pe_get16 (int fd, off_t offset, uint16_t* value) { unsigned char b[2]; if (lseek (fd, offset, SEEK_SET) == -1) return 1; if (read (fd, b, 2) != 2) return 1; *value = b[0] + (b[1]<<8); return 0; } static int pe_get32 (int fd, off_t offset, uint32_t* value) { unsigned char b[4]; if (lseek (fd, offset, SEEK_SET) == -1) return 1; if (read (fd, b, 4) != 4) return 1; *value = b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); return 0; } static int pe_set16 (int fd, off_t offset, uint16_t value) { unsigned char b[2]; b[0] = (unsigned char) (value & 0x00ff); b[1] = (unsigned char) ((value>>8) & 0x00ff); if (lseek (fd, offset, SEEK_SET) == -1) return 1; if (write (fd, b, 2) != 2) return 1; return 0; } FILE * file_list_fopen (const char *file_list) { FILE *file = stdin; if (strcmp(file_list, stdin_file_list) != 0) { file = fopen (file_list, "r"); if (!file) fprintf (stderr, "cannot read %s\n", file_list); } return file; } char * file_list_fgets (char *buf, int size, FILE *file) { char *status = fgets (buf, size, file); if (status) { size_t length = strlen (buf); if (buf[length - 1] == '\n') buf[length - 1] = '\0'; } return status; } int file_list_fclose (FILE *file) { int status = 0; if (strcmp(file_list, stdin_file_list) != 0) status = fclose (file); return status; } static const definfoflag * find_pe_flag_name (const char *name, const definfoflag *flagnames) { int i; /* Look for the name, return pointer to definfoflag if found. */ for (i = 0; flagnames[i].name; i++) if (strncmp (name, flagnames[i].name, flagnames[i].len) == 0) return &flagnames[i]; /* Unknown name could be an integer, so not an error here. */ return 0; } static definfo * find_pe_name (const char *name) { int i; /* Look for the name, return pointer to definfo. */ for (i = 0; init[i].ptr; i++) if (strcmp (name, init[i].symbol) == 0) return &init[i]; /* Unknown name is a serious internal coding error, so don't bother to diagnose or return error indication, just bail. */ abort (); } static void set_pe_by_flagname (const char *name, const char *flagname) { long flags = 0; const definfoflag *flag; definfo *someVar = find_pe_name (name); flag = find_pe_flag_name (flagname, someVar->flagnames); if (flag) flags |= flag->value; else fprintf (stderr, "Error: unrecognised integer/flag '%s' for PE parameter '%s'\n", optarg, name); if (someVar->inited) someVar->value |= flags; else { someVar->value = flags; someVar->inited = 1; } } static void set_pe_name (const char *name, long val) { /* Find the name and set it. */ definfo *someVar = find_pe_name (name); someVar->value = val; someVar->inited = 1; } static char is_flag_sep (char x) { return x == '+' || x == '|' || x == ':' || x == ','; } static void set_pe_value_from_flags (const char *name) { long flags = 0; definfo *someVar; /* Look up the symbolic flag names. Even if there aren't any we will still parse multiple integers combined by separators. */ someVar = find_pe_name (name); /* Parse the flags out of optarg. We accept any combination of symbolic abbreviations and strtoul-parseable integers, separated by any combination of '+', '|', ':' and ',' characters. */ while (*optarg) { const definfoflag *flag; /* Deliberately allow multiple conjoined separators. */ while (is_flag_sep (*optarg)) optarg++; /* Even trailing at the end. */ if (!*optarg) break; flag = find_pe_flag_name (optarg, someVar->flagnames); if (flag) { flags |= flag->value; optarg += flag->len; } else { char *end; long value; value = strtoul (optarg, &end, 0); if (end == optarg) fprintf (stderr, "Error: unrecognised integer/flag '%s' for PE parameter '%s'\n", optarg, name); flags |= value; optarg = end; } /* If there's any more, we do insist on at least one separator. */ if (*optarg && !is_flag_sep (*optarg)) fprintf (stderr, "Error: unparseable at '%s' for PE parameter '%s'\n", optarg, name); } set_pe_name (name, flags); } static void short_usage (FILE *f) { fputs ("Usage: peflags [OPTIONS] file...\n", f); fputs ("Sets or clears various flags in PE files (that is, exes and dlls)\n", f); fputs ("Use --help for full help text\n", f); } static void help (FILE *f) { fputs ("Usage: peflags [OPTIONS] file...\n", f); fputs ("Sets or clears various flags in PE files (that is, exes and dlls)\n", f); fputs (" -d, --dynbase=BOOL Sets or clears the dynbase flag\n", f); fputs (" -t, --tsaware=BOOL Sets or clears the tsaware flag\n", f); fputs (" -n, --nxcompat=BOOL Sets or clears the nxcompat flag\n", f); fputs (" --set-image-characteristics=SPECSTR Set or clear various flags in the\n", f); fputs (" --clr-image-characteristics=SPECSTR 'Characteristics' field of the PE\n", f); fputs (" --show-image-characteristics=SPECSTR file's ImageFileHeader. See winnt.h\n", f); fputs (" for possible values. The --show-*h\n", f); fputs (" option indicates which flags to\n", f); fputs (" display symbolically.n", f); fputs (" --set-dll-characteristics=SPECSTR Set or clear various flags in the\n", f); fputs (" --clr-dll-characteristics=SPECSTR 'DllCharacteristics' field of the\n", f); fputs (" --show-dll-characteristics=SPECSTR PE file's ImageOptionalHeader. See\n", f); fputs (" winnt.h for possible values; this\n", f); fputs (" field is not only for DLLs\n", f); fputs (" -T, --filelist FILE Indicate that FILE contains a list\n", f); fputs (" of PE files to process\n", f); fputs (" --verbose display diagnostic information\n", f); fputs (" -V, --version display version information\n", f); fputs (" -h, --help display this help\n", f); fputs (" --flag-help display all symbolic flag names\n", f); fputs ("\n", f); fputs ("BOOL: may be 1, true, or yes - indicates that the flag should be set\n", f); fputs (" if 0, false, or no - indicates that the flag should be cleared\n", f); fputs ("\n", f); fputs ("SPECSTR: |[(+|,:)|[...]]\n", f); fputs (" where is one of several known symbolic names (see --flag-help)\n", f); fputs (" and any of +|;: may be used to join multiple values in a single option\n", f); } static void help_flags (FILE *f) { int i; fputs ("Flag help: peflags [OPTIONS] file...\n", f); fputs ("The --set-* and --clr-* options accept as an argument a specification\n", f); fputs ("string of the following form:\n", f); fputs (" |[(+|,:)|[...]]\n", f); fputs ("That is, flag values may be expressed using a combination of numeric\n", f); fputs ("values and symbolic names. For example:\n", f); fputs (" --set-dll-characteristics=0x0400|0x0100\n", f); fputs (" --set-dll-characteristics=1+128+1024,noseh,nobind\n", f); fputs (" --set-dll-characteristics=noseh:nobind:tsaware\n", f); fputs ("There are a number of these symbolic names, which are listed below\n", f); fputs (" --[set|clr|show]-dll-characteristics:\n", f); /* Loop over symbolic names */ for (i = 0; dllchrctnames[i].name; i++) fprintf (f, " %s\n", dllchrctnames[i].name); fputs (" --[set|clr|show]-image-characteristics:\n", f); /* Loop over symbolic names */ for (i = 0; imgfilechrctnames[i].name; i++) fprintf (f, " %s\n", imgfilechrctnames[i].name); } static void version (FILE *f) { fprintf (f, "peflags version %s\n", VERSION); fprintf (f, "Copyright (c) 2009 Charles Wilson, Dave Korn, Jason Tishler\n"); } --------------010900040303050304040906 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --------------010900040303050304040906--