mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
New ps1/exe version from Jens.
committer: mfx <mfx> 1049665152 +0000
This commit is contained in:
parent
b8a9b321fa
commit
a1064dc2cb
270
src/p_ps1.cpp
270
src/p_ps1.cpp
|
@ -40,32 +40,44 @@ static const
|
||||||
#include "stub/l_ps1.h"
|
#include "stub/l_ps1.h"
|
||||||
|
|
||||||
|
|
||||||
#define MIPS_HI(a) (((a) >> 16) /* + (((a)&0x8000)>>15) */ )
|
#define MIPS_HI(a) ((a) >> 16)
|
||||||
#define MIPS_LO(a) ((a) & 0xffff)
|
#define MIPS_LO(a) ((a) & 0xffff)
|
||||||
#define MIPS_JP(a) ((0x08 << 24) | (((a) & 0x0fffffff) >> 2))
|
#define MIPS_JP(a) ((0x08 << 24) | (((a) & 0x0fffffff) >> 2))
|
||||||
#define NOCACHE(a) ((a) & 0x1FFFFFFF)
|
#define TIL_ALIGNED(a,b) (((b) - ((a) & ((b) - 1))) & (b) - 1)
|
||||||
|
|
||||||
#define PS_HDR_SIZE 2048 // one CD sector in bytes
|
#define CD_SEC 2048
|
||||||
|
#define PS_HDR_SIZE CD_SEC
|
||||||
#define PS_MAX_SIZE 0x1e8000
|
#define PS_MAX_SIZE 0x1e8000
|
||||||
|
|
||||||
#define IH_BKUP (10 * sizeof(LE32))
|
#define IH_BKUP (10 * sizeof(LE32))
|
||||||
|
|
||||||
|
// FIXME: would be nice to set this once, so runtime and handler will
|
||||||
|
// use this together
|
||||||
#define EIGHTBIT
|
#define EIGHTBIT
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// FIXME: Jens please add some small docs how a ps1 exe looks, and
|
// ps1 exe looks like this:
|
||||||
// where alignments are required or optional
|
// 1. <header> 2048 bytes
|
||||||
|
// 2. <body> plain binary
|
||||||
|
//
|
||||||
|
// header: contains the ps1_exe_t structure 188 bytes at offset zero
|
||||||
|
// rest is filled with zeros to reach the required
|
||||||
|
// cd mode 2 data sector size of 2048 bytes
|
||||||
|
// body: contains the binary data / code of the executable
|
||||||
|
// reqiures: executable code must be aligned to 4
|
||||||
|
// must be aligned to 2048 to run from a CD
|
||||||
|
// optinal: not aligned to 2048 (for console run only)
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackPs1::PackPs1(InputFile *f) :
|
PackPs1::PackPs1(InputFile *f) :
|
||||||
super(f), overlap(0), sa_cnt(0)
|
super(f), overlap(0), sa_cnt(0), cfile_size(0)
|
||||||
{
|
{
|
||||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 188);
|
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 188);
|
||||||
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
||||||
COMPILE_TIME_ASSERT(IH_BKUP == 40);
|
COMPILE_TIME_ASSERT(IH_BKUP == 40);
|
||||||
|
|
||||||
fdata_size = file_size - PS_HDR_SIZE;
|
fdata_size = file_size-PS_HDR_SIZE;
|
||||||
cfile_size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,8 +108,16 @@ int PackPs1::readFileHeader()
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(&ih, sizeof(ih));
|
fi->readx(&ih, sizeof(ih));
|
||||||
if ((memcmp(&ih.id,"PS-X EXE",8) != 0) && (memcmp(&ih.id,"EXE X-SP",8) != 0))
|
if ((memcmp(&ih.id,"PS-X EXE",8) != 0) && (memcmp(&ih.id,"EXE X-SP",8) != 0))
|
||||||
return 0;
|
return 0;
|
||||||
// FIXME: add some more sanity checks here
|
if (fdata_size != ih.tx_len || (ih.tx_len & 3))
|
||||||
|
{
|
||||||
|
if (!opt->force)
|
||||||
|
{
|
||||||
|
infoWarning("check header for file size (try --force)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cfile_size = fdata_size;
|
||||||
|
}
|
||||||
cfile_size = ih.tx_len;
|
cfile_size = ih.tx_len;
|
||||||
return UPX_F_PS1_EXE;
|
return UPX_F_PS1_EXE;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +125,9 @@ int PackPs1::readFileHeader()
|
||||||
|
|
||||||
bool PackPs1::checkFileHeader()
|
bool PackPs1::checkFileHeader()
|
||||||
{
|
{
|
||||||
// FIXME: check ih for legal but unsupported values
|
// FIXME: check ih for legal but unsupported values
|
||||||
|
if ((ih.text != 0) && (ih.data != 0))
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,26 +136,36 @@ bool PackPs1::checkFileHeader()
|
||||||
// patch util
|
// patch util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackPs1::patch_mips_le16(void *b, int blen, const void *old, unsigned new_)
|
void PackPs1::patch_mips_le(void *b, int blen, const void *old, unsigned new_)
|
||||||
{
|
{
|
||||||
unsigned char w[2];
|
size_t type = strlen((const char*)old);
|
||||||
|
|
||||||
set_le16(w, get_be16(old));
|
if (type == 2)
|
||||||
return patch_le16(b, blen, w, new_);
|
{
|
||||||
}
|
unsigned char w[2];
|
||||||
|
|
||||||
int PackPs1::patch_mips_le32(void *b, int blen, const void *old, unsigned new_)
|
set_le16(w, get_be16(old));
|
||||||
{
|
patch_le16(b, blen, w, MIPS_LO(new_));
|
||||||
unsigned char w[4];
|
}
|
||||||
|
else if (type == 4)
|
||||||
|
{
|
||||||
|
unsigned char w[4];
|
||||||
|
|
||||||
set_le32(w, get_be32(old));
|
set_le32(w, get_be32(old));
|
||||||
return patch_le32(b, blen, w, new_);
|
int boff = find(b, blen, w, 4);
|
||||||
}
|
|
||||||
|
|
||||||
void PackPs1::patch_hi_lo(void *b, int blen, const void *old_hi, const void *old_lo, unsigned new_)
|
if (boff == -1)
|
||||||
{
|
{
|
||||||
patch_mips_le16(b, blen, old_lo, MIPS_LO(new_));
|
patch_le16(b, blen, &w[0], MIPS_LO(new_));
|
||||||
patch_mips_le16(b, blen, old_hi, MIPS_HI(new_));
|
patch_le16(b, blen, &w[2], MIPS_HI(new_));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
patch_le32((unsigned char *)b + boff, (blen-boff), &w, new_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throwInternalError("bad marker length");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,14 +184,7 @@ bool PackPs1::canPack()
|
||||||
|
|
||||||
if (!checkFileHeader())
|
if (!checkFileHeader())
|
||||||
throwCantPack("unsupported header flags");
|
throwCantPack("unsupported header flags");
|
||||||
// FIXME: which of these checks belongs to checkFileHeader() ?
|
if (file_size <= (PS_HDR_SIZE*3) && !opt->force)
|
||||||
if (fdata_size != ih.tx_len || (ih.tx_len & 3))
|
|
||||||
{
|
|
||||||
if (!opt->force)
|
|
||||||
throwCantPack("check header for file size (try --force)");
|
|
||||||
cfile_size = fdata_size;
|
|
||||||
}
|
|
||||||
if (file_size <= (PS_HDR_SIZE*3) && !opt->force)
|
|
||||||
throwCantPack("file is too small (try --force)");
|
throwCantPack("file is too small (try --force)");
|
||||||
if (file_size > PS_MAX_SIZE && !opt->force)
|
if (file_size > PS_MAX_SIZE && !opt->force)
|
||||||
throwCantPack("file is too big (try --force)");
|
throwCantPack("file is too big (try --force)");
|
||||||
|
@ -175,24 +200,23 @@ bool PackPs1::canPack()
|
||||||
int PackPs1::buildLoader(const Filter *)
|
int PackPs1::buildLoader(const Filter *)
|
||||||
{
|
{
|
||||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||||
addLoader("PSXPREP0","PSXSTSZ0","PSXMAIN0",
|
addLoader("PS1MAIN0",
|
||||||
ih.tx_ptr & 0xffff ? "PSXJSTA0" : "PSXJSTH0",
|
ih.tx_ptr & 0xffff ? "PS1JSTA0" : "PS1JSTH0",
|
||||||
"PSXDECO0",
|
"PS1DECO0", NULL);
|
||||||
NULL);
|
|
||||||
#ifdef EIGHTBIT
|
#ifdef EIGHTBIT
|
||||||
if (ph.method == M_NRV2B_8)
|
if (ph.method == M_NRV2B_8)
|
||||||
addLoader("PSXN2BD0", NULL);
|
addLoader("PS1N2BD0", NULL);
|
||||||
else if (ph.method == M_NRV2D_8)
|
else if (ph.method == M_NRV2D_8)
|
||||||
addLoader("PSXN2DD0", NULL);
|
addLoader("PS1N2DD0", NULL);
|
||||||
else if (ph.method == M_NRV2E_8)
|
else if (ph.method == M_NRV2E_8)
|
||||||
addLoader("PSXN2ED0", NULL);
|
addLoader("PS1N2ED0", NULL);
|
||||||
#else
|
#else
|
||||||
if (ph.method == M_NRV2B_LE32)
|
if (ph.method == M_NRV2B_LE32)
|
||||||
addLoader("PSXN2BD0", NULL);
|
addLoader("PS1N2BD0", NULL);
|
||||||
else if (ph.method == M_NRV2D_LE32)
|
else if (ph.method == M_NRV2D_LE32)
|
||||||
addLoader("PSXN2DD0", NULL);
|
addLoader("PS1N2DD0", NULL);
|
||||||
else if (ph.method == M_NRV2E_LE32)
|
else if (ph.method == M_NRV2E_LE32)
|
||||||
addLoader("PSXN2ED0", NULL);
|
addLoader("PS1N2ED0", NULL);
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
|
@ -200,7 +224,7 @@ int PackPs1::buildLoader(const Filter *)
|
||||||
addLoader((sa_cnt > 0xfffc) ? "MSETBIG0" : "MSETSML0", // set small/big memset
|
addLoader((sa_cnt > 0xfffc) ? "MSETBIG0" : "MSETSML0", // set small/big memset
|
||||||
(ih.tx_len & 3) ? "MSETUAL0" : "MSETALG0", // un/aligned memset
|
(ih.tx_len & 3) ? "MSETUAL0" : "MSETALG0", // un/aligned memset
|
||||||
NULL);
|
NULL);
|
||||||
addLoader("PSXEXIT0", "IDENTSTR", "PSXPHDR0", NULL);
|
addLoader("PS1EXIT0", "IDENTSTR", "PS1PHDR0", "PS1RGSZ0", NULL);
|
||||||
return getLoaderSize();
|
return getLoaderSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,38 +235,41 @@ int PackPs1::buildLoader(const Filter *)
|
||||||
|
|
||||||
void PackPs1::pack(OutputFile *fo)
|
void PackPs1::pack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
// read file
|
|
||||||
ibuf.alloc(fdata_size);
|
ibuf.alloc(fdata_size);
|
||||||
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
obuf.allocForCompression(fdata_size);
|
||||||
fi->readx(ibuf, fdata_size);
|
|
||||||
|
|
||||||
// this scans the end of file for 2048 bytes sector alignment
|
|
||||||
// this should be padded with zeros
|
|
||||||
const upx_byte *p_scan = ibuf+(fdata_size-1);
|
const upx_byte *p_scan = ibuf+(fdata_size-1);
|
||||||
while (!(*p_scan--)) { if ((sa_cnt += 1) > (0xfffc<<3)) break; }
|
|
||||||
if (sa_cnt > 0xfffc)
|
|
||||||
sa_cnt = ALIGN_DOWN(sa_cnt, 8);
|
|
||||||
else
|
|
||||||
sa_cnt = ALIGN_DOWN(sa_cnt, 4);
|
|
||||||
|
|
||||||
obuf.allocForCompression(fdata_size - sa_cnt);
|
// read file
|
||||||
|
fi->seek(PS_HDR_SIZE,SEEK_SET);
|
||||||
|
fi->readx(ibuf,fdata_size);
|
||||||
|
|
||||||
|
// scan the end of file for 2048 bytes sector alignment
|
||||||
|
// normaly padded with zeros
|
||||||
|
// this removed space will secure in-place decompression
|
||||||
|
while (!(*p_scan--)) { if (sa_cnt++ > (0xfffc<<3)) break; }
|
||||||
|
if (sa_cnt > 0xfffc)
|
||||||
|
sa_cnt = ALIGN_DOWN(sa_cnt,8);
|
||||||
|
else
|
||||||
|
sa_cnt = ALIGN_DOWN(sa_cnt,4);
|
||||||
|
|
||||||
// prepare packheader
|
// prepare packheader
|
||||||
ph.u_len = fdata_size - sa_cnt;
|
ph.u_len = (fdata_size - sa_cnt);
|
||||||
ph.filter = 0;
|
ph.filter = 0;
|
||||||
|
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
// compress (max_match = 65535)
|
// compress (max_match = 65535)
|
||||||
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
||||||
|
|
||||||
overlap = 0;
|
|
||||||
if (ph.overlap_overhead > sa_cnt)
|
if (ph.overlap_overhead > sa_cnt)
|
||||||
{
|
{
|
||||||
if (!opt->force)
|
if (!opt->force)
|
||||||
|
{
|
||||||
|
infoWarning("not in-place decompressible");
|
||||||
throwCantPack("packed data overlap (try --force)");
|
throwCantPack("packed data overlap (try --force)");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
overlap = ALIGN_UP(ph.overlap_overhead-sa_cnt, 4);
|
overlap = ALIGN_UP((ph.overlap_overhead-sa_cnt),4);
|
||||||
opt->info_mode += !opt->info_mode ? 1 : 0;
|
opt->info_mode += !opt->info_mode ? 1 : 0;
|
||||||
infoWarning("%s will load to a %d bytes higher offset",fi->getName(),overlap);
|
infoWarning("%s will load to a %d bytes higher offset",fi->getName(),overlap);
|
||||||
}
|
}
|
||||||
|
@ -253,76 +280,72 @@ void PackPs1::pack(OutputFile *fo)
|
||||||
oh.ih_csum = upx_adler32(&ih.epc, IH_BKUP);
|
oh.ih_csum = upx_adler32(&ih.epc, IH_BKUP);
|
||||||
|
|
||||||
const int lsize = getLoaderSize();
|
const int lsize = getLoaderSize();
|
||||||
const int h_len = lsize - getLoaderSectionStart("IDENTSTR");
|
|
||||||
const int e_len = lsize - h_len;
|
|
||||||
const int d_len = e_len - getLoaderSectionStart("PSXDECO0");
|
|
||||||
int s_len;
|
|
||||||
getLoaderSection("PSXSTSZ0", &s_len); // get size of pushed/poped regs
|
|
||||||
|
|
||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
memcpy(loader, getLoader(), lsize);
|
memcpy(loader,getLoader(),lsize);
|
||||||
|
|
||||||
const unsigned pad_code = ALIGN_GAP(ph.c_len, 4);
|
|
||||||
unsigned pad = 0;
|
unsigned pad = 0;
|
||||||
if (!opt->ps1.no_align)
|
unsigned filelen = ALIGN_UP((cfile_size ? cfile_size : ih.tx_len), 4);
|
||||||
{
|
unsigned pad_code = TIL_ALIGNED(ph.c_len, 4);
|
||||||
pad = ALIGN_DOWN(cfile_size, 4);
|
|
||||||
// align the packed file to mode 2 data sector size (2048)
|
|
||||||
pad = ALIGN_GAP(ph.c_len+pad_code+e_len+overlap, PS_HDR_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned decomp_data_start = NOCACHE(ih.tx_ptr);
|
const int h_len = lsize-getLoaderSectionStart("IDENTSTR");
|
||||||
|
const int e_len = lsize-h_len;
|
||||||
|
const int d_len = e_len-getLoaderSectionStart("PS1DECO0");
|
||||||
|
const int s_len = get_le32(&loader[getLoaderSectionStart("PS1RGSZ0")]);
|
||||||
|
|
||||||
// set the offset for compressed stuff at the very end of file
|
// set the offset for compressed stuff at the very end of file
|
||||||
const unsigned comp_data_start = NOCACHE(((decomp_data_start+pad+overlap)-ph.c_len));
|
const unsigned decomp_data_start = ih.tx_ptr;
|
||||||
|
const unsigned comp_data_start = ((decomp_data_start + filelen + overlap) - ph.c_len);
|
||||||
|
const unsigned entry = comp_data_start - e_len - pad_code;
|
||||||
|
|
||||||
const unsigned entry = NOCACHE(comp_data_start - e_len - pad_code);
|
|
||||||
patchPackHeader(loader,lsize);
|
patchPackHeader(loader,lsize);
|
||||||
patch_mips_le32(loader,e_len,"JPEP",MIPS_JP(ih.epc));
|
patch_mips_le(loader,e_len,"JPEP",MIPS_JP(ih.epc));
|
||||||
if (sa_cnt)
|
|
||||||
patch_mips_le16(loader,e_len,"SC",
|
|
||||||
MIPS_LO(sa_cnt > 0xfffc ? sa_cnt >> 3 : sa_cnt));
|
|
||||||
if (ih.tx_ptr & 0xffff)
|
|
||||||
// we have to set the high/low value of the offset
|
|
||||||
patch_hi_lo(loader,e_len,"OH","OL",decomp_data_start);
|
|
||||||
else
|
|
||||||
// only high has to be set, this will save 4 bytes
|
|
||||||
patch_mips_le16(loader,e_len,"OH",decomp_data_start>>16);
|
|
||||||
patch_hi_lo(loader,e_len,"CH","CL",comp_data_start);
|
|
||||||
patch_hi_lo(loader,e_len,"DH","DL",entry+(e_len-d_len));
|
|
||||||
patch_mips_le16(loader,e_len,"LS",d_len+s_len);
|
|
||||||
|
|
||||||
// set the file load address
|
if (sa_cnt)
|
||||||
oh.tx_ptr = entry - pad;
|
patch_mips_le(loader,e_len,"SC",MIPS_LO(sa_cnt > 0xfffc ? sa_cnt >> 3 : sa_cnt));
|
||||||
// set the correct file len in header
|
if (ih.tx_ptr & 0xffff)
|
||||||
oh.tx_len = ph.c_len + pad + e_len + pad_code;
|
patch_mips_le(loader,e_len,"DECO",decomp_data_start);
|
||||||
// set the code entry
|
else
|
||||||
|
patch_mips_le(loader,e_len,"DE",MIPS_HI(decomp_data_start));
|
||||||
|
patch_mips_le(loader,e_len,"COMP",comp_data_start);
|
||||||
|
patch_mips_le(loader,e_len,"DCRT",entry + (e_len - d_len));
|
||||||
|
patch_mips_le(loader,e_len,"LS",d_len + s_len);
|
||||||
|
|
||||||
|
oh.tx_ptr = entry;
|
||||||
|
oh.tx_len = ph.c_len + e_len + pad_code;
|
||||||
oh.epc = entry;
|
oh.epc = entry;
|
||||||
|
|
||||||
// prepare paddata
|
if (!opt->ps1.no_align)
|
||||||
MemBuffer paddata(PS_HDR_SIZE);
|
{
|
||||||
paddata.clear();
|
pad = oh.tx_len;
|
||||||
|
oh.tx_len = ALIGN_UP(oh.tx_len, CD_SEC);
|
||||||
|
pad = oh.tx_len - pad;
|
||||||
|
oh.tx_ptr -= pad;
|
||||||
|
}
|
||||||
|
|
||||||
// write loader + compressed file
|
ibuf.clear(0,fdata_size);
|
||||||
fo->write(&oh, sizeof(oh));
|
upx_bytep paddata = ibuf;
|
||||||
// id & upx header
|
|
||||||
fo->write(loader+e_len, h_len);
|
// ps1_exe_t structure 188 bytes
|
||||||
// FIXME: why do we need this double align here ???
|
fo->write(&oh,sizeof(oh));
|
||||||
// align the ps exe header (mode 2 sector data size)
|
// id & upx header some more bytes
|
||||||
fo->write(paddata, PS_HDR_SIZE - (sizeof(oh) + h_len));
|
fo->write(loader+e_len,h_len);
|
||||||
// align the file
|
// remember? header size is 2048 bytes so we write the rest
|
||||||
fo->write(paddata, pad);
|
fo->write(paddata,PS_HDR_SIZE - fo->getBytesWritten());
|
||||||
// entry
|
|
||||||
fo->write(loader, e_len);
|
// padding placed in front of the runtime, because we don't want to overwrite other
|
||||||
// align the mips runtime code
|
// than the allowed space (ih.tx_ptr >= allowed space <= (ih.tx_ptr+ih.tx_len))
|
||||||
fo->write(paddata, pad_code);
|
if (pad)
|
||||||
// write compressed data
|
fo->write(paddata,pad);
|
||||||
fo->write(obuf, ph.c_len);
|
// runtime
|
||||||
|
fo->write(loader,e_len);
|
||||||
|
// does the code need to be padded? must be aligned to 4!
|
||||||
|
if (pad_code)
|
||||||
|
fo->write(paddata,pad_code);
|
||||||
|
// compressed binary / data
|
||||||
|
fo->write(obuf,ph.c_len);
|
||||||
|
|
||||||
// verify
|
|
||||||
verifyOverlappingDecompression();
|
verifyOverlappingDecompression();
|
||||||
|
|
||||||
// finally check the compression ratio
|
|
||||||
if (!checkFinalCompressionRatio(fo))
|
if (!checkFinalCompressionRatio(fo))
|
||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
|
|
||||||
|
@ -349,12 +372,9 @@ int PackPs1::canUnpack()
|
||||||
if (!readPackHeader(1024))
|
if (!readPackHeader(1024))
|
||||||
return false;
|
return false;
|
||||||
// check header as set by packer
|
// check header as set by packer
|
||||||
if (ih.ih_csum != upx_adler32(&ih.ih_bkup, IH_BKUP))
|
if (ih.ih_csum != upx_adler32(&ih.ih_bkup, IH_BKUP)
|
||||||
throwCantUnpack("file is possibly modified/hacked/protected; take care!");
|
&& (ph.c_len >= fdata_size))
|
||||||
if (ph.c_len >= fdata_size)
|
|
||||||
throwCantUnpack("header damaged");
|
throwCantUnpack("header damaged");
|
||||||
// FIXME: add a check for (oh.tx_len - ph.u_len) in canUnpack() below
|
|
||||||
assert(oh.tx_len >= ph.u_len);
|
|
||||||
// generic check
|
// generic check
|
||||||
if (!checkFileHeader())
|
if (!checkFileHeader())
|
||||||
throwCantUnpack("unsupported header flags");
|
throwCantUnpack("unsupported header flags");
|
||||||
|
@ -368,7 +388,12 @@ assert(oh.tx_len >= ph.u_len);
|
||||||
|
|
||||||
void PackPs1::unpack(OutputFile *fo)
|
void PackPs1::unpack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
|
// restore orig exec hdr
|
||||||
|
memcpy(&oh, &ih, sizeof(ih));
|
||||||
|
memcpy(&oh.epc, &ih.ih_bkup, IH_BKUP);
|
||||||
|
|
||||||
// check for removed sector alignment
|
// check for removed sector alignment
|
||||||
|
assert(oh.tx_len >= ph.u_len);
|
||||||
const unsigned pad = oh.tx_len - ph.u_len;
|
const unsigned pad = oh.tx_len - ph.u_len;
|
||||||
|
|
||||||
ibuf.alloc(fdata_size);
|
ibuf.alloc(fdata_size);
|
||||||
|
@ -377,9 +402,6 @@ void PackPs1::unpack(OutputFile *fo)
|
||||||
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
||||||
fi->readx(ibuf, fdata_size);
|
fi->readx(ibuf, fdata_size);
|
||||||
|
|
||||||
// restore orig exec hdr
|
|
||||||
memcpy(&oh, &ih, sizeof(ih));
|
|
||||||
memcpy(&oh.epc, &ih.ih_bkup, IH_BKUP);
|
|
||||||
// clear backup and checksum of header
|
// clear backup and checksum of header
|
||||||
memset(&oh.ih_bkup, 0, IH_BKUP+4);
|
memset(&oh.ih_bkup, 0, IH_BKUP+4);
|
||||||
|
|
||||||
|
|
15
src/p_ps1.h
15
src/p_ps1.h
|
@ -56,6 +56,7 @@ public:
|
||||||
virtual int canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void patch_mips_le(void *b, int blen, const void *old, unsigned new_);
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
|
||||||
virtual int readFileHeader();
|
virtual int readFileHeader();
|
||||||
|
@ -63,12 +64,19 @@ protected:
|
||||||
|
|
||||||
struct ps1_exe_t
|
struct ps1_exe_t
|
||||||
{
|
{
|
||||||
|
// ident string
|
||||||
char id[8];
|
char id[8];
|
||||||
|
// contains NULL in normal ps-x exe
|
||||||
LE32 text;
|
LE32 text;
|
||||||
|
// contains NULL in normal ps-x exe
|
||||||
LE32 data;
|
LE32 data;
|
||||||
|
// entry offset
|
||||||
LE32 epc;
|
LE32 epc;
|
||||||
|
// gp register value load at execution
|
||||||
LE32 gp;
|
LE32 gp;
|
||||||
|
// load offset of binary data
|
||||||
LE32 tx_ptr;
|
LE32 tx_ptr;
|
||||||
|
// file length
|
||||||
LE32 tx_len;
|
LE32 tx_len;
|
||||||
LE32 da_ptr;
|
LE32 da_ptr;
|
||||||
LE32 da_len;
|
LE32 da_len;
|
||||||
|
@ -77,7 +85,9 @@ protected:
|
||||||
LE32 sd_ptr;
|
LE32 sd_ptr;
|
||||||
LE32 sd_len;
|
LE32 sd_len;
|
||||||
LE32 sp,fp,gp0,ra,k0;
|
LE32 sp,fp,gp0,ra,k0;
|
||||||
|
// origin of executable Jap/USA/Europe
|
||||||
char origin[60];
|
char origin[60];
|
||||||
|
|
||||||
// some safety space after that
|
// some safety space after that
|
||||||
char pad[8];
|
char pad[8];
|
||||||
// i'll place the backup of the original
|
// i'll place the backup of the original
|
||||||
|
@ -100,11 +110,6 @@ protected:
|
||||||
unsigned fdata_size;
|
unsigned fdata_size;
|
||||||
// calculated filesize
|
// calculated filesize
|
||||||
unsigned cfile_size;
|
unsigned cfile_size;
|
||||||
|
|
||||||
protected:
|
|
||||||
int patch_mips_le16(void *b, int blen, const void *old, unsigned new_);
|
|
||||||
int patch_mips_le32(void *b, int blen, const void *old, unsigned new_);
|
|
||||||
void patch_hi_lo(void *b, int blen, const void *old_hi, const void *old_lo, unsigned new_);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,18 +32,23 @@
|
||||||
|
|
||||||
#include <mr3k/macros.ash>
|
#include <mr3k/macros.ash>
|
||||||
|
|
||||||
|
#define SZ_REG 4
|
||||||
|
|
||||||
do_regs MACRO _w
|
do_regs MACRO _w
|
||||||
_w at,0(sp)
|
_w at,SZ_REG*0(sp)
|
||||||
_w a0,4(sp)
|
_w a0,SZ_REG*1(sp)
|
||||||
_w a1,8(sp)
|
_w a1,SZ_REG*2(sp)
|
||||||
_w a2,12(sp)
|
_w a2,SZ_REG*3(sp)
|
||||||
_w a3,16(sp)
|
_w a3,SZ_REG*4(sp)
|
||||||
_w v0,20(sp)
|
_w v0,SZ_REG*5(sp)
|
||||||
_w v1,24(sp)
|
_w v1,SZ_REG*6(sp)
|
||||||
_w ra,28(sp)
|
_w ra,SZ_REG*7(sp)
|
||||||
do_regs ENDM
|
do_regs ENDM
|
||||||
|
|
||||||
DEFINE REG_SZ = (8*4)
|
#define REG_SZ (8*SZ_REG)
|
||||||
|
|
||||||
|
#define HI(a) (a >> 16)
|
||||||
|
#define LO(a) (a & 0xffff)
|
||||||
|
|
||||||
ORG 0
|
ORG 0
|
||||||
|
|
||||||
|
@ -52,19 +57,14 @@ DEFINE REG_SZ = (8*4)
|
||||||
; =============
|
; =============
|
||||||
|
|
||||||
entry:
|
entry:
|
||||||
; __PSXPREP0__ ; needed by packer to calc the LS value
|
; __PS1MAIN0__
|
||||||
addiu at,zero,'LS' ; size of decomp. routine
|
addiu at,zero,'LS' ; size of decomp. routine
|
||||||
sub sp,at ; adjust the stack with this size
|
subu sp,at ; adjust the stack with this size
|
||||||
; __PSXPREPZ__ ; needed by packer to calc the LS value
|
|
||||||
; __PSXSTSZ0__ ; needed by packer to calc the LS value
|
|
||||||
do_regs sw ; push used regs
|
do_regs sw ; push used regs
|
||||||
; __PSXSTSZZ__
|
|
||||||
; __PSXMAIN0__
|
|
||||||
subiu a0,at,REG_SZ ; a0 = counter copyloop
|
subiu a0,at,REG_SZ ; a0 = counter copyloop
|
||||||
addiu a3,sp,REG_SZ ; get offset for decomp. routine
|
addiu a3,sp,REG_SZ ; get offset for decomp. routine
|
||||||
move a1,a3
|
move a1,a3
|
||||||
lui a2,'DH' ; load decomp routine HI offset
|
li a2,'DCRT' ; load decompression routine's offset
|
||||||
ori a2,'DL' ; and the LO offset
|
|
||||||
copyloop:
|
copyloop:
|
||||||
addi a0,-4
|
addi a0,-4
|
||||||
lw at,0(a2) ; memcpy *a2 -> at -> *a1
|
lw at,0(a2) ; memcpy *a2 -> at -> *a1
|
||||||
|
@ -73,23 +73,21 @@ copyloop:
|
||||||
bnez a0,copyloop
|
bnez a0,copyloop
|
||||||
addiu a1,4
|
addiu a1,4
|
||||||
|
|
||||||
lui a0,'CH' ; load COMPDATA HI offset
|
li a0,'COMP' ; load COMPDATA HI offset
|
||||||
ori a0,'CL' ; and the LO part
|
; li a1,'CDSZ' ; compressed data size !disabled
|
||||||
; lui a1,'LH' ; compressed data length
|
; __PS1MAINZ__
|
||||||
; ori a1,'LL' ; HI and LO !disabled
|
|
||||||
; __PSXMAINZ__
|
|
||||||
|
|
||||||
; =============
|
; =============
|
||||||
|
|
||||||
; __PSXJSTA0__
|
; __PS1JSTA0__
|
||||||
lui a2,'OH' ; load DECOMPDATA HI offset
|
lui a2,HI('DECO') ; load DECOMPDATA HI offset
|
||||||
jr a3
|
jr a3
|
||||||
ori a2,'OL' ; load DECOMPDATA LO offset
|
ori a2,LO('DECO') ; load DECOMPDATA LO offset
|
||||||
; __PSXJSTAZ__
|
; __PS1JSTAZ__
|
||||||
; __PSXJSTH0__
|
; __PS1JSTH0__
|
||||||
jr a3 ;
|
jr a3
|
||||||
lui a2,'OH' ; same for HI only !(offset&0xffff)
|
lui a2,HI('DECO') ; same for HI only !(offset&0xffff)
|
||||||
; __PSXJSTHZ__
|
; __PS1JSTHZ__
|
||||||
|
|
||||||
; =============
|
; =============
|
||||||
; ============= DECOMPRESSION
|
; ============= DECOMPRESSION
|
||||||
|
@ -104,17 +102,17 @@ copyloop:
|
||||||
# define SMALL
|
# define SMALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
; __PSXDECO0__
|
; __PS1DECO0__
|
||||||
; __PSXDECOZ__
|
; __PS1DECOZ__
|
||||||
; __PSXN2BD0__
|
; __PS1N2BD0__
|
||||||
#include <mr3k/n2b_d.ash>
|
#include <mr3k/n2b_d.ash>
|
||||||
; __PSXN2BDZ__
|
; __PS1N2BDZ__
|
||||||
; __PSXN2DD0__
|
; __PS1N2DD0__
|
||||||
#include <mr3k/n2d_d.ash>
|
#include <mr3k/n2d_d.ash>
|
||||||
; __PSXN2DDZ__
|
; __PS1N2DDZ__
|
||||||
; __PSXN2ED0__
|
; __PS1N2ED0__
|
||||||
#include <mr3k/n2e_d.ash>
|
#include <mr3k/n2e_d.ash>
|
||||||
; __PSXN2EDZ__
|
; __PS1N2EDZ__
|
||||||
|
|
||||||
; =============
|
; =============
|
||||||
|
|
||||||
|
@ -146,18 +144,18 @@ memset_unaligned:
|
||||||
|
|
||||||
; =============
|
; =============
|
||||||
|
|
||||||
; __PSXEXIT0__
|
; __PS1EXIT0__
|
||||||
li t2,160 ; flushes
|
li t2,160 ; flushes
|
||||||
jalr ra,t2 ; instruction
|
jalr ra,t2 ; instruction
|
||||||
li t1,68 ; cache
|
li t1,68 ; cache
|
||||||
do_regs lw ; pop used regs
|
do_regs lw ; pop used regs
|
||||||
DW 'JPEP' ; marker for the entry jump
|
DW 'JPEP' ; marker for the entry jump
|
||||||
addu sp,at
|
addu sp,at
|
||||||
; __PSXEXITZ__
|
; __PS1EXITZ__
|
||||||
|
|
||||||
; =============
|
; =============
|
||||||
|
|
||||||
; __PSXPHDR0__
|
; __PS1PHDR0__
|
||||||
DB 85,80,88,33 ; 0 UPX_MAGIC_LE32
|
DB 85,80,88,33 ; 0 UPX_MAGIC_LE32
|
||||||
; another magic for PackHeader::putPackHeader
|
; another magic for PackHeader::putPackHeader
|
||||||
DB 161,216,208,213 ; UPX_MAGIC2_LE32
|
DB 161,216,208,213 ; UPX_MAGIC2_LE32
|
||||||
|
@ -168,15 +166,19 @@ memset_unaligned:
|
||||||
DW 0 ; 24 original file size
|
DW 0 ; 24 original file size
|
||||||
DB 0 ; 28 filter id
|
DB 0 ; 28 filter id
|
||||||
DB 0 ; 29 filter cto
|
DB 0 ; 29 filter cto
|
||||||
DB 0 ; unused
|
DB 0 ; unsused
|
||||||
DB 45 ; 31 header checksum
|
DB 45 ; 31 header checksum
|
||||||
; __PSXPHDRZ__
|
; __PS1PHDRZ__
|
||||||
|
|
||||||
|
; =============
|
||||||
|
|
||||||
|
; __PS1RGSZ0__
|
||||||
|
DW REG_SZ
|
||||||
|
; __PS1RGSZZ__
|
||||||
eof:
|
eof:
|
||||||
|
|
||||||
; section .data
|
; section .data
|
||||||
DW -1
|
DW -1
|
||||||
DH eof
|
DH eof
|
||||||
|
|
||||||
|
|
||||||
; vi:ts=8:et:nowrap
|
; vi:ts=8:et:nowrap
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* l_ps1.h -- created from l_ps1.bin, 1590 (0x636) bytes
|
/* l_ps1.h -- created from l_ps1.bin, 1570 (0x622) bytes
|
||||||
|
|
||||||
This file is part of the UPX executable compressor.
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
@ -26,17 +26,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define NRV_LOADER_ADLER32 0x6ad553ee
|
#define NRV_LOADER_ADLER32 0x0cf34d3a
|
||||||
#define NRV_LOADER_CRC32 0x7be8c655
|
#define NRV_LOADER_CRC32 0xd78b1eb4
|
||||||
|
|
||||||
unsigned char nrv_loader[1590] = {
|
unsigned char nrv_loader[1570] = {
|
||||||
83, 76, 1, 36, 34,232,161, 3, 0, 0,161,175, 4, 0,164,175, /* 0x 0 */
|
83, 76, 1, 36, 35,232,161, 3, 0, 0,161,175, 4, 0,164,175, /* 0x 0 */
|
||||||
8, 0,165,175, 12, 0,166,175, 16, 0,167,175, 20, 0,162,175, /* 0x 10 */
|
8, 0,165,175, 12, 0,166,175, 16, 0,167,175, 20, 0,162,175, /* 0x 10 */
|
||||||
24, 0,163,175, 28, 0,191,175,224,255, 36, 36, 32, 0,167, 39, /* 0x 20 */
|
24, 0,163,175, 28, 0,191,175,224,255, 36, 36, 32, 0,167, 39, /* 0x 20 */
|
||||||
33, 40,224, 0, 72, 68, 6, 60, 76, 68,198, 52,252,255,132, 32, /* 0x 30 */
|
33, 40,224, 0, 67, 68, 6, 60, 84, 82,198, 52,252,255,132, 32, /* 0x 30 */
|
||||||
0, 0,193,140, 4, 0,198, 36, 0, 0,161,172,251,255,128, 20, /* 0x 40 */
|
0, 0,193,140, 4, 0,198, 36, 0, 0,161,172,251,255,128, 20, /* 0x 40 */
|
||||||
4, 0,165, 36, 72, 67, 4, 60, 76, 67,132, 52, 72, 79, 6, 60, /* 0x 50 */
|
4, 0,165, 36, 79, 67, 4, 60, 80, 77,132, 52, 69, 68, 6, 60, /* 0x 50 */
|
||||||
8, 0,224, 0, 76, 79,198, 52, 8, 0,224, 0, 72, 79, 6, 60, /* 0x 60 */
|
8, 0,224, 0, 79, 67,198, 52, 8, 0,224, 0, 69, 68, 6, 60, /* 0x 60 */
|
||||||
33, 72, 0, 0, 1, 0, 11, 36, 33, 64,128, 0, 60, 0, 17, 4, /* 0x 70 */
|
33, 72, 0, 0, 1, 0, 11, 36, 33, 64,128, 0, 60, 0, 17, 4, /* 0x 70 */
|
||||||
127, 0, 34, 49, 6, 0, 64, 16, 1, 0, 3, 36, 0, 0, 2,145, /* 0x 80 */
|
127, 0, 34, 49, 6, 0, 64, 16, 1, 0, 3, 36, 0, 0, 2,145, /* 0x 80 */
|
||||||
1, 0, 8, 37, 0, 0,194,160,248,255, 0, 16, 1, 0,198, 36, /* 0x 90 */
|
1, 0, 8, 37, 0, 0,194,160,248,255, 0, 16, 1, 0,198, 36, /* 0x 90 */
|
||||||
|
@ -106,28 +106,27 @@ unsigned char nrv_loader[1590] = {
|
||||||
16, 0,167,143, 20, 0,162,143, 24, 0,163,143, 28, 0,191,143, /* 0x 490 */
|
16, 0,167,143, 20, 0,162,143, 24, 0,163,143, 28, 0,191,143, /* 0x 490 */
|
||||||
80, 69, 80, 74, 33,232,161, 3, 85, 80, 88, 33,161,216,208,213, /* 0x 4a0 */
|
80, 69, 80, 74, 33,232,161, 3, 85, 80, 88, 33,161,216,208,213, /* 0x 4a0 */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 4b0 */
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 4b0 */
|
||||||
0, 0, 0, 0, 0, 0, 0, 45, 80, 83, 88, 80, 82, 69, 80, 48, /* 0x 4c0 */
|
0, 0, 0, 0, 0, 0, 0, 45, 32, 0, 0, 0, 80, 83, 49, 77, /* 0x 4c0 */
|
||||||
0, 0, 0, 0, 80, 83, 88, 80, 82, 69, 80, 90, 8, 0, 0, 0, /* 0x 4d0 */
|
65, 73, 78, 48, 0, 0, 0, 0, 80, 83, 49, 77, 65, 73, 78, 90, /* 0x 4d0 */
|
||||||
80, 83, 88, 83, 84, 83, 90, 48, 8, 0, 0, 0, 80, 83, 88, 83, /* 0x 4e0 */
|
92, 0, 0, 0, 80, 83, 49, 74, 83, 84, 65, 48, 92, 0, 0, 0, /* 0x 4e0 */
|
||||||
84, 83, 90, 90, 40, 0, 0, 0, 80, 83, 88, 77, 65, 73, 78, 48, /* 0x 4f0 */
|
80, 83, 49, 74, 83, 84, 65, 90,104, 0, 0, 0, 80, 83, 49, 74, /* 0x 4f0 */
|
||||||
40, 0, 0, 0, 80, 83, 88, 77, 65, 73, 78, 90, 92, 0, 0, 0, /* 0x 500 */
|
83, 84, 72, 48,104, 0, 0, 0, 80, 83, 49, 74, 83, 84, 72, 90, /* 0x 500 */
|
||||||
80, 83, 88, 74, 83, 84, 65, 48, 92, 0, 0, 0, 80, 83, 88, 74, /* 0x 510 */
|
112, 0, 0, 0, 80, 83, 49, 68, 69, 67, 79, 48,112, 0, 0, 0, /* 0x 510 */
|
||||||
83, 84, 65, 90,104, 0, 0, 0, 80, 83, 88, 74, 83, 84, 72, 48, /* 0x 520 */
|
80, 83, 49, 68, 69, 67, 79, 90,112, 0, 0, 0, 80, 83, 49, 78, /* 0x 520 */
|
||||||
104, 0, 0, 0, 80, 83, 88, 74, 83, 84, 72, 90,112, 0, 0, 0, /* 0x 530 */
|
50, 66, 68, 48,112, 0, 0, 0, 80, 83, 49, 78, 50, 66, 68, 90, /* 0x 530 */
|
||||||
80, 83, 88, 68, 69, 67, 79, 48,112, 0, 0, 0, 80, 83, 88, 68, /* 0x 540 */
|
148, 1, 0, 0, 80, 83, 49, 78, 50, 68, 68, 48,148, 1, 0, 0, /* 0x 540 */
|
||||||
69, 67, 79, 90,112, 0, 0, 0, 80, 83, 88, 78, 50, 66, 68, 48, /* 0x 550 */
|
80, 83, 49, 78, 50, 68, 68, 90,220, 2, 0, 0, 80, 83, 49, 78, /* 0x 550 */
|
||||||
112, 0, 0, 0, 80, 83, 88, 78, 50, 66, 68, 90,148, 1, 0, 0, /* 0x 560 */
|
50, 69, 68, 48,220, 2, 0, 0, 80, 83, 49, 78, 50, 69, 68, 90, /* 0x 560 */
|
||||||
80, 83, 88, 78, 50, 68, 68, 48,148, 1, 0, 0, 80, 83, 88, 78, /* 0x 570 */
|
68, 4, 0, 0, 77, 83, 69, 84, 66, 73, 71, 48, 68, 4, 0, 0, /* 0x 570 */
|
||||||
50, 68, 68, 90,220, 2, 0, 0, 80, 83, 88, 78, 50, 69, 68, 48, /* 0x 580 */
|
77, 83, 69, 84, 66, 73, 71, 90, 76, 4, 0, 0, 77, 83, 69, 84, /* 0x 580 */
|
||||||
220, 2, 0, 0, 80, 83, 88, 78, 50, 69, 68, 90, 68, 4, 0, 0, /* 0x 590 */
|
83, 77, 76, 48, 76, 4, 0, 0, 77, 83, 69, 84, 83, 77, 76, 90, /* 0x 590 */
|
||||||
77, 83, 69, 84, 66, 73, 71, 48, 68, 4, 0, 0, 77, 83, 69, 84, /* 0x 5a0 */
|
80, 4, 0, 0, 77, 83, 69, 84, 65, 76, 71, 48, 80, 4, 0, 0, /* 0x 5a0 */
|
||||||
66, 73, 71, 90, 76, 4, 0, 0, 77, 83, 69, 84, 83, 77, 76, 48, /* 0x 5b0 */
|
77, 83, 69, 84, 65, 76, 71, 90, 96, 4, 0, 0, 77, 83, 69, 84, /* 0x 5b0 */
|
||||||
76, 4, 0, 0, 77, 83, 69, 84, 83, 77, 76, 90, 80, 4, 0, 0, /* 0x 5c0 */
|
85, 65, 76, 48, 96, 4, 0, 0, 77, 83, 69, 84, 85, 65, 76, 90, /* 0x 5c0 */
|
||||||
77, 83, 69, 84, 65, 76, 71, 48, 80, 4, 0, 0, 77, 83, 69, 84, /* 0x 5d0 */
|
116, 4, 0, 0, 80, 83, 49, 69, 88, 73, 84, 48,116, 4, 0, 0, /* 0x 5d0 */
|
||||||
65, 76, 71, 90, 96, 4, 0, 0, 77, 83, 69, 84, 85, 65, 76, 48, /* 0x 5e0 */
|
80, 83, 49, 69, 88, 73, 84, 90,168, 4, 0, 0, 80, 83, 49, 80, /* 0x 5e0 */
|
||||||
96, 4, 0, 0, 77, 83, 69, 84, 85, 65, 76, 90,116, 4, 0, 0, /* 0x 5f0 */
|
72, 68, 82, 48,168, 4, 0, 0, 80, 83, 49, 80, 72, 68, 82, 90, /* 0x 5f0 */
|
||||||
80, 83, 88, 69, 88, 73, 84, 48,116, 4, 0, 0, 80, 83, 88, 69, /* 0x 600 */
|
200, 4, 0, 0, 80, 83, 49, 82, 71, 83, 90, 48,200, 4, 0, 0, /* 0x 600 */
|
||||||
88, 73, 84, 90,168, 4, 0, 0, 80, 83, 88, 80, 72, 68, 82, 48, /* 0x 610 */
|
80, 83, 49, 82, 71, 83, 90, 90,204, 4, 0, 0,255,255,255,255, /* 0x 610 */
|
||||||
168, 4, 0, 0, 80, 83, 88, 80, 72, 68, 82, 90,200, 4, 0, 0, /* 0x 620 */
|
204, 4 /* 0x 620 */
|
||||||
255,255,255,255,200, 4 /* 0x 630 */
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user