pkgsrc-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[pkgsrc/trunk]: pkgsrc/pkgtools/binpatch A small package to arbitrary tiny pa...
details: https://anonhg.NetBSD.org/pkgsrc/rev/d466a07b0ac1
branches: trunk
changeset: 478389:d466a07b0ac1
user: atatat <atatat%pkgsrc.org@localhost>
date: Fri Jul 23 03:37:26 2004 +0000
description:
A small package to arbitrary tiny patches to binaries (where the
source cannot otherwise be patched).
diffstat:
pkgtools/binpatch/DESCR | 2 +
pkgtools/binpatch/Makefile | 31 ++++++
pkgtools/binpatch/PLIST | 3 +
pkgtools/binpatch/files/binpatch.1 | 116 ++++++++++++++++++++++++
pkgtools/binpatch/files/binpatch.c | 174 +++++++++++++++++++++++++++++++++++++
5 files changed, 326 insertions(+), 0 deletions(-)
diffs (truncated from 346 to 300 lines):
diff -r 86eb9c6f0ba3 -r d466a07b0ac1 pkgtools/binpatch/DESCR
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkgtools/binpatch/DESCR Fri Jul 23 03:37:26 2004 +0000
@@ -0,0 +1,2 @@
+Apply small, arbitrary binary patches using an arcane command line
+syntax.
diff -r 86eb9c6f0ba3 -r d466a07b0ac1 pkgtools/binpatch/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkgtools/binpatch/Makefile Fri Jul 23 03:37:26 2004 +0000
@@ -0,0 +1,31 @@
+# $NetBSD: Makefile,v 1.1.1.1 2004/07/23 03:37:26 atatat Exp $
+#
+
+DISTNAME= binpatch-1.0
+CATEGORIES= pkgtools
+MASTER_SITES= # empty
+DISTFILES= # empty
+
+MAINTAINER= atatat%NetBSD.org@localhost
+HOMEPAGE= ftp://ftp.NetBSD.org/pub/NetBSD/packages/pkgsrc/Packages.txt
+COMMENT= Trivial binary patch applicator
+
+USE_BUILDLINK3= yes
+
+NO_CHECKSUM= # defined
+
+.include "../../mk/bsd.prefs.mk"
+
+do-extract:
+ @${CP} -Rp ${FILESDIR} ${WRKSRC}
+
+do-build:
+ @(cd ${WRKSRC}; \
+ ${ECHO} "${CC} -o binpatch binpatch.c"; \
+ ${CC} -o binpatch binpatch.c )
+
+do-install:
+ ${INSTALL_PROGRAM} ${WRKSRC}/binpatch ${PREFIX}/bin/binpatch
+ ${INSTALL_MAN} ${WRKSRC}/binpatch.1 ${PREFIX}/man/man1
+
+.include "../../mk/bsd.pkg.mk"
diff -r 86eb9c6f0ba3 -r d466a07b0ac1 pkgtools/binpatch/PLIST
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkgtools/binpatch/PLIST Fri Jul 23 03:37:26 2004 +0000
@@ -0,0 +1,3 @@
+@comment $NetBSD: PLIST,v 1.1.1.1 2004/07/23 03:37:26 atatat Exp $
+bin/binpatch
+man/man1/binpatch.1
diff -r 86eb9c6f0ba3 -r d466a07b0ac1 pkgtools/binpatch/files/binpatch.1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkgtools/binpatch/files/binpatch.1 Fri Jul 23 03:37:26 2004 +0000
@@ -0,0 +1,116 @@
+.\" $NetBSD: binpatch.1,v 1.1.1.1 2004/07/23 03:37:26 atatat Exp $
+.\"
+.\" Copyright (c) 2004 by Andrew Brown <atatat%netbsd.org@localhost>
+.\" Absolutely no warranty.
+.\"
+.Dd July 20, 2004
+.Dt BINPATCH 1
+.Sh NAME
+.Nm binpatch
+.Nd trivial binary patch applicator
+.Sh SYNOPSIS
+.Nm
+.Pa file=...
+.Pa size=...
+.Pa offset=...
+.Pa compare=...
+.Pa skip=...
+.Pa replace=...
+.Sh DESCRIPTION
+The
+.Nm
+utility can read and replace a small section of a given file.
+It is designed for use in those instances where a problem exists with
+a given binary that cannot be reconstructed from source code, but the
+required change can be implemented by replacing a few bytes in the
+existing binary.
+All arguments must be given.
+.Sh EXAMPLES
+Given a binary called
+.Dq a.out
+of 10713 bytes in size with the following text segment:
+.Bd -literal -offset indent
+% objdump -h a.out
+.sp
+a.out: file format elf32-i386
+.sp
+Sections:
+Idx Name Size VMA LMA File off Algn
+[...]
+ 9 .text 00000be4 08048968 08048968 00000968 2**2
+ CONTENTS, ALLOC, LOAD, READONLY, CODE
+[...]
+% objdump -d -j .text a.out
+[...]
+ 8048b0f: 83 ef 04 sub $0x4,%edi
+ 8048b12: ff d0 call *%eax
+ 8048b14: 83 fe ff cmp $0xffffffff,%esi
+[...]
+.sp
+.Ed
+where we wish to elide the call through
+.Ar %eax
+by replacing it with a series of
+.Ar nop
+(or
+.Dq no operation )
+instructions (the machine code for this on the i386 platform is 0x90),
+we first calculate the offset into the file of the previous
+.Ar sub
+instruction. To do this, we take the address of the
+.Ar sub
+instruction as given by the dissassembly output, subtract the
+.Dq LMA
+and add the
+.Dq File off
+values from the objdump output (note that
+.Xr bc 1
+expects hexadecimal values to be given using upper case):
+.Bd -literal -offset indent
+% bc
+ibase=16
+8048B0F-08048968+00000968
+2831
+.sp
+.Ed
+The region of the binary we want to compare to before applying the
+patch is the concatenation of the relevant machine codes from the
+dissassembly dump (\c
+.Ar 83ef04ffd083feff )
+and the replacement is simply two
+.Ar nop
+instructions (\c
+.Ar 9090 ) ,
+that will replace the
+.Ar ffd0
+of the original call.
+The offset of the replacement is 3, since that is the number of bytes
+in the
+.Ar sub
+instruction.
+From this we have our patch:
+.Bd -literal -offset indent
+% binpatch file=a.out size=10713 offset=2831 \\
+ compare=83ef04ffd083feff skip=3 replace=9090
+% objdump -d -j .text a.out
+[...]
+ 8048b0f: 83 ef 04 sub $0x4,%edi
+ 8048b12: 90 nop
+ 8048b13: 90 nop
+ 8048b14: 83 fe ff cmp $0xffffffff,%esi
+[...]
+.sp
+.Ed
+And thus the call is removed.
+.Sh DIAGNOSTICS
+The diagnostics are terse and almost unhelpful, but are more verbose
+than users of
+.Xr ed 1
+might be used to.
+They typically mention the command line argument that was in error.
+.Sh SEE ALSO
+.Xr bc 1 ,
+.Xr objdump 1 ,
+.Xr patch 1
+.Sh AUTHORS
+.An Andrew Brown Aq atatat%netbsd.org@localhost
diff -r 86eb9c6f0ba3 -r d466a07b0ac1 pkgtools/binpatch/files/binpatch.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkgtools/binpatch/files/binpatch.c Fri Jul 23 03:37:26 2004 +0000
@@ -0,0 +1,174 @@
+/* $NetBSD: binpatch.c,v 1.1.1.1 2004/07/23 03:37:26 atatat Exp $ */
+
+/*
+ * ------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Andrew Brown <atatat%NetBSD.org@localhost> wrote this file. As long as you
+ * retain this notice you can do whatever you want with this stuff.
+ * If we meet some day, and you think this stuff is worth it, you can
+ * buy me a beer in return.
+ * ------------------------------------------------------------------------
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int
+die(int rc, const char *msg)
+{
+ if (rc)
+ perror(msg);
+ else
+ fprintf(stderr, "%s\n", msg);
+ exit(1);
+}
+
+static void
+cvt(const char *s, const char *i, unsigned char *o, size_t l)
+{
+ int t, x;
+
+ for (t = 0; t < l; t++) {
+ x = i[2 * t];
+ if (x >= '0' && x <= '9')
+ x -= '0';
+ else if (x >= 'a' && x <= 'f')
+ x -= 'a' - 10;
+ else if (x >= 'A' && x <= 'F')
+ x -= 'A' - 10;
+ else
+ die(0, s);
+ o[t] = x * 16;
+
+ x = i[2 * t + 1];
+ if (x >= '0' && x <= '9')
+ x -= '0';
+ else if (x >= 'a' && x <= 'f')
+ x -= 'a' - 10;
+ else if (x >= 'A' && x <= 'F')
+ x -= 'A' - 10;
+ else
+ die(0, s);
+ o[t] += x;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ char *key, *value;
+ int f, i;
+ unsigned char *buf, *get, *put;
+ size_t lget, lput;
+ off_t sz, cmp_off, skip_off;
+
+ f = -1;
+ get = put = NULL;
+ lget = lput = 0;
+ sz = cmp_off = skip_off = -1;
+
+ while (--argc > 0) {
+ key = *++argv;
+ if ((value = strchr(key, '=')) == NULL)
+ die(0, "value required");
+ else
+ *value++ = '\0';
+
+ if (strcmp(key, "file") == 0) {
+ f = open(value, O_RDWR);
+ if (f == -1)
+ die(1, "file");
+ }
+ else if (strcmp(key, "size") == 0) {
+ char *t;
+ errno = 0;
+ sz = strtol(value, &t, 0);
+ if (errno != 0)
+ die(1, "size");
+ }
+ else if (strcmp(key, "offset") == 0) {
+ char *t;
+ errno = 0;
+ cmp_off = strtol(value, &t, 0);
+ if (errno != 0)
+ die(1, "offset");
+ }
+ else if (strcmp(key, "compare") == 0) {
+ lget = strlen(value);
+ if (lget % 2 != 0)
+ die(0, "compare");
+ lget /= 2;
+ get = malloc(lget);
+ buf = malloc(lget);
+ cvt("compare", value, get, lget);
+ }
+ else if (strcmp(key, "skip") == 0) {
+ char *t;
+ errno = 0;
+ skip_off = strtol(value, &t, 0);
+ if (errno != 0)
+ die(1, "offset");
+ }
+ else if (strcmp(key, "replace") == 0) {
+ lput = strlen(value);
+ if (lput % 2 != 0)
+ die(0, "replace");
+ lput /= 2;
+ put = malloc(lput);
+ cvt("replace", value, put, lput);
+ }
+ }
+
Home |
Main Index |
Thread Index |
Old Index