exeflat: add support for response file to exeflat utility
the command line can overflow DOS max length that it fixes this issue
This commit is contained in:
parent
2fb0956513
commit
a5b516dd7b
@ -74,6 +74,7 @@ git clean -x -d -f -e test -e _output -e _downloads -e _watcom
|
|||||||
echo set XCPU=386
|
echo set XCPU=386
|
||||||
echo set XFAT=32
|
echo set XFAT=32
|
||||||
echo set XNASM='C:\\devel\\nasm\\nasm'
|
echo set XNASM='C:\\devel\\nasm\\nasm'
|
||||||
|
echo set XUPX=upx --8086 --best
|
||||||
echo set OLDPATH=%PATH%
|
echo set OLDPATH=%PATH%
|
||||||
echo set PATH='%WATCOM%\\binw;C:\\bin;%OLDPATH%'
|
echo set PATH='%WATCOM%\\binw;C:\\bin;%OLDPATH%'
|
||||||
} | unix2dos > config.bat
|
} | unix2dos > config.bat
|
||||||
|
@ -36,8 +36,8 @@ production: ../bin/$(TARGET).sys
|
|||||||
|
|
||||||
# -S to avoid showing expected relocations
|
# -S to avoid showing expected relocations
|
||||||
# 0x10 & 0x78 or 0x79 depending on compilation options
|
# 0x10 & 0x78 or 0x79 depending on compilation options
|
||||||
kernel.sys: kernel.exe ../utils/exeflat.exe ../utils/upxentry.bin ../utils/upxdevic.bin
|
kernel.sys: kernel.exe ../utils/exeflat.exe ../utils/upxentry.bin ../utils/upxdevic.bin exeflat.rsp
|
||||||
..$(DIRSEP)utils$(DIRSEP)exeflat.exe kernel.exe kernel.sys $(LOADSEG) -S0x10 -S0x78 -S0x79 -E..$(DIRSEP)utils$(DIRSEP)upxentry.bin -D..$(DIRSEP)utils$(DIRSEP)upxdevic.bin $(UPXOPT) $(XUPX)
|
..$(DIRSEP)utils$(DIRSEP)exeflat.exe kernel.exe kernel.sys $(LOADSEG) @exeflat.rsp
|
||||||
|
|
||||||
kernel.exe: $(TARGET).lnk $(OBJS) $(LIBS)
|
kernel.exe: $(TARGET).lnk $(OBJS) $(LIBS)
|
||||||
$(LINK) @$(TARGET).lnk;
|
$(LINK) @$(TARGET).lnk;
|
||||||
@ -46,11 +46,21 @@ clobber: clean
|
|||||||
-$(RM) kernel.exe kernel.sys status.me
|
-$(RM) kernel.exe kernel.sys status.me
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err *.lnk
|
-$(RM) *.obj *.bak *.crf *.xrf *.map *.lst *.cod *.err *.lnk *.rsp
|
||||||
|
|
||||||
# XXX: This is a very ugly way of linking the kernel, forced upon us by the
|
# XXX: This is a very ugly way of linking the kernel, forced upon us by the
|
||||||
# inability of Turbo `make' 2.0 to perform command line redirection. -- ror4
|
# inability of Turbo `make' 2.0 to perform command line redirection. -- ror4
|
||||||
|
|
||||||
|
exeflat.rsp: makefile
|
||||||
|
-$(RM) exeflat.rsp
|
||||||
|
$(ECHOTO) exeflat.rsp -S0x10
|
||||||
|
$(ECHOTO) exeflat.rsp -S0x78
|
||||||
|
$(ECHOTO) exeflat.rsp -S0x79
|
||||||
|
$(ECHOTO) exeflat.rsp -E..$(DIRSEP)utils$(DIRSEP)upxentry.bin
|
||||||
|
$(ECHOTO) exeflat.rsp -D..$(DIRSEP)utils$(DIRSEP)upxdevic.bin
|
||||||
|
$(ECHOTO) exeflat.rsp $(UPXOPT)
|
||||||
|
$(ECHOTO) exeflat.rsp $(XUPX)
|
||||||
|
|
||||||
$(TARGET).lnk: turboc.cfg makefile ../mkfiles/generic.mak ../mkfiles/$(COMPILER).mak
|
$(TARGET).lnk: turboc.cfg makefile ../mkfiles/generic.mak ../mkfiles/$(COMPILER).mak
|
||||||
-$(RM) *.lnk
|
-$(RM) *.lnk
|
||||||
$(ECHOTO) $(TARGET).lnk $(OBJS1)+
|
$(ECHOTO) $(TARGET).lnk $(OBJS1)+
|
||||||
|
352
utils/exeflat.c
352
utils/exeflat.c
@ -90,7 +90,7 @@ static void usage(void)
|
|||||||
|
|
||||||
static int exeflat(const char *srcfile, const char *dstfile,
|
static int exeflat(const char *srcfile, const char *dstfile,
|
||||||
const char *start, short *silentSegments, short silentcount,
|
const char *start, short *silentSegments, short silentcount,
|
||||||
int UPX, UWORD stubexesize, UWORD stubdevsize,
|
int use_upx, UWORD stubexesize, UWORD stubdevsize,
|
||||||
UWORD entryparagraphs, exe_header *header)
|
UWORD entryparagraphs, exe_header *header)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -207,7 +207,7 @@ static int exeflat(const char *srcfile, const char *dstfile,
|
|||||||
printf("\nProcessed %d relocations, %d not shown\n",
|
printf("\nProcessed %d relocations, %d not shown\n",
|
||||||
header->exRelocItems, silentdone);
|
header->exRelocItems, silentdone);
|
||||||
|
|
||||||
if (UPX)
|
if (use_upx)
|
||||||
{
|
{
|
||||||
struct x {
|
struct x {
|
||||||
char y[(KERNEL_CONFIG_LENGTH + 2) <= BUFSIZE ? 1 : -1];
|
char y[(KERNEL_CONFIG_LENGTH + 2) <= BUFSIZE ? 1 : -1];
|
||||||
@ -224,7 +224,7 @@ static int exeflat(const char *srcfile, const char *dstfile,
|
|||||||
/* The biggest .sys file that UPX accepts seems to be 65419 bytes long.
|
/* The biggest .sys file that UPX accepts seems to be 65419 bytes long.
|
||||||
Actually, UPX 3.96 appears to accept DOS/SYS files up to 65426 bytes.
|
Actually, UPX 3.96 appears to accept DOS/SYS files up to 65426 bytes.
|
||||||
To avoid problems we use a slightly lower limit. */
|
To avoid problems we use a slightly lower limit. */
|
||||||
if (UPX) {
|
if (use_upx) {
|
||||||
if (stubdevsize && stubexesize)
|
if (stubdevsize && stubexesize)
|
||||||
compress_sys_file = (size - stubdevsize) <= /* 65426 */ 65400;
|
compress_sys_file = (size - stubdevsize) <= /* 65426 */ 65400;
|
||||||
/* would need to subtract 0x10 for the device header here
|
/* would need to subtract 0x10 for the device header here
|
||||||
@ -407,13 +407,59 @@ static void write_header(FILE *dest, unsigned char * code, UWORD stubsize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int my_isspace( int c )
|
||||||
|
{
|
||||||
|
switch( c ) {
|
||||||
|
case ' ':
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case '\f':
|
||||||
|
case '\t':
|
||||||
|
case '\v':
|
||||||
|
return( 1 );
|
||||||
|
default:
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *getarg( FILE *fp )
|
||||||
|
{
|
||||||
|
static char buff[256];
|
||||||
|
char *str;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
while( (str = fgets( buff, sizeof(buff) - 1, fp )) != NULL ) {
|
||||||
|
buff[sizeof(buff) - 1] = '\0';
|
||||||
|
len = strlen(buff);
|
||||||
|
while( len > 0 ) {
|
||||||
|
len--;
|
||||||
|
if( my_isspace( buff[len] ) ) {
|
||||||
|
buff[len] = '\0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
len++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while( len-- > 0 ) {
|
||||||
|
if( !my_isspace(*str) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( *str != '\0' ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return( str );
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
short silentSegments[20], silentcount = 0;
|
short silentSegments[20], silentcount = 0;
|
||||||
static exe_header header; /* must be initialized to zero */
|
static exe_header header; /* must be initialized to zero */
|
||||||
int UPX = FALSE;
|
int use_upx = 0;
|
||||||
|
char *upx_cmd;
|
||||||
int i;
|
int i;
|
||||||
size_t sz, len, len2, n;
|
size_t len;
|
||||||
int compress_sys_file;
|
int compress_sys_file;
|
||||||
char *buffer, *tmpexe, *cmdbuf, *entryexefilename = "", *entrydevfilename = "";
|
char *buffer, *tmpexe, *cmdbuf, *entryexefilename = "", *entrydevfilename = "";
|
||||||
FILE *dest, *source;
|
FILE *dest, *source;
|
||||||
@ -423,48 +469,81 @@ int main(int argc, char **argv)
|
|||||||
FILE * entryf = NULL;
|
FILE * entryf = NULL;
|
||||||
UWORD end;
|
UWORD end;
|
||||||
UWORD stubexesize = 0, stubdevsize = 0;
|
UWORD stubexesize = 0, stubdevsize = 0;
|
||||||
|
FILE *indir = NULL;
|
||||||
|
|
||||||
/* if no arguments provided, show usage and exit */
|
/* if no arguments provided, show usage and exit */
|
||||||
if (argc < 4) usage();
|
if (argc < 4) usage();
|
||||||
|
|
||||||
|
upx_cmd = malloc(1);
|
||||||
|
*upx_cmd = '\0';
|
||||||
|
i = 4;
|
||||||
/* do optional argument processing here */
|
/* do optional argument processing here */
|
||||||
for (i = 4; i < argc && !UPX; i++)
|
while ( i < argc || indir != NULL )
|
||||||
{
|
{
|
||||||
char *argptr = argv[i];
|
char *argptr = NULL;
|
||||||
|
|
||||||
if (argptr[0] != '-' && argptr[0] != '/')
|
if( indir != NULL ) {
|
||||||
usage();
|
argptr = getarg( indir );
|
||||||
|
if(argptr == NULL) {
|
||||||
argptr++;
|
fclose( indir );
|
||||||
|
indir = NULL;
|
||||||
switch (toupper(argptr[0]))
|
continue;
|
||||||
{
|
}
|
||||||
case 'U':
|
}
|
||||||
UPX = i;
|
if( argptr == NULL ) {
|
||||||
break;
|
argptr = argv[i++];
|
||||||
case 'E':
|
}
|
||||||
entryexefilename = &argptr[1];
|
if( use_upx ) {
|
||||||
break;
|
len = strlen( upx_cmd );
|
||||||
case 'D':
|
if( len > 0 ) len++;
|
||||||
entrydevfilename = &argptr[1];
|
upx_cmd = realloc( upx_cmd, len + strlen( argptr ) + 1 );
|
||||||
break;
|
if( len > 0 ) upx_cmd[len - 1] = ' ';
|
||||||
case 'S':
|
strcpy( upx_cmd + len, argptr );
|
||||||
if (silentcount >= LENGTH(silentSegments))
|
} else {
|
||||||
{
|
switch (*(unsigned char *)argptr++)
|
||||||
printf("can't handle more then %d silent's\n",
|
{
|
||||||
(int)LENGTH(silentSegments));
|
case '@':
|
||||||
exit(1);
|
indir = fopen( argptr, "r" );
|
||||||
}
|
if( indir == NULL ) {
|
||||||
|
printf("can't open indirect file '%s'\n", argptr);
|
||||||
silentSegments[silentcount++] = (short)strtol(argptr + 1, NULL, 0);
|
exit(1);
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
default:
|
case '-':
|
||||||
usage();
|
case '/':
|
||||||
|
switch (toupper(*(unsigned char *)argptr++))
|
||||||
|
{
|
||||||
|
case 'U':
|
||||||
|
use_upx = 1;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
entryexefilename = malloc(strlen(argptr) + 1);
|
||||||
|
strcpy(entryexefilename, argptr);
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
entrydevfilename = malloc(strlen(argptr) + 1);
|
||||||
|
strcpy(entrydevfilename, argptr);
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
if (silentcount >= LENGTH(silentSegments))
|
||||||
|
{
|
||||||
|
printf("can't handle more then %d silent's\n",
|
||||||
|
(int)LENGTH(silentSegments));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
silentSegments[silentcount++] = (short)strtol(argptr, NULL, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UPX) {
|
if (use_upx) {
|
||||||
if (*entryexefilename) {
|
if (*entryexefilename) {
|
||||||
entryf = fopen(entryexefilename, "rb");
|
entryf = fopen(entryexefilename, "rb");
|
||||||
if (!entryf) {
|
if (!entryf) {
|
||||||
@ -510,115 +589,100 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
compress_sys_file = exeflat(argv[1], argv[2], argv[3],
|
compress_sys_file = exeflat(argv[1], argv[2], argv[3],
|
||||||
silentSegments, silentcount,
|
silentSegments, silentcount,
|
||||||
UPX, stubexesize, stubdevsize, 0, &header);
|
use_upx, stubexesize, stubdevsize, 0, &header);
|
||||||
if (!UPX)
|
if (use_upx)
|
||||||
exit(0);
|
|
||||||
|
|
||||||
/* move kernel.sys tmp.exe */
|
|
||||||
if (!compress_sys_file)
|
|
||||||
{
|
{
|
||||||
tmpexe = "tmp.exe";
|
/* move kernel.sys tmp.exe */
|
||||||
} else {
|
if (!compress_sys_file)
|
||||||
tmpexe = "tmp.sys";
|
{
|
||||||
}
|
tmpexe = "tmp.exe";
|
||||||
if (rename(argv[2], tmpexe))
|
} else {
|
||||||
{
|
tmpexe = "tmp.sys";
|
||||||
printf("Can not rename %s to %s\n", argv[2], tmpexe);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
len2 = strlen(tmpexe) + 1;
|
|
||||||
sz = len2;
|
|
||||||
if (sz < 256) sz = 256;
|
|
||||||
cmdbuf = malloc(sz);
|
|
||||||
len = 0;
|
|
||||||
for (i = UPX+1; i < argc; i++)
|
|
||||||
{
|
|
||||||
n = strlen(argv[i]);
|
|
||||||
if (len + len2 + n + 2 >= sz) {
|
|
||||||
sz *= 2;
|
|
||||||
cmdbuf = realloc(cmdbuf, sz);
|
|
||||||
}
|
}
|
||||||
if (i > UPX+1)
|
if (rename(argv[2], tmpexe))
|
||||||
cmdbuf[len++] = ' ';
|
{
|
||||||
memcpy(cmdbuf + len, argv[i], n + 1);
|
printf("Can not rename %s to %s\n", argv[2], tmpexe);
|
||||||
len += n;
|
exit(1);
|
||||||
}
|
}
|
||||||
cmdbuf[len++] = ' ';
|
|
||||||
/* if tmpexe is tmpfile set above no quotes needed, if user needs quotes should add on cmd line */
|
len = strlen(upx_cmd);
|
||||||
memcpy(cmdbuf + len, tmpexe, len2);
|
cmdbuf = malloc(len + 1 + strlen(tmpexe) + 1);
|
||||||
cmdbuf[len + len2] = '\0';
|
strcpy(cmdbuf, upx_cmd);
|
||||||
printf("%s\n", cmdbuf);
|
cmdbuf[len] = ' ';
|
||||||
fflush(stdout);
|
/* if tmpexe is tmpfile set above no quotes needed, if user needs quotes should add on cmd line */
|
||||||
if (system(cmdbuf))
|
strcpy(cmdbuf + len + 1, tmpexe);
|
||||||
{
|
printf("%s\n", cmdbuf);
|
||||||
printf("Problems executing %s\n", cmdbuf);
|
fflush(stdout);
|
||||||
printf("Removing [%s]\n", tmpexe);
|
if (system(cmdbuf))
|
||||||
|
{
|
||||||
|
printf("Problems executing %s\n", cmdbuf);
|
||||||
|
printf("Removing [%s]\n", tmpexe);
|
||||||
|
remove(tmpexe);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
free(cmdbuf);
|
||||||
|
|
||||||
|
if (!compress_sys_file)
|
||||||
|
{
|
||||||
|
exeflat(tmpexe, "tmp.bin", argv[3],
|
||||||
|
silentSegments, silentcount,
|
||||||
|
FALSE, stubexesize, 0, stubexesize >> 4, &header);
|
||||||
|
} else {
|
||||||
|
UBYTE deviceheader[16];
|
||||||
|
FILE * devfile = fopen("tmp.sys", "rb");
|
||||||
|
if (!devfile) {
|
||||||
|
printf("Source file %s could not be opened\n", "tmp.sys");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (fread(deviceheader, 1, sizeof deviceheader, devfile)
|
||||||
|
!= sizeof deviceheader) {
|
||||||
|
printf("Source file %s could not be read\n", "tmp.sys");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(devfile);
|
||||||
|
header.exInitIP = deviceheader[6] + deviceheader[7] * 256U;
|
||||||
|
header.exInitCS = 0;
|
||||||
|
rename("tmp.sys", "tmp.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tmp.bin now contains the final flattened file: just
|
||||||
|
the UPX entry header needs to be added. */
|
||||||
|
/* the compressed file may exceed 64 KiB for DOS/EXE format. */
|
||||||
|
|
||||||
|
if ((dest = fopen(argv[2], "wb")) == NULL)
|
||||||
|
{
|
||||||
|
printf("Destination file %s could not be opened\n", argv[2]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((source = fopen("tmp.bin", "rb")) == NULL)
|
||||||
|
{
|
||||||
|
printf("Source file %s could not be opened\n", "tmp.bin");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = malloc(32 * 1024);
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
printf("Memory allocation failure\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_header(dest,
|
||||||
|
compress_sys_file ? devcode : execode,
|
||||||
|
compress_sys_file ? stubdevsize : stubexesize,
|
||||||
|
argv[3], compress_sys_file, &header);
|
||||||
|
|
||||||
|
do {
|
||||||
|
size = fread(buffer, 1, 32 * 1024, source);
|
||||||
|
if (fwrite(buffer, 1, size, dest) != size) {
|
||||||
|
printf("Write failure\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} while (size);
|
||||||
|
|
||||||
|
fclose(source);
|
||||||
|
remove("tmp.bin");
|
||||||
remove(tmpexe);
|
remove(tmpexe);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
free(cmdbuf);
|
|
||||||
|
|
||||||
if (!compress_sys_file)
|
|
||||||
{
|
|
||||||
exeflat(tmpexe, "tmp.bin", argv[3],
|
|
||||||
silentSegments, silentcount,
|
|
||||||
FALSE, stubexesize, 0, stubexesize >> 4, &header);
|
|
||||||
} else {
|
|
||||||
UBYTE deviceheader[16];
|
|
||||||
FILE * devfile = fopen("tmp.sys", "rb");
|
|
||||||
if (!devfile) {
|
|
||||||
printf("Source file %s could not be opened\n", "tmp.sys");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (fread(deviceheader, 1, sizeof deviceheader, devfile)
|
|
||||||
!= sizeof deviceheader) {
|
|
||||||
printf("Source file %s could not be read\n", "tmp.sys");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
fclose(devfile);
|
|
||||||
header.exInitIP = deviceheader[6] + deviceheader[7] * 256U;
|
|
||||||
header.exInitCS = 0;
|
|
||||||
rename("tmp.sys", "tmp.bin");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tmp.bin now contains the final flattened file: just
|
|
||||||
the UPX entry header needs to be added. */
|
|
||||||
/* the compressed file may exceed 64 KiB for DOS/EXE format. */
|
|
||||||
|
|
||||||
if ((dest = fopen(argv[2], "wb")) == NULL)
|
|
||||||
{
|
|
||||||
printf("Destination file %s could not be opened\n", argv[2]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if ((source = fopen("tmp.bin", "rb")) == NULL)
|
|
||||||
{
|
|
||||||
printf("Source file %s could not be opened\n", "tmp.bin");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = malloc(32 * 1024);
|
|
||||||
if (!buffer)
|
|
||||||
{
|
|
||||||
printf("Memory allocation failure\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
write_header(dest,
|
|
||||||
compress_sys_file ? devcode : execode,
|
|
||||||
compress_sys_file ? stubdevsize : stubexesize,
|
|
||||||
argv[3], compress_sys_file, &header);
|
|
||||||
|
|
||||||
do {
|
|
||||||
size = fread(buffer, 1, 32 * 1024, source);
|
|
||||||
if (fwrite(buffer, 1, size, dest) != size) {
|
|
||||||
printf("Write failure\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
} while (size);
|
|
||||||
|
|
||||||
fclose(source);
|
|
||||||
remove("tmp.bin");
|
|
||||||
remove(tmpexe);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user