Import of pkgsrc-2013Q2

This commit is contained in:
2013-09-26 17:14:40 +02:00
commit 785076ae39
74991 changed files with 4380255 additions and 0 deletions

2
pkgtools/binpatch/DESCR Normal file
View File

@@ -0,0 +1,2 @@
Apply small, arbitrary binary patches using an arcane command line
syntax.

View File

@@ -0,0 +1,29 @@
# $NetBSD: Makefile,v 1.12 2012/09/11 23:19:33 asau Exp $
#
DISTNAME= binpatch-1.0
CATEGORIES= pkgtools
MASTER_SITES= # empty
DISTFILES= # empty
MAINTAINER= pkgsrc-users@NetBSD.org
HOMEPAGE= ftp://ftp.NetBSD.org/pub/NetBSD/packages/pkgsrc/doc/pkgsrc.html
COMMENT= Trivial binary patch applicator
.include "../../mk/bsd.prefs.mk"
INSTALLATION_DIRS= bin ${PKGMANDIR}/man1
do-extract:
@${CP} -R ${FILESDIR} ${WRKSRC}
do-build:
@(cd ${WRKSRC}; \
${ECHO} "${CC} -o binpatch binpatch.c"; \
${CC} -o binpatch binpatch.c )
do-install:
${INSTALL_PROGRAM} ${WRKSRC}/binpatch ${DESTDIR}${PREFIX}/bin/binpatch
${INSTALL_MAN} ${WRKSRC}/binpatch.1 ${DESTDIR}${PREFIX}/${PKGMANDIR}/man1
.include "../../mk/bsd.pkg.mk"

3
pkgtools/binpatch/PLIST Normal file
View File

@@ -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

View File

@@ -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>
.\" 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

View File

@@ -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> 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);
}
}
/*
* ./binpatch
* file=${MOZILLA_HOME}/netscape
* size=13823336
* offset=0x008073e9
* compare=6a00e82406a3ffe81f0ca3ff
* skip=2
* replace=9090909090
*/
if (f == -1)
die(0, "file missing");
if (get == NULL || lget == 0)
die(0, "compare missing");
if (put == NULL || lput == 0)
die(0, "replace missing");
if (sz == -1)
die(0, "size missing");
if (cmp_off == -1)
die(0, "offset missing");
if (skip_off == -1)
die(0, "skip missing");
if (skip_off < 0 ||
(skip_off == 0 && lput >= lget) ||
(skip_off > 0 && skip_off + lput > lget))
die(0, "illegal skip");
if (fstat(f, &st) == -1)
die(1, "fstat");
if (st.st_size != sz)
die(0, "wrong size");
if (lseek(f, cmp_off, SEEK_SET) == -1)
die(1, "lseek");
if (read(f, buf, lget) != lget)
die(1, "read");
if (memcmp(buf, get, lget) != 0)
die(0, "instructions not found");
if (lseek(f, cmp_off + skip_off, SEEK_SET) == -1)
die(1, "lseek");
if (write(f, put, lput) != lput)
die(1, "write");
if (close(f) != 0)
die(1, "close");
return (0);
}