1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/cmd/shlibsign/mangle/mangle.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,141 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 + * Test program to mangle 1 bit in a binary 1.10 + */ 1.11 + 1.12 +#include "nspr.h" 1.13 +#include "plstr.h" 1.14 +#include "plgetopt.h" 1.15 +#include "prio.h" 1.16 + 1.17 +static PRFileDesc *pr_stderr; 1.18 +static void 1.19 +usage (char *program_name) 1.20 +{ 1.21 + 1.22 + PR_fprintf (pr_stderr, "Usage:"); 1.23 + PR_fprintf (pr_stderr, "%s -i shared_library_name -o byte_offset -b bit\n", program_name); 1.24 +} 1.25 + 1.26 + 1.27 +int 1.28 +main (int argc, char **argv) 1.29 +{ 1.30 + /* buffers and locals */ 1.31 + PLOptState *optstate; 1.32 + char *programName; 1.33 + char cbuf; 1.34 + 1.35 + /* parameter set variables */ 1.36 + const char *libFile = NULL; 1.37 + int bitOffset = -1; 1.38 + 1.39 + /* return values */ 1.40 + int retval = 2; /* 0 - test succeeded. 1.41 + * 1 - illegal args 1.42 + * 2 - function failed */ 1.43 + PRFileDesc *fd = NULL; 1.44 + int bytesRead; 1.45 + int bytesWritten; 1.46 + PROffset32 offset = -1; 1.47 + PROffset32 pos; 1.48 + 1.49 + programName = PL_strrchr(argv[0], '/'); 1.50 + programName = programName ? (programName + 1) : argv[0]; 1.51 + 1.52 + pr_stderr = PR_STDERR; 1.53 + 1.54 + optstate = PL_CreateOptState (argc, argv, "i:o:b:"); 1.55 + if (optstate == NULL) { 1.56 + return 1; 1.57 + } 1.58 + 1.59 + while (PL_GetNextOpt (optstate) == PL_OPT_OK) { 1.60 + switch (optstate->option) { 1.61 + case 'i': 1.62 + libFile = optstate->value; 1.63 + break; 1.64 + 1.65 + case 'o': 1.66 + offset = atoi(optstate->value); 1.67 + break; 1.68 + 1.69 + case 'b': 1.70 + bitOffset = atoi(optstate->value); 1.71 + break; 1.72 + } 1.73 + } 1.74 + 1.75 + if (libFile == NULL) { 1.76 + usage(programName); 1.77 + return 1; 1.78 + } 1.79 + if ((bitOffset >= 8) || (bitOffset < 0)) { 1.80 + usage(programName); 1.81 + return 1; 1.82 + } 1.83 + 1.84 + /* open the target signature file */ 1.85 + fd = PR_OpenFile(libFile,PR_RDWR,0666); 1.86 + if (fd == NULL ) { 1.87 + /* lperror(libFile); */ 1.88 + PR_fprintf(pr_stderr,"Couldn't Open %s\n",libFile); 1.89 + goto loser; 1.90 + } 1.91 + 1.92 + if (offset < 0) { /* convert to positive offset */ 1.93 + pos = PR_Seek(fd, offset, PR_SEEK_END); 1.94 + if (pos == -1) { 1.95 + PR_fprintf(pr_stderr,"Seek for read on %s (to %d) failed\n", 1.96 + libFile, offset); 1.97 + goto loser; 1.98 + } 1.99 + offset = pos; 1.100 + } 1.101 + 1.102 + /* read the byte */ 1.103 + pos = PR_Seek(fd, offset, PR_SEEK_SET); 1.104 + if (pos != offset) { 1.105 + PR_fprintf(pr_stderr,"Seek for read on %s (to %d) failed\n", 1.106 + libFile, offset); 1.107 + goto loser; 1.108 + } 1.109 + bytesRead = PR_Read(fd, &cbuf, 1); 1.110 + if (bytesRead != 1) { 1.111 + PR_fprintf(pr_stderr,"Read on %s (to %d) failed\n", libFile, offset); 1.112 + goto loser; 1.113 + } 1.114 + 1.115 + PR_fprintf(pr_stderr,"Changing byte 0x%08x (%d): from %02x (%d) to ", 1.116 + offset, offset, (unsigned char)cbuf, (unsigned char)cbuf); 1.117 + /* change it */ 1.118 + cbuf ^= 1 << bitOffset; 1.119 + PR_fprintf(pr_stderr,"%02x (%d)\n", 1.120 + (unsigned char)cbuf, (unsigned char)cbuf); 1.121 + 1.122 + /* write it back out */ 1.123 + pos = PR_Seek(fd, offset, PR_SEEK_SET); 1.124 + if (pos != offset) { 1.125 + PR_fprintf(pr_stderr,"Seek for write on %s (to %d) failed\n", 1.126 + libFile, offset); 1.127 + goto loser; 1.128 + } 1.129 + bytesWritten = PR_Write(fd, &cbuf, 1); 1.130 + if (bytesWritten != 1) { 1.131 + PR_fprintf(pr_stderr,"Write on %s (to %d) failed\n", libFile, offset); 1.132 + goto loser; 1.133 + } 1.134 + 1.135 + retval = 0; 1.136 + 1.137 +loser: 1.138 + if (fd) 1.139 + PR_Close(fd); 1.140 + PR_Cleanup (); 1.141 + return retval; 1.142 +} 1.143 + 1.144 +/*#DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" */