mangle.c (3656B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /* 6 * Test program to mangle 1 bit in a binary 7 */ 8 9 #include "nspr.h" 10 #include "plstr.h" 11 #include "plgetopt.h" 12 #include "prio.h" 13 14 static PRFileDesc *pr_stderr; 15 static void 16 usage(char *program_name) 17 { 18 19 PR_fprintf(pr_stderr, "Usage:"); 20 PR_fprintf(pr_stderr, "%s -i shared_library_name -o byte_offset -b bit\n", program_name); 21 } 22 23 int 24 main(int argc, char **argv) 25 { 26 /* buffers and locals */ 27 PLOptState *optstate; 28 char *programName; 29 char cbuf; 30 31 /* parameter set variables */ 32 const char *libFile = NULL; 33 int bitOffset = -1; 34 35 /* return values */ 36 int retval = 2; /* 0 - test succeeded. 37 * 1 - illegal args 38 * 2 - function failed */ 39 PRFileDesc *fd = NULL; 40 int bytesRead; 41 int bytesWritten; 42 PROffset32 offset = -1; 43 PROffset32 pos; 44 45 programName = PL_strrchr(argv[0], '/'); 46 programName = programName ? (programName + 1) : argv[0]; 47 48 pr_stderr = PR_STDERR; 49 50 optstate = PL_CreateOptState(argc, argv, "i:o:b:"); 51 if (optstate == NULL) { 52 return 1; 53 } 54 55 while (PL_GetNextOpt(optstate) == PL_OPT_OK) { 56 switch (optstate->option) { 57 case 'i': 58 libFile = optstate->value; 59 break; 60 61 case 'o': 62 offset = atoi(optstate->value); 63 break; 64 65 case 'b': 66 bitOffset = atoi(optstate->value); 67 break; 68 } 69 } 70 71 if (libFile == NULL) { 72 usage(programName); 73 return 1; 74 } 75 if ((bitOffset >= 8) || (bitOffset < 0)) { 76 usage(programName); 77 return 1; 78 } 79 80 /* open the target signature file */ 81 fd = PR_OpenFile(libFile, PR_RDWR, 0666); 82 if (fd == NULL) { 83 /* lperror(libFile); */ 84 PR_fprintf(pr_stderr, "Couldn't Open %s\n", libFile); 85 goto loser; 86 } 87 88 if (offset < 0) { /* convert to positive offset */ 89 pos = PR_Seek(fd, offset, PR_SEEK_END); 90 if (pos == -1) { 91 PR_fprintf(pr_stderr, "Seek for read on %s (to %d) failed\n", 92 libFile, offset); 93 goto loser; 94 } 95 offset = pos; 96 } 97 98 /* read the byte */ 99 pos = PR_Seek(fd, offset, PR_SEEK_SET); 100 if (pos != offset) { 101 PR_fprintf(pr_stderr, "Seek for read on %s (to %d) failed\n", 102 libFile, offset); 103 goto loser; 104 } 105 bytesRead = PR_Read(fd, &cbuf, 1); 106 if (bytesRead != 1) { 107 PR_fprintf(pr_stderr, "Read on %s (to %d) failed\n", libFile, offset); 108 goto loser; 109 } 110 111 PR_fprintf(pr_stderr, "Changing byte 0x%08x (%d): from %02x (%d) to ", 112 offset, offset, (unsigned char)cbuf, (unsigned char)cbuf); 113 /* change it */ 114 cbuf ^= 1 << bitOffset; 115 PR_fprintf(pr_stderr, "%02x (%d)\n", 116 (unsigned char)cbuf, (unsigned char)cbuf); 117 118 /* write it back out */ 119 pos = PR_Seek(fd, offset, PR_SEEK_SET); 120 if (pos != offset) { 121 PR_fprintf(pr_stderr, "Seek for write on %s (to %d) failed\n", 122 libFile, offset); 123 goto loser; 124 } 125 bytesWritten = PR_Write(fd, &cbuf, 1); 126 if (bytesWritten != 1) { 127 PR_fprintf(pr_stderr, "Write on %s (to %d) failed\n", libFile, offset); 128 goto loser; 129 } 130 131 retval = 0; 132 133 loser: 134 if (fd) 135 PR_Close(fd); 136 PR_Cleanup(); 137 return retval; 138 } 139 140 /*#DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" */