work on PackLinuxElf32arm, including nrv2d and lzma
This commit is contained in:
+23
-91
@@ -190,10 +190,18 @@ void
|
|||||||
PackLinuxElf::addStubEntrySections(Filter const *)
|
PackLinuxElf::addStubEntrySections(Filter const *)
|
||||||
{
|
{
|
||||||
addLoader("ELFMAINX", NULL);
|
addLoader("ELFMAINX", NULL);
|
||||||
|
//addLoader(getDecompressorSections(), NULL);
|
||||||
|
addLoader(
|
||||||
|
( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL"
|
||||||
|
: M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL"
|
||||||
|
: M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL"
|
||||||
|
: M_IS_LZMA(ph.method) ? "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"
|
||||||
|
: NULL), NULL);
|
||||||
|
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PackLinuxElf::addLinkerSymbols(Filter const *)
|
void PackLinuxElf::addLinkerSymbols(Filter const *)
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
@@ -224,19 +232,6 @@ Linker* PackLinuxElf64amd::newLinker() const
|
|||||||
return new ElfLinkerAMD64;
|
return new ElfLinkerAMD64;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxElf64amd::addStubEntrySections(Filter const *)
|
|
||||||
{
|
|
||||||
addLoader("ELFMAINX", NULL);
|
|
||||||
//addLoader(getDecompressorSections(), NULL);
|
|
||||||
addLoader(
|
|
||||||
( M_IS_NRV2E(ph.method) ? "NRV_COMMON,NRV2E"
|
|
||||||
: M_IS_NRV2D(ph.method) ? "NRV_COMMON,NRV2D"
|
|
||||||
: M_IS_NRV2B(ph.method) ? "NRV_COMMON,NRV2B"
|
|
||||||
: M_IS_LZMA(ph.method) ? "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"
|
|
||||||
: NULL), NULL);
|
|
||||||
addLoader("ELFMAINY,IDENTSTR,ELFMAINZ,FOLDEXEC", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int const *
|
int const *
|
||||||
PackLinuxElf::getCompressionMethods(int method, int level) const
|
PackLinuxElf::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
@@ -244,22 +239,6 @@ PackLinuxElf::getCompressionMethods(int method, int level) const
|
|||||||
return Packer::getDefaultCompressionMethods_le32(method, level);
|
return Packer::getDefaultCompressionMethods_le32(method, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
int const *
|
|
||||||
PackLinuxElf32armLe::getCompressionMethods(int /*method*/, int /*level*/) const
|
|
||||||
{
|
|
||||||
static const int m_nrv2e[] = { M_NRV2E_8, -1 };
|
|
||||||
|
|
||||||
return m_nrv2e;
|
|
||||||
}
|
|
||||||
|
|
||||||
int const *
|
|
||||||
PackLinuxElf32armBe::getCompressionMethods(int /*method*/, int /*level*/) const
|
|
||||||
{
|
|
||||||
static const int m_nrv2e[] = { M_NRV2E_8, -1 };
|
|
||||||
|
|
||||||
return m_nrv2e;
|
|
||||||
}
|
|
||||||
|
|
||||||
int const *
|
int const *
|
||||||
PackLinuxElf32ppc::getFilters() const
|
PackLinuxElf32ppc::getFilters() const
|
||||||
{
|
{
|
||||||
@@ -779,26 +758,6 @@ PackLinuxElf32ppc::buildLoader(const Filter *ft)
|
|||||||
linux_elfppc32_fold, sizeof(linux_elfppc32_fold), ft );
|
linux_elfppc32_fold, sizeof(linux_elfppc32_fold), ft );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PackLinuxElf32ppc::addStubEntrySections(Filter const *)
|
|
||||||
{
|
|
||||||
addLoader("ELFMAINX", NULL);
|
|
||||||
//addLoader(getDecompressorSections(), NULL);
|
|
||||||
addLoader(
|
|
||||||
( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL"
|
|
||||||
: M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL"
|
|
||||||
: M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL"
|
|
||||||
: M_IS_LZMA(ph.method) ? "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"
|
|
||||||
: NULL), NULL);
|
|
||||||
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PackLinuxElf32ppc::addLinkerSymbols(Filter const *)
|
|
||||||
{
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/amd64-linux.elf-entry.h"
|
#include "stub/amd64-linux.elf-entry.h"
|
||||||
static const
|
static const
|
||||||
@@ -1557,19 +1516,15 @@ PackLinuxElf32::ARM_buildLoader(const Filter *ft, bool const isBE)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxElf32::ARM_pack3(OutputFile *fo, Filter &ft, bool isBE)
|
void PackLinuxElf32::ARM_addLinkerSymbols(Filter const * /*ft*/)
|
||||||
{
|
{
|
||||||
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
||||||
unsigned const len0 = fo->getBytesWritten();
|
unsigned const len0 = sz_pack2;
|
||||||
unsigned len = len0;
|
unsigned len = len0;
|
||||||
unsigned const zero = 0;
|
|
||||||
fo->write(&zero, 3& -len); // align to 0 mod 4
|
|
||||||
len += (3& -len);
|
|
||||||
|
|
||||||
#define PAGE_MASK (~0u<<12)
|
#define PAGE_MASK (~0u<<12)
|
||||||
#define PAGE_SIZE (-PAGE_MASK)
|
#define PAGE_SIZE (-PAGE_MASK)
|
||||||
upx_byte *const p = getLoader();
|
lsize = /*getLoaderSize()*/ 4 * 1024; // upper bound; avoid circularity
|
||||||
lsize = getLoaderSize();
|
|
||||||
unsigned const lo_va_user = 0x8000; // XXX
|
unsigned const lo_va_user = 0x8000; // XXX
|
||||||
unsigned lo_va_stub = get_native32(&elfout.phdr[0].p_vaddr);
|
unsigned lo_va_stub = get_native32(&elfout.phdr[0].p_vaddr);
|
||||||
unsigned adrc;
|
unsigned adrc;
|
||||||
@@ -1602,49 +1557,26 @@ void PackLinuxElf32::ARM_pack3(OutputFile *fo, Filter &ft, bool isBE)
|
|||||||
adrm = PAGE_MASK & (~PAGE_MASK + adrm); // round up to page boundary
|
adrm = PAGE_MASK & (~PAGE_MASK + adrm); // round up to page boundary
|
||||||
adrc = PAGE_MASK & (~PAGE_MASK + adrc); // round up to page boundary
|
adrc = PAGE_MASK & (~PAGE_MASK + adrc); // round up to page boundary
|
||||||
|
|
||||||
// Patch in order of descending address.
|
linker->defineSymbol("ADRX", adrx); // compressed input for eXpansion
|
||||||
//
|
linker->defineSymbol("LENX", len0 - hlen);
|
||||||
// Because Packer::patch_be32 is overloaded, it is impossible
|
|
||||||
// to choose the right one to initialize a pointer to function.
|
|
||||||
// Therefore, write either patch_be32 or patch_le32 literally.
|
|
||||||
//
|
|
||||||
// ::ARM_buildLoader() put the stub into native order.
|
|
||||||
// util.c::find() uses host order.
|
|
||||||
int const swap = (HostPolicy::isBE ^ isBE);
|
|
||||||
if (isBE) {
|
|
||||||
patch_be32(p,lsize, 4*swap + "ADRXXRDA", adrx); // compressed input for eXpansion
|
|
||||||
patch_be32(p,lsize, 4*swap + "LENXXNEL", len0 - hlen);
|
|
||||||
|
|
||||||
patch_be32(p,lsize, 4*swap + "CNTCCTNC", cntc); // count for copy
|
linker->defineSymbol("CNTC", cntc); // count for copy
|
||||||
patch_be32(p,lsize, 4*swap + "ADRCCRDA", adrc); // addr for copy
|
linker->defineSymbol("ADRC", adrc); // addr for copy
|
||||||
|
|
||||||
patch_be32(p,lsize, 4*swap + "LENMMNEL", lenm); // len for map
|
linker->defineSymbol("LENM", lenm); // len for map
|
||||||
patch_be32(p,lsize, 4*swap + "ADRMMRDA", adrm); // addr for map
|
linker->defineSymbol("ADRM", adrm); // addr for map
|
||||||
}
|
|
||||||
else {
|
|
||||||
patch_le32(p,lsize, 4*swap + "ADRXXRDA", adrx); // compressed input for eXpansion
|
|
||||||
patch_le32(p,lsize, 4*swap + "LENXXNEL", len0 - hlen);
|
|
||||||
|
|
||||||
patch_le32(p,lsize, 4*swap + "CNTCCTNC", cntc); // count for copy
|
|
||||||
patch_le32(p,lsize, 4*swap + "ADRCCRDA", adrc); // addr for copy
|
|
||||||
|
|
||||||
patch_le32(p,lsize, 4*swap + "LENMMNEL", lenm); // len for map
|
|
||||||
patch_le32(p,lsize, 4*swap + "ADRMMRDA", adrm); // addr for map
|
|
||||||
}
|
|
||||||
#undef PAGE_SIZE
|
#undef PAGE_SIZE
|
||||||
#undef PAGE_MASK
|
#undef PAGE_MASK
|
||||||
|
|
||||||
super::pack3(fo, ft);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxElf32armLe::pack3(OutputFile *fo, Filter &ft)
|
void PackLinuxElf32armLe::addLinkerSymbols(Filter const *ft)
|
||||||
{
|
{
|
||||||
ARM_pack3(fo, ft, false);
|
ARM_addLinkerSymbols(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxElf32armBe::pack3(OutputFile *fo, Filter &ft)
|
void PackLinuxElf32armBe::addLinkerSymbols(Filter const *ft)
|
||||||
{
|
{
|
||||||
ARM_pack3(fo, ft, true);
|
ARM_addLinkerSymbols(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
|
void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
|
||||||
|
|||||||
+3
-8
@@ -91,7 +91,7 @@ protected:
|
|||||||
// These ARM routines are essentially common to big/little endian,
|
// These ARM routines are essentially common to big/little endian,
|
||||||
// but the class hierarchy splits after this class.
|
// but the class hierarchy splits after this class.
|
||||||
virtual int ARM_buildLoader(Filter const *ft, bool isBE);
|
virtual int ARM_buildLoader(Filter const *ft, bool isBE);
|
||||||
virtual void ARM_pack3(OutputFile *, Filter &, bool isBE);
|
virtual void ARM_addLinkerSymbols(Filter const *ft);
|
||||||
virtual void ARM_pack1(OutputFile *, bool isBE);
|
virtual void ARM_pack1(OutputFile *, bool isBE);
|
||||||
|
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
@@ -288,7 +288,6 @@ protected:
|
|||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
//virtual void pack3(OutputFile *, Filter &); // append loader
|
||||||
virtual int buildLoader(const Filter *);
|
virtual int buildLoader(const Filter *);
|
||||||
virtual void addStubEntrySections(Filter const *);
|
|
||||||
virtual Linker* newLinker() const;
|
virtual Linker* newLinker() const;
|
||||||
virtual void addLinkerSymbols(Filter const *);
|
virtual void addLinkerSymbols(Filter const *);
|
||||||
};
|
};
|
||||||
@@ -309,9 +308,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual int buildLoader(const Filter *);
|
virtual int buildLoader(const Filter *);
|
||||||
virtual void addStubEntrySections(Filter const *);
|
|
||||||
virtual Linker* newLinker() const;
|
virtual Linker* newLinker() const;
|
||||||
virtual void addLinkerSymbols(Filter const *);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -399,12 +396,11 @@ public:
|
|||||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
|
||||||
virtual const char *getName() const { return "linux/armLE"; }
|
virtual const char *getName() const { return "linux/armLE"; }
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual int const *getCompressionMethods(int method, int level) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
|
||||||
virtual int buildLoader(const Filter *);
|
virtual int buildLoader(const Filter *);
|
||||||
|
virtual void addLinkerSymbols(Filter const *);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PackLinuxElf32armBe : public PackLinuxElf32Be
|
class PackLinuxElf32armBe : public PackLinuxElf32Be
|
||||||
@@ -416,12 +412,11 @@ public:
|
|||||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; }
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMBE; }
|
||||||
virtual const char *getName() const { return "linux/armBE"; }
|
virtual const char *getName() const { return "linux/armBE"; }
|
||||||
virtual const int *getFilters() const;
|
virtual const int *getFilters() const;
|
||||||
virtual int const *getCompressionMethods(int method, int level) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
|
||||||
virtual int buildLoader(const Filter *);
|
virtual int buildLoader(const Filter *);
|
||||||
|
virtual void addLinkerSymbols(Filter const *);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*} already included */
|
#endif /*} already included */
|
||||||
|
|||||||
+4
-2
@@ -223,8 +223,10 @@ tc.arm-linux.elf.objdump = $(call tc,m-objdump)
|
|||||||
tc.arm-linux.elf.objstrip = $(call tc,objcopy) -R .comment -R .note
|
tc.arm-linux.elf.objstrip = $(call tc,objcopy) -R .comment -R .note
|
||||||
|
|
||||||
arm-linux.elf-entry.h : $(srcdir)/src/$$T.S
|
arm-linux.elf-entry.h : $(srcdir)/src/$$T.S
|
||||||
$(call tc,gcc) -nostdlib $< -o tmp/$T.out
|
$(call tc,gcc) -march=armv4 -c $< -o tmp/$T.bin
|
||||||
$(call tc,objcopy) --only-section .text -O binary tmp/$T.out tmp/$T.bin
|
$(call tc,m-objcopy) -R .text -R .data -R .bss tmp/$T.bin
|
||||||
|
$(call tc,m-objcopy) -R .note -R .comment tmp/$T.bin
|
||||||
|
$(call tc,m-objdump) -trwh tmp/$T.bin >> tmp/$T.bin
|
||||||
$(call tc,bin2h) --ident=linux_elf32arm_loader tmp/$T.bin $@
|
$(call tc,bin2h) --ident=linux_elf32arm_loader tmp/$T.bin $@
|
||||||
|
|
||||||
arm-linux.elf-fold.h : tmp/$$T.o tmp/arm-linux.elf-main.o $(srcdir)/src/$$T.lds
|
arm-linux.elf-fold.h : tmp/$$T.o tmp/arm-linux.elf-main.o $(srcdir)/src/$$T.lds
|
||||||
|
|||||||
+1020
-42
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,118 @@
|
|||||||
|
/* lzma_d.S -- ARM decompressor for LZMA
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
Copyright (C) 2000-2006 John F. Reiser
|
||||||
|
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
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define section .section
|
||||||
|
|
||||||
|
section LZMA_ELF00
|
||||||
|
//decompress: // (uchar const *src, size_t lsrc, uchar *dst, u32 &ldst, uint method)
|
||||||
|
/* Arguments according to calling convention */
|
||||||
|
#define src r0
|
||||||
|
#define lsrc r1
|
||||||
|
#define dst r2
|
||||||
|
#define ldst r3 /* Out: actually a reference: &len_dst */
|
||||||
|
#define meth [sp,#0]
|
||||||
|
|
||||||
|
// bkpt // debugging
|
||||||
|
|
||||||
|
#define M_LZMA 14
|
||||||
|
ldrb ip,meth; cmp ip,#M_LZMA; bne not_lzma
|
||||||
|
|
||||||
|
PUSH {fp,lr}
|
||||||
|
mov fp,sp
|
||||||
|
|
||||||
|
#define a0 r0
|
||||||
|
#define a1 r1
|
||||||
|
#define a2 r2
|
||||||
|
#define a3 r3
|
||||||
|
#define a4 [sp,#0*4] /* outp */
|
||||||
|
#define a5 [sp,#1*4] /* outSize */
|
||||||
|
#define a6 [sp,#2*4] /* &outSizeProcessed */
|
||||||
|
#define inSzP 3*4 /* inSizeprocessed */
|
||||||
|
#define State 4*4 /* CLzmaDecoderState */
|
||||||
|
|
||||||
|
//LzmaDecode( // from lzmaSDK/C/7zip/Compress/LZMA_C/LzmaDecode.h
|
||||||
|
// a0= &CLzmaDecoderState,
|
||||||
|
// a1= inp, a2= inSize, a3= &inSizeProcessed,
|
||||||
|
// a4= outp, a5= outSize, a6= &outSizeProcessed
|
||||||
|
//)
|
||||||
|
#define LZMA_BASE_SIZE 1846
|
||||||
|
#define LZMA_LIT_SIZE 768
|
||||||
|
|
||||||
|
ldrb fp,[src,#0] // first byte, replaces LzmaDecodeProperties()
|
||||||
|
mov ip,#2*LZMA_LIT_SIZE
|
||||||
|
mov fp,fp,LSR #3 // lit_context_bits + lit_pos_bits
|
||||||
|
mov ip,ip,LSL fp // 2*LZMA_LIT_SIZE << (lit_context_bits + lit_pos_bits)
|
||||||
|
mov fp,sp
|
||||||
|
add ip,ip,# ((4*4 + 2*LZMA_BASE_SIZE)>>8)<<8
|
||||||
|
add ip,ip,#0xff & (4*4 + 2*LZMA_BASE_SIZE)
|
||||||
|
sub sp,sp,ip
|
||||||
|
|
||||||
|
ldr ip,[ldst]
|
||||||
|
str ldst,a6 // &outSizeProcessed
|
||||||
|
str ip, a5 // outSize
|
||||||
|
str dst, a4 // outp
|
||||||
|
|
||||||
|
add r3,sp,#inSzP
|
||||||
|
mov ip,#0
|
||||||
|
1: // clear inSizeProcessed and CLzmaDecoderState
|
||||||
|
str ip,[r3],#4
|
||||||
|
cmp r3,fp
|
||||||
|
bne 1b
|
||||||
|
|
||||||
|
add a3,sp,#inSzP // &inSizeProcessed
|
||||||
|
sub a2,lsrc,#2 // inSize
|
||||||
|
mov a1, src // inp
|
||||||
|
|
||||||
|
ldrb ip,[a1],#1 // first byte, replaces LzmaDecodeProperties()
|
||||||
|
and ip,ip,#7 // posBits
|
||||||
|
strb ip,[sp,#2 + State]
|
||||||
|
ldrb ip,[a1],#1 // second byte, replaces LzmaDecodeProperties()
|
||||||
|
mov a0,ip,LSR #4 // lit_pos_bits
|
||||||
|
strb a0,[sp,#1 + State]
|
||||||
|
and ip,ip,#0xf // lib_context_bits
|
||||||
|
strb ip,[sp,#0 + State]
|
||||||
|
|
||||||
|
add a0,sp,#State
|
||||||
|
|
||||||
|
section LZMA_DEC10
|
||||||
|
#include "lzma_d_cs.S"
|
||||||
|
|
||||||
|
section LZMA_DEC20
|
||||||
|
#include "lzma_d_cf.S"
|
||||||
|
|
||||||
|
section LZMA_DEC30
|
||||||
|
mov sp,fp
|
||||||
|
POP {fp,pc}
|
||||||
|
|
||||||
|
not_lzma:
|
||||||
|
|
||||||
|
// vi:ts=8:et
|
||||||
|
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
/* nrv2d_d8.S -- ARM decompressor for NRV2D
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
Copyright (C) 1996-2006 Laszlo Molnar
|
||||||
|
Copyright (C) 2000-2006 John F. Reiser
|
||||||
|
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
|
||||||
|
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||||
|
|
||||||
|
John F. Reiser
|
||||||
|
<jreiser@users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
#define SAFE 0 /* 1 for src+dst bounds checking: cost 76 bytes */
|
||||||
|
|
||||||
|
#define src r0
|
||||||
|
#define len r1 /* overlaps 'cnt' */
|
||||||
|
#define dst r2
|
||||||
|
#define tmp r3
|
||||||
|
#define bits r4
|
||||||
|
#define off r5
|
||||||
|
/* r6 UNUSED in ARM code unless DEBUG mode */
|
||||||
|
#define srclim r7
|
||||||
|
#if 1==SAFE /*{*/
|
||||||
|
#define dstlim r12
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#define cnt r1 /* overlaps 'len' while reading an offset */
|
||||||
|
|
||||||
|
/* macros reduce "noise" when comparing this ARM code to corresponding THUMB code */
|
||||||
|
#define PUSH stmdb sp!,
|
||||||
|
#define POP ldmia sp!,
|
||||||
|
#define ADD2( dst,src) add dst,dst,src
|
||||||
|
#define ADD2S(dst,src) adds dst,dst,src
|
||||||
|
#define ADC2( dst,src) adc dst,dst,src
|
||||||
|
#define ADC2S(dst,src) adcs dst,dst,src
|
||||||
|
#define SUB2( dst,src) sub dst,dst,src
|
||||||
|
#define SUB2S(dst,src) subs dst,dst,src
|
||||||
|
#define LDRB3(reg,psrc,incr) ldrb reg,psrc,incr
|
||||||
|
#define STRB3(reg,pdst,incr) strb reg,pdst,incr
|
||||||
|
|
||||||
|
#if 1==SAFE /*{*/
|
||||||
|
#define CHECK_SRC cmp srclim,src; bls bad_src_n2d /* Out: 1==Carry for get8_n2d */
|
||||||
|
#define CHECK_DST cmp dst,dstlim; bhs bad_dst_n2d
|
||||||
|
#else /*}{*/
|
||||||
|
#define CHECK_SRC /*empty*/
|
||||||
|
#define CHECK_DST /*empty*/
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#if 0 /*{ DEBUG only: check newly-decompressed against original dst */
|
||||||
|
#define CHECK_BYTE \
|
||||||
|
ldrb r6,[dst]; \
|
||||||
|
cmp r6,tmp; beq 0f; bkpt; 0:
|
||||||
|
#else /*}{*/
|
||||||
|
#define CHECK_BYTE /*empty*/
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
#undef GETBIT
|
||||||
|
#define GETBIT ADD2S(bits,bits); bleq get8_n2d
|
||||||
|
|
||||||
|
#undef getnextb
|
||||||
|
#define getnextb(reg) GETBIT; ADC2S(reg,reg) /* Out: condition code changed */
|
||||||
|
#define jnextb0 GETBIT; bcc
|
||||||
|
#define jnextb1 GETBIT; bcs
|
||||||
|
|
||||||
|
ucl_nrv2d_decompress_8: .globl ucl_nrv2d_decompress_8 // ARM mode
|
||||||
|
.type ucl_nrv2d_decompress_8, %function
|
||||||
|
/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst)
|
||||||
|
Actual decompressed length is stored through plen_dst.
|
||||||
|
For SAFE mode: at call, *plen_dst must be allowed length of output buffer.
|
||||||
|
*/
|
||||||
|
PUSH {r2,r3, r4,r5,r6,r7, lr}
|
||||||
|
#define sp_DST0 0 /* stack offset of original dst */
|
||||||
|
add srclim,len,src // srclim= eof_src;
|
||||||
|
#if 1==SAFE /*{*/
|
||||||
|
ldr tmp,[r3] // len_dst
|
||||||
|
add dstlim,tmp,dst
|
||||||
|
#endif /*}*/
|
||||||
|
mvn off,#~-1 // off= -1 initial condition
|
||||||
|
mov bits,#1<<31 // refill next time
|
||||||
|
b top_n2d
|
||||||
|
|
||||||
|
#if 1==SAFE /*{*/
|
||||||
|
bad_dst_n2d: # return value will be 2
|
||||||
|
bkpt
|
||||||
|
add src,srclim,#1
|
||||||
|
bad_src_n2d: # return value will be 1
|
||||||
|
ADD2(src,#1)
|
||||||
|
#endif /*}*/
|
||||||
|
eof_n2d:
|
||||||
|
POP {r3,r4} // r3= orig_dst; r4= plen_dst
|
||||||
|
SUB2(src,srclim) // 0 if actual src length equals expected length
|
||||||
|
SUB2(dst,r3) // actual dst length
|
||||||
|
str dst,[r4]
|
||||||
|
|
||||||
|
#if defined(LINUX_ARM_CACHEFLUSH) /*{*/
|
||||||
|
/* linux/include/asm-arm/unistd.h */
|
||||||
|
#define __NR_SYSCALL_BASE 0x900000
|
||||||
|
#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
|
||||||
|
#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
|
||||||
|
mov r4,r0 // save result value
|
||||||
|
mov r0,r3 // orig_dst
|
||||||
|
add r1,r3,dst // orig_dst + dst_len
|
||||||
|
mov r2,#0
|
||||||
|
swi __ARM_NR_cacheflush // decompressed region
|
||||||
|
mov r0,r4 // result value
|
||||||
|
#endif /*}*/
|
||||||
|
|
||||||
|
POP {r4,r5,r6,r7 ,pc}
|
||||||
|
|
||||||
|
get8_n2d: // In: Carry set [from adding 0x80000000 (1<<31) to itself]
|
||||||
|
CHECK_SRC; LDRB3(bits,[src],#1) // zero-extend next byte
|
||||||
|
adc bits,bits,bits // double and insert CarryIn as low bit
|
||||||
|
movs bits,bits,lsl #24 // move to top byte, and set CarryOut from old bit 8
|
||||||
|
mov pc,lr
|
||||||
|
|
||||||
|
lit_n2d:
|
||||||
|
CHECK_SRC; LDRB3(tmp,[src],#1)
|
||||||
|
CHECK_BYTE
|
||||||
|
CHECK_DST; STRB3(tmp,[dst],#1)
|
||||||
|
top_n2d:
|
||||||
|
jnextb1 lit_n2d
|
||||||
|
mov cnt,#1; b getoff_n2d
|
||||||
|
|
||||||
|
off_n2d:
|
||||||
|
SUB2(cnt,#1)
|
||||||
|
getnextb(cnt)
|
||||||
|
getoff_n2d:
|
||||||
|
getnextb(cnt)
|
||||||
|
jnextb0 off_n2d
|
||||||
|
|
||||||
|
subs tmp,cnt,#3 // set Carry
|
||||||
|
mov len,#0 // Carry unaffected
|
||||||
|
blo offprev_n2d // cnt was 2; tests Carry only
|
||||||
|
CHECK_SRC; LDRB3(off,[src],#1) // low 7+1 bits
|
||||||
|
orr off,off,tmp,lsl #8
|
||||||
|
mvns off,off; beq eof_n2d // off= ~off
|
||||||
|
movs off,off,asr #1
|
||||||
|
b len_n2d -4 // CHEAT [getnextb ends in ADC2(reg,reg)]
|
||||||
|
|
||||||
|
offprev_n2d:
|
||||||
|
getnextb(len)
|
||||||
|
len_n2d:
|
||||||
|
getnextb(len); bne gotlen_n2d // 1..3 getnextb() must set Condition Code
|
||||||
|
mov len,#1 // begin ss11
|
||||||
|
lenmore_n2d:
|
||||||
|
getnextb(len)
|
||||||
|
jnextb0 lenmore_n2d
|
||||||
|
ADD2(len,#2) // 2.. ==> 4..
|
||||||
|
gotlen_n2d: // 'cmn': add the inputs, set condition codes, discard the sum
|
||||||
|
ADD2(len,#1) // 1..3 ==> 2..4; 4.. ==> 5..
|
||||||
|
cmn off,#5<<8 // displ<=M2_MAX_OFFSET ==> no increment
|
||||||
|
addcc len,len,#1 // too far away, so minimum match length is 3
|
||||||
|
#if 1==SAFE /*{*/
|
||||||
|
ldr tmp,[sp,#sp_DST0]
|
||||||
|
SUB2( tmp,dst)
|
||||||
|
SUB2S(tmp,off); bhi bad_dst_n2d // reaching back too far
|
||||||
|
|
||||||
|
add tmp,dst,cnt
|
||||||
|
cmp tmp,dstlim; bhi bad_dst_n2d // too much output
|
||||||
|
#endif /*}*/
|
||||||
|
ldrb tmp,[dst] // force cacheline allocate
|
||||||
|
copy_n2d:
|
||||||
|
ldrb tmp,[dst,off]
|
||||||
|
CHECK_BYTE
|
||||||
|
STRB3(tmp,[dst],#1)
|
||||||
|
SUB2S(len,#1); bne copy_n2d
|
||||||
|
b top_n2d
|
||||||
|
|
||||||
|
.size ucl_nrv2d_decompress_8, .-ucl_nrv2d_decompress_8
|
||||||
|
|
||||||
|
/*
|
||||||
|
vi:ts=8:et:nowrap
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
#define jnextb0 GETBIT; bcc
|
#define jnextb0 GETBIT; bcc
|
||||||
#define jnextb1 GETBIT; bcs
|
#define jnextb1 GETBIT; bcs
|
||||||
|
|
||||||
ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8 @ ARM mode
|
ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8 // ARM mode
|
||||||
.type ucl_nrv2e_decompress_8, %function
|
.type ucl_nrv2e_decompress_8, %function
|
||||||
/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst)
|
/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst)
|
||||||
Actual decompressed length is stored through plen_dst.
|
Actual decompressed length is stored through plen_dst.
|
||||||
@@ -86,13 +86,13 @@ ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8 @ ARM mode
|
|||||||
*/
|
*/
|
||||||
PUSH {r2,r3, r4,r5,r6,r7, lr}
|
PUSH {r2,r3, r4,r5,r6,r7, lr}
|
||||||
#define sp_DST0 0 /* stack offset of original dst */
|
#define sp_DST0 0 /* stack offset of original dst */
|
||||||
add srclim,len,src @ srclim= eof_src;
|
add srclim,len,src // srclim= eof_src;
|
||||||
#if 1==SAFE /*{*/
|
#if 1==SAFE /*{*/
|
||||||
ldr tmp,[r3] @ len_dst
|
ldr tmp,[r3] // len_dst
|
||||||
add dstlim,tmp,dst
|
add dstlim,tmp,dst
|
||||||
#endif /*}*/
|
#endif /*}*/
|
||||||
mvn off,#~-1 @ off= -1 initial condition
|
mvn off,#~-1 // off= -1 initial condition
|
||||||
mov bits,#1<<31 @ refill next time
|
mov bits,#1<<31 // refill next time
|
||||||
b top_n2e
|
b top_n2e
|
||||||
|
|
||||||
#if 1==SAFE /*{*/
|
#if 1==SAFE /*{*/
|
||||||
@@ -103,9 +103,9 @@ bad_src_n2e: # return value will be 1
|
|||||||
ADD2(src,#1)
|
ADD2(src,#1)
|
||||||
#endif /*}*/
|
#endif /*}*/
|
||||||
eof_n2e:
|
eof_n2e:
|
||||||
POP {r3,r4} @ r3= orig_dst; r4= plen_dst
|
POP {r3,r4} // r3= orig_dst; r4= plen_dst
|
||||||
SUB2(src,srclim) @ 0 if actual src length equals expected length
|
SUB2(src,srclim) // 0 if actual src length equals expected length
|
||||||
SUB2(dst,r3) @ actual dst length
|
SUB2(dst,r3) // actual dst length
|
||||||
str dst,[r4]
|
str dst,[r4]
|
||||||
|
|
||||||
#if defined(LINUX_ARM_CACHEFLUSH) /*{*/
|
#if defined(LINUX_ARM_CACHEFLUSH) /*{*/
|
||||||
@@ -113,20 +113,20 @@ eof_n2e:
|
|||||||
#define __NR_SYSCALL_BASE 0x900000
|
#define __NR_SYSCALL_BASE 0x900000
|
||||||
#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
|
#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
|
||||||
#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
|
#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
|
||||||
mov r4,r0 @ save result value
|
mov r4,r0 // save result value
|
||||||
mov r0,r3 @ orig_dst
|
mov r0,r3 // orig_dst
|
||||||
add r1,r3,dst @ orig_dst + dst_len
|
add r1,r3,dst // orig_dst + dst_len
|
||||||
mov r2,#0
|
mov r2,#0
|
||||||
swi __ARM_NR_cacheflush @ decompressed region
|
swi __ARM_NR_cacheflush // decompressed region
|
||||||
mov r0,r4 @ result value
|
mov r0,r4 // result value
|
||||||
#endif /*}*/
|
#endif /*}*/
|
||||||
|
|
||||||
POP {r4,r5,r6,r7 ,pc}
|
POP {r4,r5,r6,r7 ,pc}
|
||||||
|
|
||||||
get8_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself]
|
get8_n2e: // In: Carry set [from adding 0x80000000 (1<<31) to itself]
|
||||||
CHECK_SRC; LDRB3(bits,[src],#1) @ zero-extend next byte
|
CHECK_SRC; LDRB3(bits,[src],#1) // zero-extend next byte
|
||||||
adc bits,bits,bits @ double and insert CarryIn as low bit
|
adc bits,bits,bits // double and insert CarryIn as low bit
|
||||||
movs bits,bits,lsl #24 @ move to top byte, and set CarryOut from old bit 8
|
movs bits,bits,lsl #24 // move to top byte, and set CarryOut from old bit 8
|
||||||
mov pc,lr
|
mov pc,lr
|
||||||
|
|
||||||
lit_n2e:
|
lit_n2e:
|
||||||
@@ -144,12 +144,12 @@ getoff_n2e:
|
|||||||
getnextb(cnt)
|
getnextb(cnt)
|
||||||
jnextb0 off_n2e
|
jnextb0 off_n2e
|
||||||
|
|
||||||
subs tmp,cnt,#3 @ set Carry
|
subs tmp,cnt,#3 // set Carry
|
||||||
mov len,#0 @ Carry unaffected
|
mov len,#0 // Carry unaffected
|
||||||
blo offprev_n2e @ cnt was 2; tests Carry only
|
blo offprev_n2e // cnt was 2; tests Carry only
|
||||||
CHECK_SRC; LDRB3(off,[src],#1) @ low 7+1 bits
|
CHECK_SRC; LDRB3(off,[src],#1) // low 7+1 bits
|
||||||
orr off,off,tmp,lsl #8
|
orr off,off,tmp,lsl #8
|
||||||
mvns off,off; beq eof_n2e @ off= ~off
|
mvns off,off; beq eof_n2e // off= ~off
|
||||||
movs off,off,asr #1; bcs lenlast_n2e
|
movs off,off,asr #1; bcs lenlast_n2e
|
||||||
b lenmore_n2e
|
b lenmore_n2e
|
||||||
|
|
||||||
@@ -165,21 +165,21 @@ len_n2e:
|
|||||||
b gotlen_n2e
|
b gotlen_n2e
|
||||||
|
|
||||||
lenlast_n2e:
|
lenlast_n2e:
|
||||||
getnextb(len) @ 0,1,2,3
|
getnextb(len) // 0,1,2,3
|
||||||
ADD2(len,#2)
|
ADD2(len,#2)
|
||||||
gotlen_n2e: @ 'cmn': add the inputs, set condition codes, discard the sum
|
gotlen_n2e: // 'cmn': add the inputs, set condition codes, discard the sum
|
||||||
cmn off,#5<<8; bcs near_n2e @ within M2_MAX_OFFSET
|
cmn off,#5<<8 // within M2_MAX_OFFSET
|
||||||
ADD2(len,#1) @ too far away, so minimum match length is 3
|
addcc len,len,#1 // too far away, so minimum match length is 3
|
||||||
near_n2e:
|
near_n2e:
|
||||||
#if 1==SAFE /*{*/
|
#if 1==SAFE /*{*/
|
||||||
ldr tmp,[sp,#sp_DST0]
|
ldr tmp,[sp,#sp_DST0]
|
||||||
SUB2( tmp,dst)
|
SUB2( tmp,dst)
|
||||||
SUB2S(tmp,off); bhi bad_dst_n2e @ reaching back too far
|
SUB2S(tmp,off); bhi bad_dst_n2e // reaching back too far
|
||||||
|
|
||||||
add tmp,dst,cnt
|
add tmp,dst,cnt
|
||||||
cmp tmp,dstlim; bhi bad_dst_n2e @ too much output
|
cmp tmp,dstlim; bhi bad_dst_n2e // too much output
|
||||||
#endif /*}*/
|
#endif /*}*/
|
||||||
ldrb tmp,[dst] @ force cacheline allocate
|
ldrb tmp,[dst] // force cacheline allocate
|
||||||
copy_n2e:
|
copy_n2e:
|
||||||
ldrb tmp,[dst,off]
|
ldrb tmp,[dst,off]
|
||||||
CHECK_BYTE
|
CHECK_BYTE
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ lit_n2d:
|
|||||||
#undef tmp
|
#undef tmp
|
||||||
top_n2d:
|
top_n2d:
|
||||||
jnextb1y lit_n2d
|
jnextb1y lit_n2d
|
||||||
li off,1
|
li off,1 // start ss12
|
||||||
b getoff_n2d
|
b getoff_n2d
|
||||||
|
|
||||||
off_n2d:
|
off_n2d:
|
||||||
@@ -115,11 +115,11 @@ offprev_n2d:
|
|||||||
getnextb(len)
|
getnextb(len)
|
||||||
len_n2d:
|
len_n2d:
|
||||||
getnextb(len); bne gotlen_n2d // need getnextb() to set Condition Register
|
getnextb(len); bne gotlen_n2d // need getnextb() to set Condition Register
|
||||||
addi len,len,1
|
li len,1 // begin ss11
|
||||||
lenmore_n2d:
|
lenmore_n2d:
|
||||||
getnextb(len)
|
getnextb(len)
|
||||||
jnextb0n lenmore_n2d
|
jnextb0n lenmore_n2d
|
||||||
addi len,len,2
|
addi len,len,2 // 2.. ==> 4..
|
||||||
gotlen_n2d:
|
gotlen_n2d:
|
||||||
|
|
||||||
#define tmp off
|
#define tmp off
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
* John F. Reiser
|
* John F. Reiser
|
||||||
* <jreiser@users.sourceforge.net>
|
* <jreiser@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
#define section .section
|
||||||
|
|
||||||
sz_Elf32_Ehdr = 13*4
|
sz_Elf32_Ehdr = 13*4
|
||||||
sz_Elf32_Phdr = 8*4
|
sz_Elf32_Phdr = 8*4
|
||||||
@@ -48,14 +49,7 @@ MAP_ANONYMOUS= 0x20
|
|||||||
PAGE_SHIFT= 12
|
PAGE_SHIFT= 12
|
||||||
PAGE_SIZE = -(~0<<PAGE_SHIFT)
|
PAGE_SIZE = -(~0<<PAGE_SHIFT)
|
||||||
|
|
||||||
// magic for the UPX linker
|
section ELFMAINX
|
||||||
#define SECT(n) .text 1; .asciz #n; .long n - _start; .text 0; n
|
|
||||||
|
|
||||||
#define BL(t) \
|
|
||||||
.text 1; .long 0, bl##t - _start; .asciz #t; .long 0; \
|
|
||||||
.text 0; .byte 0, 0, 0; bl##t: .byte 0xeb
|
|
||||||
|
|
||||||
/*__ARMOS000__*/
|
|
||||||
_start: .globl _start
|
_start: .globl _start
|
||||||
/* Get some pages: enough
|
/* Get some pages: enough
|
||||||
to duplicate the entire compressed PT_LOAD, plus 1 page, located just after
|
to duplicate the entire compressed PT_LOAD, plus 1 page, located just after
|
||||||
@@ -63,23 +57,23 @@ _start: .globl _start
|
|||||||
calculated by PackLinuxElf32arm::pack3(), and patched in at compress time.
|
calculated by PackLinuxElf32arm::pack3(), and patched in at compress time.
|
||||||
*/
|
*/
|
||||||
adr r12,start_params
|
adr r12,start_params
|
||||||
ldmia r12!,{r0,r1, r8,r10} @ ADRM,LENM, ADRC,CNTC
|
ldmia r12!,{r0,r1, r8,r10} // ADRM,LENM, ADRC,CNTC
|
||||||
stmdb sp!,{r0,r1,r2} @ ADRU,LENU,space for sz_unc
|
stmdb sp!,{r0,r1,r2} // ADRU,LENU,space for sz_unc
|
||||||
mov r2,#PROT_READ | PROT_WRITE | PROT_EXEC
|
mov r2,#PROT_READ | PROT_WRITE | PROT_EXEC
|
||||||
mov r3,#MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS
|
mov r3,#MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS
|
||||||
mvn r4,#0 @ -1; cater to *BSD for fd when MAP_ANON
|
mvn r4,#0 // -1; cater to *BSD for fd when MAP_ANON
|
||||||
swi 0x009000c0 @ mmap64
|
swi 0x009000c0 // mmap64
|
||||||
cmn r0,#4096
|
cmn r0,#4096
|
||||||
bcs msg_SELinux
|
bcs msg_SELinux
|
||||||
mov r9,r0 @ destination for copy
|
mov r9,r0 // destination for copy
|
||||||
copy:
|
copy:
|
||||||
ldmia r8!,{r0,r1,r2,r3,r4,r5,r6,r7}; subs r10,r10,#1
|
ldmia r8!,{r0,r1,r2,r3,r4,r5,r6,r7}; subs r10,r10,#1
|
||||||
stmia r9!,{r0,r1,r2,r3,r4,r5,r6,r7}; bne copy
|
stmia r9!,{r0,r1,r2,r3,r4,r5,r6,r7}; bne copy
|
||||||
|
|
||||||
mov lr,r9 @ dst for unfolded code
|
mov lr,r9 // dst for unfolded code
|
||||||
sub r11,r9,r8 @ relocation amount
|
sub r11,r9,r8 // relocation amount
|
||||||
ldmia r12!,{r9,r10} @ LENX,ADRX
|
ldmia r12!,{r1,r4,r9,r10} // len_f,cpr0,LENX,ADRX
|
||||||
add r5,r12,r11 @ relocated f_decompress
|
add r5,r12,r11 // relocated f_decompress
|
||||||
|
|
||||||
/* linux/include/asm-arm/unistd.h */
|
/* linux/include/asm-arm/unistd.h */
|
||||||
#define __NR_SYSCALL_BASE 0x900000
|
#define __NR_SYSCALL_BASE 0x900000
|
||||||
@@ -87,57 +81,61 @@ copy:
|
|||||||
#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
|
#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
|
||||||
|
|
||||||
mov r0,r5
|
mov r0,r5
|
||||||
adr r1,end_decompress
|
add r1,r1,r0 // relocated end_decompress
|
||||||
sub r1,r1,r12 @ len(f_decompress)
|
|
||||||
add r1,r1,r0 @ relocated end_decompress
|
|
||||||
mov r2,#0
|
mov r2,#0
|
||||||
swi __ARM_NR_cacheflush @ relocated decompressor
|
swi __ARM_NR_cacheflush // relocated decompressor
|
||||||
|
|
||||||
ldrb r4,b_method +cpr0
|
add r0, r4,# sz_b_info
|
||||||
add r3,sp,#2*4 @ &sz_unc
|
ldr r1,[r4,# sz_cpr ]
|
||||||
mov r2,lr @ dst
|
mov r2,lr // dst
|
||||||
ldr r1,sz_cpr +cpr0
|
add r3,sp,#2*4 // &sz_unc
|
||||||
adr r0,sz_b_info +cpr0
|
ldrb r4,[r4,# b_method ]
|
||||||
mov pc,r5 @ decompress folded code; go there (lr)
|
mov pc,r5 // decompress folded code; go there (lr)
|
||||||
|
|
||||||
start_params:
|
start_params:
|
||||||
.ascii "ADRM" @ dst for map
|
.long ADRM // dst for map
|
||||||
.ascii "LENM" @ len for map
|
.long LENM // len for map
|
||||||
|
|
||||||
.ascii "ADRC" @ src for copy
|
.long ADRC // src for copy
|
||||||
.ascii "CNTC" @ cnt for copy: number of 32-byte blocks
|
.long CNTC // cnt for copy: number of 32-byte blocks
|
||||||
|
|
||||||
.ascii "LENX" @ total size of compressed data
|
.long len_f // length of decompressor code
|
||||||
.ascii "ADRX" @ &b_info of 1st compressed block (after moving)
|
.long cpr0
|
||||||
|
|
||||||
|
.long LENX // total size of compressed data
|
||||||
|
.long ADRX // &b_info of 1st compressed block (after moving)
|
||||||
f_decompress:
|
f_decompress:
|
||||||
#define LINUX_ARM_CACHEFLUSH 1
|
#define LINUX_ARM_CACHEFLUSH 1
|
||||||
|
|
||||||
|
section NRV2E
|
||||||
#include "arch/arm/v4a/nrv2e_d8.S"
|
#include "arch/arm/v4a/nrv2e_d8.S"
|
||||||
|
|
||||||
|
section NRV2D
|
||||||
|
#include "arch/arm/v4a/nrv2d_d8.S"
|
||||||
|
|
||||||
|
#include "arch/arm/v4a/lzma_d.S"
|
||||||
|
|
||||||
|
section ELFMAINY
|
||||||
end_decompress:
|
end_decompress:
|
||||||
|
|
||||||
.subsection 2
|
|
||||||
msg_SELinux:
|
msg_SELinux:
|
||||||
mov r2,#L71 - L70 @ length
|
mov r2,#L71 - L70 // length
|
||||||
adr r1,L70 @ message text
|
adr r1,L70 // message text
|
||||||
mov r0,#2 @ fd stderr
|
mov r0,#2 // fd stderr
|
||||||
swi 0x00900004 @ write
|
swi 0x00900004 // write
|
||||||
die:
|
die:
|
||||||
mov r0,#127
|
mov r0,#127
|
||||||
swi 0x00900001 @ exit
|
swi 0x00900001 // exit
|
||||||
b die
|
|
||||||
|
|
||||||
/* Temporary until we get the buildLoader stuff working ... */
|
|
||||||
.ascii "\n$Id: UPX (C) 1996-2006 the UPX Team. "
|
|
||||||
.asciz "All Rights Reserved. http://upx.sf.net $\n"
|
|
||||||
|
|
||||||
L70:
|
L70:
|
||||||
.asciz "PROT_EXEC|PROT_WRITE failed.\n"
|
.asciz "PROT_EXEC|PROT_WRITE failed.\n"
|
||||||
L71:
|
L71:
|
||||||
.balign 4
|
/* IDENTSTR goes here */
|
||||||
|
|
||||||
|
section ELFMAINZ
|
||||||
cpr0:
|
cpr0:
|
||||||
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
|
/* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */
|
||||||
|
|
||||||
eof:
|
eof:
|
||||||
/*__XTHEENDX__*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vi:ts=8:et:nowrap
|
vi:ts=8:et:nowrap
|
||||||
|
|||||||
Reference in New Issue
Block a user