1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00
upx/src/p_sys.cpp
Markus F.X.J. Oberhumer 5f87e9891b Enter 2004.
committer: mfx <mfx> 1074623868 +0000
2004-01-20 18:37:48 +00:00

136 lines
4.0 KiB
C++

/* p_sys.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2004 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them 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; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
markus@oberhumer.com ml1050@cdata.tvnet.hu
*/
#include "conf.h"
#include "file.h"
#include "filter.h"
#include "packer.h"
#include "p_com.h"
#include "p_sys.h"
static const
#include "stub/l_sys.h"
/*************************************************************************
//
**************************************************************************/
bool PackSys::canPack()
{
unsigned char buf[128];
fi->readx(buf, sizeof(buf));
if (memcmp (buf,"\xff\xff\xff\xff",4) != 0)
return false;
if (!fn_has_ext(fi->getName(),"sys"))
return false;
checkAlreadyPacked(buf, sizeof(buf));
if (file_size < 1024)
throwCantPack("file is too small");
if (file_size > 0x10000)
throwCantPack("file is too big for dos/sys");
return true;
}
/*************************************************************************
//
**************************************************************************/
void PackSys::patchLoader(OutputFile *fo,
upx_byte *loader, int lsize,
unsigned calls)
{
const int filter_id = ph.filter;
const int e_len = getLoaderSectionStart("SYSCUTPO");
const int d_len = lsize - e_len;
assert(e_len > 0 && e_len < 256);
assert(d_len > 0 && d_len < 256);
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
throwNotCompressible();
memcpy(loader,ibuf,6); // copy from orig. header
memcpy(loader+8,ibuf+8,2); // opendos wants this word too
unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead;
patch_le16(loader,lsize,"JO",get_le16(ibuf+6)-copy_to-1);
if (filter_id)
{
assert(calls > 0);
patch_le16(loader,lsize,"CT",calls);
}
patchPackHeader(loader,e_len);
const unsigned jmp_pos = find_le16(loader,e_len,get_le16("JM"));
patch_le16(loader,e_len,"JM",ph.u_len+ph.overlap_overhead+2-jmp_pos-2);
loader[getLoaderSectionStart("SYSSUBSI") - 1] = (upx_byte) -e_len;
patch_le16(loader,e_len,"DI",copy_to);
patch_le16(loader,e_len,"SI",ph.c_len+e_len+d_len-1);
// write loader + compressed file
fo->write(loader,e_len); // entry
fo->write(obuf,ph.c_len);
fo->write(loader+e_len,d_len); // decompressor
}
int PackSys::buildLoader(const Filter *ft)
{
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
addLoader("SYSMAIN1",
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
"SYSMAIN2""SYSSUBSI",
ph.first_offset_found == 1 ? "SYSSBBBP" : "",
ft->id ? "SYSCALLT" : "",
"SYSMAIN3""UPX1HEAD""SYSCUTPO""NRV2B160""NRVDDONE""NRVDECO1",
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
"NRVDECO2""NRV2B169",
NULL
);
if (ft->id)
{
assert(ft->calls > 0);
addFilter16(ft->id);
}
addLoader("SYSMAIN5",
opt->cpu == opt->CPU_8086 ? "SYSI0862" : "SYSI2862",
"SYSJUMP1",
NULL
);
return getLoaderSize();
}
/*
vi:ts=4:et
*/