michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * Test program to mangle 1 bit in a binary michael@0: */ michael@0: michael@0: #include "nspr.h" michael@0: #include "plstr.h" michael@0: #include "plgetopt.h" michael@0: #include "prio.h" michael@0: michael@0: static PRFileDesc *pr_stderr; michael@0: static void michael@0: usage (char *program_name) michael@0: { michael@0: michael@0: PR_fprintf (pr_stderr, "Usage:"); michael@0: PR_fprintf (pr_stderr, "%s -i shared_library_name -o byte_offset -b bit\n", program_name); michael@0: } michael@0: michael@0: michael@0: int michael@0: main (int argc, char **argv) michael@0: { michael@0: /* buffers and locals */ michael@0: PLOptState *optstate; michael@0: char *programName; michael@0: char cbuf; michael@0: michael@0: /* parameter set variables */ michael@0: const char *libFile = NULL; michael@0: int bitOffset = -1; michael@0: michael@0: /* return values */ michael@0: int retval = 2; /* 0 - test succeeded. michael@0: * 1 - illegal args michael@0: * 2 - function failed */ michael@0: PRFileDesc *fd = NULL; michael@0: int bytesRead; michael@0: int bytesWritten; michael@0: PROffset32 offset = -1; michael@0: PROffset32 pos; michael@0: michael@0: programName = PL_strrchr(argv[0], '/'); michael@0: programName = programName ? (programName + 1) : argv[0]; michael@0: michael@0: pr_stderr = PR_STDERR; michael@0: michael@0: optstate = PL_CreateOptState (argc, argv, "i:o:b:"); michael@0: if (optstate == NULL) { michael@0: return 1; michael@0: } michael@0: michael@0: while (PL_GetNextOpt (optstate) == PL_OPT_OK) { michael@0: switch (optstate->option) { michael@0: case 'i': michael@0: libFile = optstate->value; michael@0: break; michael@0: michael@0: case 'o': michael@0: offset = atoi(optstate->value); michael@0: break; michael@0: michael@0: case 'b': michael@0: bitOffset = atoi(optstate->value); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: if (libFile == NULL) { michael@0: usage(programName); michael@0: return 1; michael@0: } michael@0: if ((bitOffset >= 8) || (bitOffset < 0)) { michael@0: usage(programName); michael@0: return 1; michael@0: } michael@0: michael@0: /* open the target signature file */ michael@0: fd = PR_OpenFile(libFile,PR_RDWR,0666); michael@0: if (fd == NULL ) { michael@0: /* lperror(libFile); */ michael@0: PR_fprintf(pr_stderr,"Couldn't Open %s\n",libFile); michael@0: goto loser; michael@0: } michael@0: michael@0: if (offset < 0) { /* convert to positive offset */ michael@0: pos = PR_Seek(fd, offset, PR_SEEK_END); michael@0: if (pos == -1) { michael@0: PR_fprintf(pr_stderr,"Seek for read on %s (to %d) failed\n", michael@0: libFile, offset); michael@0: goto loser; michael@0: } michael@0: offset = pos; michael@0: } michael@0: michael@0: /* read the byte */ michael@0: pos = PR_Seek(fd, offset, PR_SEEK_SET); michael@0: if (pos != offset) { michael@0: PR_fprintf(pr_stderr,"Seek for read on %s (to %d) failed\n", michael@0: libFile, offset); michael@0: goto loser; michael@0: } michael@0: bytesRead = PR_Read(fd, &cbuf, 1); michael@0: if (bytesRead != 1) { michael@0: PR_fprintf(pr_stderr,"Read on %s (to %d) failed\n", libFile, offset); michael@0: goto loser; michael@0: } michael@0: michael@0: PR_fprintf(pr_stderr,"Changing byte 0x%08x (%d): from %02x (%d) to ", michael@0: offset, offset, (unsigned char)cbuf, (unsigned char)cbuf); michael@0: /* change it */ michael@0: cbuf ^= 1 << bitOffset; michael@0: PR_fprintf(pr_stderr,"%02x (%d)\n", michael@0: (unsigned char)cbuf, (unsigned char)cbuf); michael@0: michael@0: /* write it back out */ michael@0: pos = PR_Seek(fd, offset, PR_SEEK_SET); michael@0: if (pos != offset) { michael@0: PR_fprintf(pr_stderr,"Seek for write on %s (to %d) failed\n", michael@0: libFile, offset); michael@0: goto loser; michael@0: } michael@0: bytesWritten = PR_Write(fd, &cbuf, 1); michael@0: if (bytesWritten != 1) { michael@0: PR_fprintf(pr_stderr,"Write on %s (to %d) failed\n", libFile, offset); michael@0: goto loser; michael@0: } michael@0: michael@0: retval = 0; michael@0: michael@0: loser: michael@0: if (fd) michael@0: PR_Close(fd); michael@0: PR_Cleanup (); michael@0: return retval; michael@0: } michael@0: michael@0: /*#DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" */