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