[Mono-list] RESULT: 0 from mono, not from mint.
Peter M. Lemmen
peter@lemmen.org
Fri, 29 Mar 2002 15:53:32 +0100
This is a multi-part message in MIME format.
------=_NextPart_000_0003_01C1D739.E0D9C380
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Hi again,
I updated the scripts and the c program with a GPL statement which I copied
from the bottom of one of those COPYING files. I hope that fixes the licensing
bit.
I also took a good look at information about the Portable Executable layout
after t3rmin4t0r's remarks and rewrote most of the ismonobin program. It now
parses the PE Header and Optional Header, looking for a Data Dictionary Entry
that signifies a .NET binary. It should now correctly identify between .NET and
non-.NET binaries. My previous assumptions were a bit overly simple. ;-)
Regards,
Peter.
> -----Original Message-----
> From: mono-list-admin@ximian.com [mailto:mono-list-admin@ximian.com]On
> Behalf Of Peter M. Lemmen
> Sent: Friday, March 29, 2002 11:34
> To: Miguel de Icaza; Peter M. Lemmen
> Cc: Mono-List Mailing List
> Subject: RE: [Mono-list] RESULT: 0 from mono, not from mint.
>
>
> Hi,
>
> > -----Original Message-----
> > From: Miguel de Icaza [mailto:miguel@ximian.com]
> > Sent: Friday, March 29, 2002 07:10
> > To: Peter M. Lemmen
> > Cc: Ulrich Kunitz; Mono-List Mailing List
> > Subject: RE: [Mono-list] RESULT: 0 from mono, not from mint.
> >
> >
> > Hello Peter!
> >
> > > I've written two little scripts and a small c program to wrap
> > around the whole
> > > binary execution thing.
> >
> > These are awesome! Would you mind licensing those scripts under the
> > GPL, LGPL or X11 licenses and allow us to distribute those as part of
> > Mono?
>
> No problem. How do I do that, and which license do you suggest?
>
> >
> >
> > > The default locations for the scripts right now is /usr/bin/local.
> > I hope this
> > > is ok. After placing them in there and running binfmt_misc_mono
> > you should be
> > > able to try the following for yourself:
> >
> > Ideally if we integrate this into the build, we will have configure
> > automatically generate the correct paths that will be embedded.
>
> I'm going to work the suggestions of t3rmin4t0r into ismonobin, then I'll see
> if I can figure out how to couple it to configure. :-)
>
> > <SNIP>
> >
>
>
>
> _______________________________________________
> Mono-list maillist - Mono-list@ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
>
------=_NextPart_000_0003_01C1D739.E0D9C380
Content-Type: application/octet-stream;
name="ismonobin.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="ismonobin.c"
//_______________________________________________________________________=
______
//
// ismonobin v0.2, Copyright (C) 2002 Peter M. Lemmen.
//
// ismonobin tries to determine wether the passed executable is an =
Intermediate
// Language binary or not.
//
// This program is free software; you can redistribute it and/or =
modify
// it under the terms of the GNU General Public License as published =
by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//_______________________________________________________________________=
______
//
// 20020329, Modified - Added correct PE Header parsing as per =
t3rmin4t0r's
// suggestions. Also moved the checks into =
functions.
//_______________________________________________________________________=
______
//
// Includes.
//
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
//_______________________________________________________________________=
______
//
// The size of the buffer used for reads, should be large enough to host =
our
// largest read.
//
#define BUFFER_SIZE 128
//
// The 'magic' bytes starting the Mono binaries.
//
unsigned char aucMSDOSSignature[] =3D {
0x4D, 0x5A
};
//
#define MSD_CMP_SIZE 2
//
// The PE Header bytes.
//
unsigned char aucPESignature[] =3D {
0x50, 0x45, 0x00, 0x00
};
//
#define PEH_CMP_SIZE 4
//_______________________________________________________________________=
______
//
int display_help() {
printf( "ismonobin v0.2, Copyright (C) 2002 Peter M. Lemmen.\n" );
printf( "Usage: ismonobin <executable>\n" );
printf( " ismonobin tries to determine wether the passed executable is =
an Intermediate\n" );
printf( " Language binary or not.\n" );
return 0;
}
//_______________________________________________________________________=
______
//
// A simple function to seek to a position in a filedescriptor and =
compare a
// range of bytes found there to those in the passed array.
//
int intCompareByteRangeAt(
const int intFileDescriptor
, const off_t oftOffSet
, const size_t setRange
, const void *ptrCompareWith
) {
unsigned char aucBuffer[BUFFER_SIZE];
int intBytesRead;
// Check if the FileDescriptor is valid.
if (intFileDescriptor < 1)
return -1;
// Check if the Offset is valid.
if (oftOffSet < (off_t)0)
return -2;
// Check if the Range is valid.
if (setRange < (size_t)1)
return -3;
// Move to the specified location.
if (lseek( intFileDescriptor, oftOffSet, SEEK_SET ) !=3D oftOffSet)
return -4;
// Read setRange bytes.
intBytesRead =3D read( intFileDescriptor, &aucBuffer, setRange );
// Check if the read was succesful.
if ((size_t)intBytesRead < setRange)
return -5;
// Ok, compare the setRange bytes to ptrCompareWith.
if (bcmp( aucBuffer, ptrCompareWith, setRange ) !=3D 0)
return 1;
// It matches.
return 0;
}
//_______________________________________________________________________=
______
//
// A simple function to get an DWord (int32/address) from a specific =
location
// within a FileDescriptor
//
int intGetDWordAt(
const int intFileDescriptor
, const off_t oftOffSet
) {
int intDWord;
int intBytesRead;
// Check if the FileDescriptor is valid.
if (intFileDescriptor < 1)
return -1;
// Check if the Offset is valid.
if (oftOffSet < (off_t)0)
return -2;
// Move to the specified location.
if (lseek( intFileDescriptor, oftOffSet, SEEK_SET ) !=3D oftOffSet)
return -3;
// Read 4 bytes into the Address variable.
intBytesRead =3D read( intFileDescriptor, &intDWord, (size_t)4 );
// Check if the read was succesful.
if (intBytesRead < 4)
return -4;
// Return the Address.
return intDWord;
}
//_______________________________________________________________________=
______
//
// A simple function to get a Word (int16) from a specific location =
within a
// FileDescriptor
//
int intGetWordAt(
const int intFileDescriptor
, const off_t oftOffSet
) {
int intWord;
int intBytesRead;
// Check if the FileDescriptor is valid.
if (intFileDescriptor < 1)
return -1;
// Check if the Offset is valid.
if (oftOffSet < (off_t)0)
return -2;
// Move to the specified location.
if (lseek( intFileDescriptor, oftOffSet, SEEK_SET ) !=3D oftOffSet)
return -3;
// Make sure the upper bits are 0
intWord =3D 0;
// Read 2 bytes into the Address variable.
intBytesRead =3D read( intFileDescriptor, &intWord, (size_t)2 );
// Check if the read was succesful.
if (intBytesRead < 2)
return -4;
// Return the Address.
return intWord;
}
//_______________________________________________________________________=
______
//
// Program Entrypoint.
//
int main (int intArgumentCount, char *acrArgumentValues []){
int intFileDescriptor;
int intBaseAddress;
int intCharacteristics;
int intVirtualAddress;
int intSize;
// Check if we're being passed anything other then a single parameter.
if ((intArgumentCount < 2)
|| (intArgumentCount > 2)) {
return display_help();
// If not, check if it isn't -h.
} else if (strcmp( "-h", acrArgumentValues[1] ) =3D=3D 0) {
return display_help();
}
// Try to open the file given on the command line.
intFileDescriptor =3D open( acrArgumentValues[1], O_RDONLY );
// Check if successful.
if (intFileDescriptor < 1) {
fprintf( stderr, "Unabled to open file %s.\n", acrArgumentValues[1] =
);
return 0;
}
// Check for a valid MSDOS Signature at the start of the file.
if (intCompareByteRangeAt( intFileDescriptor, (off_t)0, =
(size_t)MSD_CMP_SIZE, aucMSDOSSignature ) !=3D 0) {
fprintf( stderr, "File %s does not have a valid Exe header.\n", =
acrArgumentValues[1] );
return 0;
}
=20
// Get the Base Address for the PE Header.
intBaseAddress =3D intGetDWordAt( intFileDescriptor, (off_t)60 );
// Check for a valid PE Signature at the Base Address.
if (intCompareByteRangeAt( intFileDescriptor, (off_t)intBaseAddress, =
(size_t)PEH_CMP_SIZE, aucPESignature ) !=3D 0) {
fprintf( stderr, "File %s does not have a valid PE Header.\n", =
acrArgumentValues[1] );
return 0;
}
=20
// Get the PE Characteristics at Base + 0x16.
intCharacteristics =3D intGetWordAt( intFileDescriptor, =
(off_t)(intBaseAddress + 0x16) );
// Check for the Executable bit.
if ((intCharacteristics & 0x0002) !=3D 0x0002) {
fprintf( stderr, "File %s does not have it's executable bit set.\n", =
acrArgumentValues[1] );
return 0;
}
// Check for the DLL bit.
if ((intCharacteristics & 0x2000) =3D=3D 0x2000) {
fprintf( stderr, "File %s has it's DLL bit set.\n", =
acrArgumentValues[1] );
return 0;
}
// Move to the Optional Header.
intBaseAddress +=3D 0x18;
// Get the Virtual Address and Size of the Com Descriptor Directory =
Entry.
intVirtualAddress =3D intGetDWordAt( intFileDescriptor, =
(off_t)(intBaseAddress + 0xD0) );
intSize =3D intGetDWordAt( intFileDescriptor, (off_t)(intBaseAddress + =
0xD4) );
// If these two are zero (and I read the specs correctly) then it =
can't be an IL binary.
if ((intVirtualAddress =3D=3D 0)
|| (intSize =3D=3D 0)) {
fprintf( stderr, "File %s has no Com Descriptor Directory Entry =
set.\n", acrArgumentValues[1] );
return 0;
}
// Looks like an IL binary.
return 1;
}
//_______________________________________________________________________=
______
//
------=_NextPart_000_0003_01C1D739.E0D9C380
Content-Type: application/octet-stream;
name="exewrapper.sh"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="exewrapper.sh"
#!/bin/bash=0A=
# exewrapper.sh v0.2, Copyright (C) 2002 Peter M. Lemmen.=0A=
#=0A=
# This program is free software; you can redistribute it and/or modify=0A=
# it under the terms of the GNU General Public License as published by=0A=
# the Free Software Foundation; either version 2 of the License, or=0A=
# (at your option) any later version.=0A=
#=0A=
# This program is distributed in the hope that it will be useful,=0A=
# but WITHOUT ANY WARRANTY; without even the implied warranty of=0A=
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A=
# GNU General Public License for more details.=0A=
#=0A=
# You should have received a copy of the GNU General Public License=0A=
# along with this program; if not, write to the Free Software=0A=
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=0A=
#=0A=
=0A=
# Define the mono and ismonobin executables.=0A=
MONO=3D/usr/local/bin/mono=0A=
ISMONOBIN=3D/usr/local/bin/ismonobin=0A=
=0A=
# Check for at least one argument.=0A=
if [ $# -lt "1" ]=0A=
then=0A=
echo "Usage: `basename $0` <executable> [arguments]"=0A=
exit 0=0A=
fi=0A=
=0A=
# Test of the passed argument is a Mono Binary.=0A=
$ISMONOBIN $1 2> /dev/null=0A=
=0A=
# If so, run it with the Mono JIT.=0A=
if [ $? -eq 1 ]=0A=
then=0A=
$MONO $1 $*=0A=
exit 0=0A=
fi=0A=
=0A=
# If not, well, do something else I suppose.=0A=
# TODO: Wine and DOSEMU support.=0A=
echo "File \"$1\" is NOT a Mono Binary."=0A=
=0A=
exit 0=0A=
------=_NextPart_000_0003_01C1D739.E0D9C380
Content-Type: application/octet-stream;
name="binfmt_misc_mono.sh"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="binfmt_misc_mono.sh"
#!/bin/bash=0A=
# binfmt_misc_mono.sh v0.2, Copyright (C) 2002 Peter M. Lemmen.=0A=
#=0A=
# This program is free software; you can redistribute it and/or modify=0A=
# it under the terms of the GNU General Public License as published by=0A=
# the Free Software Foundation; either version 2 of the License, or=0A=
# (at your option) any later version.=0A=
#=0A=
# This program is distributed in the hope that it will be useful,=0A=
# but WITHOUT ANY WARRANTY; without even the implied warranty of=0A=
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A=
# GNU General Public License for more details.=0A=
#=0A=
# You should have received a copy of the GNU General Public License=0A=
# along with this program; if not, write to the Free Software=0A=
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=0A=
#=0A=
=0A=
# Define the register and exewrapper location.=0A=
REGISTER=3D/proc/sys/fs/binfmt_misc/register=0A=
EXEWRAPPER=3D/usr/local/bin/exewrapper.sh=0A=
MODPROBE=3D/sbin/modprobe=0A=
ECHO=3D/bin/echo=0A=
=0A=
# Create a Registration String.=0A=
REGISTRATION=3D:ExeWrapper:M::MZ::$EXEWRAPPER:=0A=
=0A=
# Load the binfmt_misc module=0A=
$MODPROBE binfmt_misc=0A=
=0A=
# Register the exewrapper =0A=
$ECHO $REGISTRATION > $REGISTER=0A=
=0A=
exit 0=0A=
------=_NextPart_000_0003_01C1D739.E0D9C380--