mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
vmlinu[xz] using nrv2e converted to ElfLinker
This commit is contained in:
parent
db7086b5e6
commit
f0d5a6ebac
|
@ -36,6 +36,7 @@
|
|||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_vmlinx.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/i386-linux.kernel.vmlinux.h"
|
||||
|
@ -153,6 +154,13 @@ bool PackVmlinuxI386::canPack()
|
|||
return 0 < n_ptload;
|
||||
}
|
||||
|
||||
|
||||
Linker* PackVmlinuxI386::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
|
||||
int PackVmlinuxI386::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
|
@ -180,6 +188,20 @@ int PackVmlinuxI386::buildLoader(const Filter *ft)
|
|||
}
|
||||
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
return false;
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PackVmlinuxI386::pack(OutputFile *fo)
|
||||
{
|
||||
unsigned fo_off = 0;
|
||||
|
@ -226,13 +248,18 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
|
||||
defineFilterSymbols(linker, &ft);
|
||||
if (0x40==(0xf0 & ft.id)) {
|
||||
linker->defineSymbol("filter_length", ph.u_len); // redefine
|
||||
}
|
||||
linker->relocate();
|
||||
|
||||
// FIXME patchDecompressor(loader, lsize);
|
||||
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
patchPackHeader(loader, lsize);
|
||||
patchDecompressor(loader, lsize);
|
||||
patch_le32(loader, lsize, "ULEN", ph.u_len);
|
||||
patchFilter32(loader, lsize, &ft);
|
||||
|
||||
while (0!=*p++) ;
|
||||
shdro[1].sh_name = ptr_diff(p, shstrtab);
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
// virtual const upx_byte *getLoader() const;
|
||||
// virtual int getLoaderSize() const;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_vmlinz.h"
|
||||
#include "linker.h"
|
||||
#include <zlib.h>
|
||||
|
||||
static const
|
||||
|
@ -242,6 +243,12 @@ void PackVmlinuzI386::readKernel()
|
|||
}
|
||||
|
||||
|
||||
Linker* PackVmlinuzI386::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// vmlinuz specific
|
||||
**************************************************************************/
|
||||
|
@ -268,6 +275,19 @@ int PackVmlinuzI386::buildLoader(const Filter *ft)
|
|||
}
|
||||
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
return false;
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PackVmlinuzI386::pack(OutputFile *fo)
|
||||
{
|
||||
readKernel();
|
||||
|
@ -283,17 +303,18 @@ void PackVmlinuzI386::pack(OutputFile *fo)
|
|||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||
|
||||
freezeLoader();
|
||||
const unsigned lsize = getLoaderSize();
|
||||
|
||||
defineFilterSymbols(linker, &ft);
|
||||
// FIXME patchDecompressor(loader, lsize);
|
||||
linker->defineSymbol("src_for_decompressor", zimage_offset + lsize);
|
||||
linker->defineSymbol("original_entry", kernel_entry);
|
||||
linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
|
||||
linker->relocate();
|
||||
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
patchPackHeader(loader, lsize);
|
||||
patchFilter32(loader, lsize, &ft);
|
||||
patchDecompressor(loader, lsize);
|
||||
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||
patch_le32(loader, lsize, "STAK", stack_offset_during_uncompression);
|
||||
|
||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||
bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16) / 16;
|
||||
|
@ -327,10 +348,15 @@ int PackBvmlinuzI386::buildLoader(const Filter *ft)
|
|||
addLoader("LINUZ000",
|
||||
(0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""),
|
||||
"LBZIMAGE,IDENTSTR",
|
||||
"+40D++++", // align the stuff to 4 byte boundary
|
||||
"+40", // align the stuff to 4 byte boundary
|
||||
"UPX1HEAD", // 32 byte
|
||||
"LZCUTPOI,+0000000",
|
||||
getDecompressorSections(),
|
||||
"LZCUTPOI",
|
||||
NULL);
|
||||
|
||||
// fake alignment for the start of the decompressor
|
||||
linker->defineSymbol("LZCUTPOI", 0x1000);
|
||||
|
||||
addLoader(getDecompressorSections(),
|
||||
NULL
|
||||
);
|
||||
if (ft->id)
|
||||
|
@ -370,12 +396,8 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
|
|||
c_len = ALIGN_UP(c_len, 4);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
patchPackHeader(loader, lsize);
|
||||
patchFilter32(loader, lsize, &ft);
|
||||
patchDecompressor(loader, lsize);
|
||||
// FIXME patchDecompressor(loader, lsize);
|
||||
|
||||
const int e_len = getLoaderSectionStart("LZCUTPOI");
|
||||
assert(e_len > 0);
|
||||
|
@ -386,19 +408,24 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
|
|||
const unsigned edi = decompr_pos + d_len4 - 4; // copy to
|
||||
const unsigned esi = ALIGN_UP(c_len + lsize, 4) - 4; // copy from
|
||||
|
||||
unsigned jpos = find_le32(loader, e_len, get_le32("JMPD"));
|
||||
patch_le32(loader, e_len, "JMPD", decompr_pos - jpos - 4);
|
||||
|
||||
patch_le32(loader, e_len, "ESI1", bzimage_offset + decompr_pos - c_len);
|
||||
patch_le32(loader, e_len, "ECX0", copy_size / 4);
|
||||
patch_le32(loader, e_len, "EDI0", bzimage_offset + edi);
|
||||
patch_le32(loader, e_len, "ESI0", bzimage_offset + esi);
|
||||
linker->defineSymbol("decompressor", decompr_pos);
|
||||
linker->defineSymbol("src_for_decompressor", bzimage_offset + decompr_pos - c_len);
|
||||
linker->defineSymbol("words_to_copy", copy_size / 4);
|
||||
linker->defineSymbol("copy_dest", bzimage_offset + edi);
|
||||
linker->defineSymbol("copy_source", bzimage_offset + esi);
|
||||
|
||||
defineFilterSymbols(linker, &ft);
|
||||
if (0x40==(0xf0 & ft.id)) {
|
||||
patch_le32(loader, e_len, "ULEN", ph.u_len);
|
||||
linker->defineSymbol("filter_length", ph.u_len); // redefine
|
||||
}
|
||||
patch_le32(loader, e_len, "KEIP", kernel_entry);
|
||||
patch_le32(loader, e_len, "STAK", stack_offset_during_uncompression);
|
||||
// FIXME patchDecompressor(loader, lsize);
|
||||
linker->defineSymbol("original_entry", kernel_entry);
|
||||
linker->defineSymbol("stack_offset", stack_offset_during_uncompression);
|
||||
linker->relocate();
|
||||
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf);
|
||||
bs->sys_size = (ALIGN_UP(lsize + c_len, 16) / 16) & 0xffff;
|
||||
|
|
|
@ -57,6 +57,8 @@ protected:
|
|||
virtual void readKernel();
|
||||
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
// virtual const upx_byte *getLoader() const;
|
||||
// virtual int getLoaderSize() const;
|
||||
|
||||
|
|
|
@ -577,9 +577,11 @@ tmp/i386-linux.elf.shell-main.o : $(srcdir)/src/$$T.c
|
|||
i386-linux.kernel.vmlin% : tc_list = arch-i386 default
|
||||
|
||||
i386-linux.kernel%.h : $(srcdir)/src/$$T.asm
|
||||
$(call tc,pp-nasm) --MMD=$@ $< -o tmp/$T.tmp1
|
||||
$(call tc,app-nasm) tmp/$T.tmp1 tmp/$T.tmp2
|
||||
$(call tc,nasm) -f bin -l tmp/$T.bin.lst tmp/$T.tmp2 -o tmp/$T.bin
|
||||
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.bin
|
||||
$(call tc,m-objcopy) --strip-unneeded 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=nrv_loader tmp/$T.bin $@
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -194,69 +194,67 @@ section CALLTR13
|
|||
stosd
|
||||
jmps ctloop1
|
||||
ctend:
|
||||
section CTTHEEND
|
||||
.endm
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
;; call/jump/jcc trick; also used more than once (and/or optionally), so
|
||||
;; ecx has byte count (not count of applied instances), and
|
||||
;; edi points to buffer.
|
||||
%macro ckt32 2
|
||||
; 1st param: effective addvalue (typically 0 or edi; any rvalue)
|
||||
; 2nd param: where is cto8 (dl, bl, or literal)
|
||||
*/
|
||||
.macro ckt32 addvalue, cto8
|
||||
// 1st param: effective addvalue (typically 0 or edi; any rvalue)
|
||||
// 2nd param: where is cto8 (dl, bl, or literal)
|
||||
|
||||
section CKLLTR00
|
||||
%ifnidn %1,0
|
||||
mov esi, %1
|
||||
%endif
|
||||
section CKLLTR00
|
||||
.ifnc \addvalue, 0
|
||||
mov esi, \addvalue
|
||||
.endif
|
||||
jmps ckstart
|
||||
ckloop3:
|
||||
mov al, [edi]
|
||||
add edi, byte 1
|
||||
section CKLLTR10 Jcc only
|
||||
cmp al, 0x80 ; lo of 6-byte Jcc
|
||||
add edi, 1
|
||||
section CKLLTR10 // Jcc only
|
||||
cmp al, 0x80 // lo of 6-byte Jcc
|
||||
jb ckloop2
|
||||
cmp al, 0x8f ; hi of 6-byte Jcc
|
||||
cmp al, 0x8f // hi of 6-byte Jcc
|
||||
ja ckloop2
|
||||
cmp byte [edi -2], 0x0F ; prefix of 6-byte Jcc
|
||||
je ckmark
|
||||
cmpb [edi -2], 0x0F // prefix of 6-byte Jcc
|
||||
jes ckmark
|
||||
ckloop2:
|
||||
section CKLLTR20
|
||||
section CKLLTR20
|
||||
sub al, 0xE8
|
||||
cmp al, 0xE9 - 0xE8
|
||||
ja ckcount
|
||||
jas ckcount
|
||||
ckmark:
|
||||
cmp byte [edi], %2 ; cto8
|
||||
jnz ckcount
|
||||
cmp [edi], \cto8
|
||||
jnzs ckcount
|
||||
mov eax, [edi]
|
||||
|
||||
shr ax, 8
|
||||
rol eax, 16
|
||||
xchg ah, al
|
||||
; above 3 instr are equivalent to the following 2 instr:
|
||||
; mov al, 0 ; clear cto8 [setup partial-write stall]
|
||||
; bswap eax ; not on 386: need 486 and up
|
||||
// above 3 instr are equivalent to the following 2 instr:
|
||||
// mov al, 0 ; clear cto8 [setup partial-write stall]
|
||||
// bswap eax ; not on 386: need 486 and up
|
||||
|
||||
sub eax, edi
|
||||
%ifnidn %1,0
|
||||
.ifnc \addvalue, 0
|
||||
add eax, esi
|
||||
%endif
|
||||
.endif
|
||||
mov [edi], eax
|
||||
add edi, byte 4
|
||||
add edi, 4
|
||||
ckstart:
|
||||
sub ecx, byte 4
|
||||
section CKLLTR30 Jcc only
|
||||
sub ecx, 4
|
||||
section CKLLTR30 // Jcc only
|
||||
mov al, [edi]
|
||||
add edi, byte 1
|
||||
loop ckloop2 ; prefix cannot overlap previous displacement
|
||||
section CKLLTR40
|
||||
add edi, 1
|
||||
loop ckloop2 // prefix cannot overlap previous displacement
|
||||
section CKLLTR40
|
||||
ckcount:
|
||||
sub ecx, byte 1
|
||||
jg ckloop3
|
||||
sub ecx, 1
|
||||
jgs ckloop3
|
||||
ckend:
|
||||
%endmacro
|
||||
#endif
|
||||
.endm
|
||||
|
||||
// =============
|
||||
// ============= 32-BIT RELOCATIONS
|
||||
|
@ -301,7 +299,7 @@ reloc_endx:
|
|||
section REL32END
|
||||
.endm
|
||||
|
||||
#if 0
|
||||
/*
|
||||
;; =============
|
||||
;; ============= 32-BIT CALL TRICK UNFILTER WITH MostRecentlyUsed BUFFER
|
||||
;; =============
|
||||
|
@ -312,90 +310,92 @@ section REL32END
|
|||
;; MRUARBnn arbitrary number of entries in wheel
|
||||
;; MRUBITSn power of 2 entries in wheel (smaller code)
|
||||
;; MRUBYTEn 256 entries in wheel (smallest code)
|
||||
*/
|
||||
|
||||
%macro ctojr32 0
|
||||
%push ctojr32
|
||||
|
||||
/*
|
||||
;; I got confused by the syntactic sugar of the fake %ifdefs.
|
||||
;; I can read the section name more easily when it is at the left margin.
|
||||
;; Also, some of the logic to select the sections is not that simple,
|
||||
;; and any mismatch between the logic and the %ifdefs is very confusing.
|
||||
;; Instead, I use comments after the section name, and blank lines for grouping.
|
||||
*/
|
||||
|
||||
section LXUNF000 enter at +0 for decompression; +2 for unfiltering
|
||||
.macro ctojr32
|
||||
|
||||
section LXUNF000 // enter at +0 for decompression; +2 for unfiltering
|
||||
jmps decompr0
|
||||
section LXUNF002
|
||||
;; 2+ address of decompress subroutine
|
||||
;; unfilter(upx_byte *, length, cto8)
|
||||
// 2+ address of decompress subroutine
|
||||
// unfilter(upx_byte *, length, cto8)
|
||||
lxunfilter:
|
||||
pop edx ; return address
|
||||
pop eax ; upx_byte *, same as addvalue
|
||||
pop ecx ; length
|
||||
xchg eax, edi ; edi= pointer; eax= saved_edi
|
||||
pusha ; save C-convention ebx, ebp, esi, edi; also eax, edx
|
||||
pop edx // return address
|
||||
pop eax // upx_byte *, same as addvalue
|
||||
pop ecx // length
|
||||
xchg eax, edi // edi= pointer; eax= saved_edi
|
||||
pusha // save C-convention ebx, ebp, esi, edi; also eax, edx
|
||||
|
||||
; at most one of the next 2
|
||||
// at most one of the next 2
|
||||
section MRUBYTE0 256==n_mru
|
||||
xor ebx, ebx ; zero
|
||||
xor ebx, ebx // zero
|
||||
section LXMRU005 0!=n_mru
|
||||
mov ebx, 'NMRU' ; modified N_MRU or N_MRU -1
|
||||
mov ebx, offxset NMRU // modified N_MRU or N_MRU -1
|
||||
|
||||
section LXMRU006 0!=n_mru
|
||||
push byte 0x0f ; prefix of 6-byte Jcc <d32>
|
||||
push 0x0f // prefix of 6-byte Jcc <d32>
|
||||
pop eax
|
||||
mov ah, [esp + 8*4] ; cto8
|
||||
mov ah, [esp + 8*4] // cto8
|
||||
section LXMRU007 0==n_mru
|
||||
push byte 0x0f ; prefix of 6-byte Jcc <d32>
|
||||
push 0x0f // prefix of 6-byte Jcc <d32>
|
||||
pop ebx
|
||||
mov bh, [esp + 8*4] ; cto8
|
||||
mov bh, [esp + 8*4] // cto8
|
||||
|
||||
section LXUNF008
|
||||
mov dl, [esp + 8*4] ; cto8
|
||||
mov dl, [esp + 8*4] // cto8
|
||||
|
||||
section LXUNF010
|
||||
jmpn lxunf0
|
||||
decompr0:
|
||||
|
||||
;; These %define are only if 0!=n_mru;
|
||||
;; else 0x0F==bl && cto8==bh==dh && 0xE8==dl && addvalue==esi .
|
||||
%define %$n_mru [esi]
|
||||
%define %$n_mru1 [esi]
|
||||
%define %$tail [esi + 4*1]
|
||||
%define %$cto8_e8e9 [esi + 4*2]
|
||||
%define %$cto8_0f [esi + 4*3]
|
||||
%define %$addvalue [esi + 4*4]
|
||||
%define %$tmp ebp
|
||||
%define %$hand ebx
|
||||
%define %$hand_l bl
|
||||
%define %$kh edx
|
||||
%define %$kh_l dl
|
||||
// These #define are only if 0!=n_mru;
|
||||
// else 0x0F==bl && cto8==bh==dh && 0xE8==dl && addvalue==esi .
|
||||
#define __n_mru [esi]
|
||||
#define __n_mru1 [esi]
|
||||
#define __tail [esi + 4*1]
|
||||
#define __cto8_e8e9 [esi + 4*2]
|
||||
#define __cto8_0f [esi + 4*3]
|
||||
#define __addvalue [esi + 4*4]
|
||||
#define __tmp ebp
|
||||
#define __hand ebx
|
||||
#define __hand_l bl
|
||||
#define __kh edx
|
||||
#define __kh_l dl
|
||||
|
||||
section LXJCC010
|
||||
lxunf2: ; have seen 0x80..0x8f of possible recoded 6-byte Jcc <d32>
|
||||
movzx ebp, word [edi] ; 2 bytes, zero-extended
|
||||
lxunf2: // have seen 0x80..0x8f of possible recoded 6-byte Jcc <d32>
|
||||
movzx ebp, word [edi] // 2 bytes, zero-extended
|
||||
|
||||
section LXMRU045 0!=n_mru
|
||||
sub ebp, %$cto8_0f
|
||||
sub ebp, __cto8_0f
|
||||
section LXMRU046 0==n_mru
|
||||
sub ebp, ebx
|
||||
|
||||
section LXJCC020 0==n_mru, or Jcc excluded ('sub' of equals clears Carry)
|
||||
jne unfcount
|
||||
section LXJCC021 0!=n_mru and Jcc participates; must set Carry
|
||||
sub ebp, byte 1 ; set Carry iff in range
|
||||
section LXJCC021 0!=n_mru and Jcc participates// must set Carry
|
||||
sub ebp, 1 // set Carry iff in range
|
||||
jnb unfcount
|
||||
|
||||
section LXJCC023 found Jcc; re-swap 0x8Y opcode and 0x0f prefix
|
||||
mov byte [edi -1], bl ; 0x0f prefix
|
||||
dec ecx ; preserve Carry
|
||||
mov byte [edi], al ; Jcc opcode
|
||||
inc edi ; preserve Carry
|
||||
section LXJCC023 found Jcc// re-swap 0x8Y opcode and 0x0f prefix
|
||||
mov [edi -1], bl // 0x0f prefix
|
||||
dec ecx // preserve Carry
|
||||
mov [edi], al // Jcc opcode
|
||||
inc edi // preserve Carry
|
||||
|
||||
section LXUNF037
|
||||
%define %$jc eax
|
||||
#define __jc eax
|
||||
|
||||
lxunf: ; in: Carry set iff we should apply mru and 0!=n_mru
|
||||
mov eax, [edi] ; BE32 displacement with cto8 in low 8 bits
|
||||
lxunf: // in: Carry set iff we should apply mru and 0!=n_mru
|
||||
mov eax, [edi] // BE32 displacement with cto8 in low 8 bits
|
||||
|
||||
section LXUNF386 0!=n_mru && 386
|
||||
pushf
|
||||
|
@ -405,120 +405,120 @@ section LXUNF387 ==386
|
|||
xchg ah, al
|
||||
section LXUNF388 0!=n_mru && 386
|
||||
popf
|
||||
jnc unf_store ; do not apply mru
|
||||
jnc unf_store // do not apply mru
|
||||
|
||||
section LXUNF486 >=486
|
||||
mov al, byte 0
|
||||
mov al, 0
|
||||
CPU 486
|
||||
bswap eax ; preserve Carry (2-byte instruction)
|
||||
bswap eax // preserve Carry (2-byte instruction)
|
||||
CPU 386
|
||||
section LXUNF487 0!=n_mru && >=486
|
||||
jnc unf_store ; do not apply mru
|
||||
jnc unf_store // do not apply mru
|
||||
|
||||
section LXMRU065 0!=n_mru
|
||||
shr %$jc, 1 ; eax= jc, or mru index
|
||||
jnc mru4 ; not 1st time for this jc
|
||||
shr __jc, 1 // eax= jc, or mru index
|
||||
jnc mru4 // not 1st time for this jc
|
||||
section MRUBYTE3
|
||||
dec %$hand_l
|
||||
dec __hand_l
|
||||
section MRUARB30
|
||||
dec %$hand
|
||||
dec __hand
|
||||
section MRUBITS3
|
||||
and %$hand, %$n_mru1
|
||||
and __hand, __n_mru1
|
||||
section MRUARB40
|
||||
jge mru3
|
||||
add %$hand, %$n_mru
|
||||
add __hand, __n_mru
|
||||
mru3:
|
||||
section LXMRU070
|
||||
|
||||
mov [esp + 4*%$hand], %$jc ; 1st time: mru[hand] = jc
|
||||
mov [esp + 4*__hand], __jc // 1st time: mru[hand] = jc
|
||||
jmps unf_store
|
||||
|
||||
mru4: ; not 1st time for this jc
|
||||
lea %$kh, [%$jc + %$hand] ; kh = jc + hand
|
||||
mru4: // not 1st time for this jc
|
||||
lea __kh, [__jc + __hand] // kh = jc + hand
|
||||
section MRUBYTE4
|
||||
movzx %$kh, %$kh_l
|
||||
movzx __kh, __kh_l
|
||||
section MRUBITS4
|
||||
and %$kh, %$n_mru1
|
||||
and __kh, __n_mru1
|
||||
section MRUARB50
|
||||
cmp %$kh, %$n_mru
|
||||
cmp __kh, __n_mru
|
||||
jb mru5
|
||||
sub %$kh, %$n_mru
|
||||
sub __kh, __n_mru
|
||||
mru5:
|
||||
section LXMRU080
|
||||
mov %$jc, [esp + 4*%$kh] ; jc = mru[kh]
|
||||
mov __jc, [esp + 4*__kh] // jc = mru[kh]
|
||||
section MRUBYTE5
|
||||
dec %$hand_l
|
||||
dec __hand_l
|
||||
section MRUARB60
|
||||
dec %$hand
|
||||
dec __hand
|
||||
section MRUBITS5
|
||||
and %$hand, %$n_mru1
|
||||
and __hand, __n_mru1
|
||||
section MRUARB70
|
||||
jge mru6
|
||||
add %$hand, %$n_mru
|
||||
add __hand, __n_mru
|
||||
mru6:
|
||||
section LXMRU090
|
||||
|
||||
mov %$tmp, [esp + 4*%$hand] ; tmp = mru[hand]
|
||||
test %$tmp,%$tmp
|
||||
mov __tmp, [esp + 4*__hand] // tmp = mru[hand]
|
||||
test __tmp,__tmp
|
||||
jnz mru8
|
||||
|
||||
push %$jc ; ran out of registers
|
||||
mov eax, %$tail
|
||||
push __jc // ran out of registers
|
||||
mov eax, __tail
|
||||
|
||||
section MRUBYTE6
|
||||
dec al
|
||||
section MRUARB80
|
||||
dec eax
|
||||
section MRUBITS6
|
||||
and eax, %$n_mru1
|
||||
and eax, __n_mru1
|
||||
section MRUARB90
|
||||
jge mru7
|
||||
add eax, %$n_mru
|
||||
add eax, __n_mru
|
||||
mru7:
|
||||
section LXMRU100
|
||||
|
||||
xor %$tmp,%$tmp
|
||||
mov %$tail, eax
|
||||
xchg [4+ esp + 4*eax], %$tmp ; tmp = mru[tail]; mru[tail] = 0
|
||||
pop %$jc
|
||||
xor __tmp,__tmp
|
||||
mov __tail, eax
|
||||
xchg [4+ esp + 4*eax], __tmp // tmp = mru[tail]; mru[tail] = 0
|
||||
pop __jc
|
||||
mru8:
|
||||
mov [esp + 4*%$kh ], %$tmp ; mru[kh] = tmp
|
||||
mov [esp + 4*%$hand], %$jc ; mru[hand] = jc
|
||||
mov [esp + 4*__kh ], __tmp // mru[kh] = tmp
|
||||
mov [esp + 4*__hand], __jc // mru[hand] = jc
|
||||
section LXUNF040
|
||||
unf_store:
|
||||
sub eax, edi
|
||||
sub ecx, byte 4
|
||||
sub ecx, 4
|
||||
|
||||
; one of the next2
|
||||
// one of the next2
|
||||
section LXMRU110 0!=n_mru
|
||||
add eax, %$addvalue
|
||||
add eax, __addvalue
|
||||
section LXMRU111 0==n_mru
|
||||
add eax, esi ; addvalue (same as initial pointer)
|
||||
add eax, esi // addvalue (same as initial pointer)
|
||||
|
||||
section LXUNF041
|
||||
mov [edi], eax
|
||||
add edi, byte 4
|
||||
add edi, 4
|
||||
jmps unfcount
|
||||
section LXUNF042
|
||||
lxunf0: ;; continuation of entry prolog for unfilter
|
||||
lxunf0: // continuation of entry prolog for unfilter
|
||||
section LEXEC016 bug in APP: jmp and label must be in same .asx/.asy
|
||||
jmp lxunf0 ; this instr does not really go here!
|
||||
jmp lxunf0 // this instr does not really go here!
|
||||
|
||||
section LXMRU010 0!=n_mru
|
||||
push eax ; cto8_0f
|
||||
push eax // cto8_0f
|
||||
section LXJMPA00 only JMP, and not CALL, is filtered
|
||||
mov al, 0xE9
|
||||
section LXCALLB0 only CALL, or both CALL and JMP are filtered
|
||||
mov al, 0xE8
|
||||
section LXUNF021 common tail
|
||||
push eax ; cto8_e8e9
|
||||
push byte 0 ; tail
|
||||
push ebx ; n_mru or n_mru1
|
||||
mov esi, esp ; flat model "[esi]" saves a byte over "[ebp]"
|
||||
push eax // cto8_e8e9
|
||||
push 0 // tail
|
||||
push ebx // n_mru or n_mru1
|
||||
mov esi, esp // flat model "[esi]" saves a byte over "[ebp]"
|
||||
|
||||
section LXMRU022 0==n_mru
|
||||
pop esi ; addvalue
|
||||
mov edx, ebx ; dh= cto8
|
||||
pop esi // addvalue
|
||||
mov edx, ebx // dh= cto8
|
||||
section LXJMPA01 only JMP, and not CALL, is filtered
|
||||
mov dl, 0xE9
|
||||
section LXCALLB1 only CALL, or both CALL and JMP are filtered
|
||||
|
@ -526,56 +526,56 @@ section LXCALLB1 only CALL, or both CALL and JMP are filtered
|
|||
|
||||
|
||||
section MRUBITS1
|
||||
inc %$hand ; n_mru1 ==> n_mru
|
||||
inc __hand // n_mru1 ==> n_mru
|
||||
section LXMRU030
|
||||
lxunf1: ; allocate and clear mru[]
|
||||
push byte 0
|
||||
lxunf1: // allocate and clear mru[]
|
||||
push 0
|
||||
|
||||
; one of the next 2, if n_mru
|
||||
// one of the next 2, if n_mru
|
||||
section MRUBYTE1
|
||||
dec %$hand_l
|
||||
dec __hand_l
|
||||
section MRUARB10
|
||||
dec %$hand
|
||||
dec __hand
|
||||
|
||||
section LXMRU040 0!=n_mru
|
||||
jnz lxunf1 ; leaves 0=='hand'
|
||||
jnz lxunf1 // leaves 0=='hand'
|
||||
|
||||
section LXUNF030
|
||||
lxctloop:
|
||||
movzx eax, word [edi] ; 2 bytes, zero extended
|
||||
add edi, byte 1
|
||||
movzx eax, word [edi] // 2 bytes, zero extended
|
||||
add edi, 1
|
||||
section LXJCC000
|
||||
cmp al, 0x80 ; lo of Jcc <d32>
|
||||
cmp al, 0x80 // lo of Jcc <d32>
|
||||
jb lxct1
|
||||
cmp al, 0x8f ; hi of Jcc <d32>
|
||||
cmp al, 0x8f // hi of Jcc <d32>
|
||||
jbe lxunf2
|
||||
lxct1:
|
||||
|
||||
section LXCJ0MRU 0==n_mru
|
||||
sub eax, edx
|
||||
section LXCJ1MRU 0!=n_mru
|
||||
sub eax, %$cto8_e8e9
|
||||
sub eax, __cto8_e8e9
|
||||
|
||||
; both CALL and JMP are filtered
|
||||
// both CALL and JMP are filtered
|
||||
section LXCALJMP
|
||||
sub eax, byte 1+ (0xE9 - 0xE8) ; set Carry iff in range (result: -2, -1)
|
||||
sub eax, 1+ (0xE9 - 0xE8) // set Carry iff in range (result: -2, -1)
|
||||
|
||||
; only CALL, or only JMP, is filtered
|
||||
// only CALL, or only JMP, is filtered
|
||||
section LXCALL00 0==n_mru
|
||||
je lxunf
|
||||
section LXCALL01 0!=n_rmu
|
||||
sub eax, byte 1 ; set Carry iff in range
|
||||
sub eax, 1 // set Carry iff in range
|
||||
|
||||
section LXCJ2MRU 0==n_mru, or apply mru to all that are filtered here
|
||||
jb lxunf ; only Carry (Borrow) matters
|
||||
jb lxunf // only Carry (Borrow) matters
|
||||
section LXCJ4MRU 0!=n_mru, but apply mru only to subset of filtered here
|
||||
jnb unfcount ; was not filtered anyway: do not unfilter
|
||||
jnb unfcount // was not filtered anyway: do not unfilter
|
||||
|
||||
;we will unfilter, and 0!=n_mru, but should we apply mru?
|
||||
//we will unfilter, and 0!=n_mru, but should we apply mru?
|
||||
section LXCJ6MRU apply mru to JMP only (0xFF==al)
|
||||
jpe lxct3 ; jump if even number of 1 bits in al
|
||||
jpe lxct3 // jump if even number of 1 bits in al
|
||||
section LXCJ7MRU apply mru to CALL only (0xFE==al)
|
||||
jpo lxct3 ; jump if odd number of 1 bits in al
|
||||
jpo lxct3 // jump if odd number of 1 bits in al
|
||||
section LXCJ8MRU do not apply mru to one or both
|
||||
clc
|
||||
lxct3:
|
||||
|
@ -583,19 +583,19 @@ lxct3:
|
|||
|
||||
section LXUNF034
|
||||
unfcount:
|
||||
sub ecx, byte 1
|
||||
sub ecx, 1
|
||||
jg lxctloop
|
||||
|
||||
section LXMRU055
|
||||
mov edi, esp ; clear mru[] portion of stack
|
||||
mov edi, esp // clear mru[] portion of stack
|
||||
section MRUBYTE2
|
||||
mov ecx, 4+ 256 ; unused, tail, cto8_e8e9, cto8_0f
|
||||
mov ecx, 4+ 256 // unused, tail, cto8_e8e9, cto8_0f
|
||||
section MRUBITS2
|
||||
mov ecx, %$n_mru1
|
||||
add ecx, byte 1+ 4 ; n_mru1, tail, cto8_e8e9, cto8_0f
|
||||
mov ecx, __n_mru1
|
||||
add ecx, 1+ 4 // n_mru1, tail, cto8_e8e9, cto8_0f
|
||||
section MRUARB20
|
||||
mov ecx, %$n_mru
|
||||
add ecx, byte 4 ; n_mru, tail, cto8_e8e9, cto8_0f
|
||||
mov ecx, __n_mru
|
||||
add ecx, 4 // n_mru, tail, cto8_e8e9, cto8_0f
|
||||
section LXMRU057
|
||||
xor eax, eax
|
||||
rep
|
||||
|
@ -611,8 +611,6 @@ section LXUNF035
|
|||
push eax
|
||||
push edx
|
||||
ret
|
||||
%pop
|
||||
%endmacro
|
||||
#endif
|
||||
.endm
|
||||
|
||||
// vi:ts=8:et:nowrap
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/*
|
||||
; l_vmlinx.asm -- loader & decompressor for the vmlinux/i386 format
|
||||
;
|
||||
; This file is part of the UPX executable compressor.
|
||||
|
@ -27,122 +28,108 @@
|
|||
;
|
||||
; John Reiser
|
||||
; <jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#include "arch/i386/macros2.ash"
|
||||
|
||||
%define jmps jmp short
|
||||
%define jmpn jmp near
|
||||
%include "arch/i386/macros.ash"
|
||||
|
||||
BITS 32
|
||||
SECTION .text
|
||||
ORG 0
|
||||
|
||||
/*
|
||||
; =============
|
||||
; ============= ENTRY POINT
|
||||
; =============
|
||||
|
||||
start:
|
||||
; In:
|
||||
; %eax= &uncompressed [and final entry]; %ds= %es= __BOOT_DS
|
||||
; %esp: &compressed; __BOOT_CS
|
||||
; __LINUX000__
|
||||
pop edx ; &compressed; length at -4(%edx)
|
||||
; #eax= &uncompressed [and final entry]; #ds= #es= __BOOT_DS
|
||||
; #esp: &compressed; __BOOT_CS
|
||||
*/
|
||||
section LINUX000
|
||||
pop edx // &compressed; length at -4(#edx)
|
||||
|
||||
push eax ; MATCH00(1/2) entry address; __BOOT_CS
|
||||
push edi ; MATCH01 save
|
||||
push esi ; MATCH02 save
|
||||
push eax // MATCH00(1/2) entry address; __BOOT_CS
|
||||
push edi // MATCH01 save
|
||||
push esi // MATCH02 save
|
||||
|
||||
%ifdef __LXCALLT1__
|
||||
push eax ; MATCH03 src unfilter
|
||||
%endif; __LXDUMMY0__
|
||||
%ifdef __LXCKLLT1__
|
||||
push eax ; MATCH03 src unfilter
|
||||
push byte '?' ; MATCH04 cto unfilter
|
||||
%endif; __LXMOVEUP__
|
||||
push 'ULEN' ; MATCH05 uncompressed length
|
||||
call move_up ; MATCH06
|
||||
section LXCALLT1
|
||||
push eax // MATCH03 src unfilter
|
||||
section LXCKLLT1
|
||||
push eax // MATCH03 src unfilter
|
||||
//push offset filter_cto // MATCH04 cto unfilter
|
||||
.byte 0x6a, filter_cto // MATCH04 cto unfilter
|
||||
section LXMOVEUP
|
||||
push offset filter_length // MATCH05 uncompressed length
|
||||
call move_up // MATCH06
|
||||
|
||||
; =============
|
||||
; ============= DECOMPRESSION
|
||||
; =============
|
||||
// =============
|
||||
// ============= DECOMPRESSION
|
||||
// =============
|
||||
|
||||
%include "arch/i386/nrv2b_d32.ash"
|
||||
%include "arch/i386/nrv2d_d32.ash"
|
||||
%include "arch/i386/nrv2e_d32.ash"
|
||||
%include "arch/i386/lzma_d.ash"
|
||||
//#include "arch/i386/nrv2b_d32.ash"
|
||||
//#include "arch/i386/nrv2d_d32.ash"
|
||||
//#include "arch/i386/nrv2e_d32.ash"
|
||||
#include "arch/i386/nrv2e_d32_2.ash"
|
||||
//#include "arch/i386/lzma_d.ash"
|
||||
|
||||
; =============
|
||||
; ============= UNFILTER
|
||||
; =============
|
||||
// =============
|
||||
// ============= UNFILTER
|
||||
// =============
|
||||
|
||||
%ifdef __LXCKLLT9__
|
||||
pop ecx ; MATCH05 len
|
||||
pop edx ; MATCH04 cto
|
||||
pop edi ; MATCH03 src
|
||||
section LXCKLLT9
|
||||
pop ecx // MATCH05 len
|
||||
pop edx // MATCH04 cto
|
||||
pop edi // MATCH03 src
|
||||
|
||||
ckt32 edi, dl ; dl has cto8
|
||||
ckt32 edi, dl // dl has cto8
|
||||
/*
|
||||
;edi: adjust for the difference between 0 origin of buffer at filter,
|
||||
;and actual origin of destination at unfilter.
|
||||
;Filter.addvalue is 0: destination origin is unknown at filter time.
|
||||
;The input data is still relocatable, and address is assigned later
|
||||
;[as of 2004-12-15 it is 'always' 0x100000].
|
||||
*/
|
||||
|
||||
%endif; __LXDUMMY2__
|
||||
%ifdef __LXCALLT9__
|
||||
pop ecx ; MATCH05 len
|
||||
pop edi ; MATCH03 src
|
||||
section LXCALLT9
|
||||
pop ecx // MATCH05 len
|
||||
pop edi // MATCH03 src
|
||||
cjt32 0
|
||||
%endif; __LINUX990__
|
||||
pop esi ; MATCH02 restore
|
||||
pop edi ; MATCH01 restore
|
||||
xor ebx, ebx ; booting the 1st cpu
|
||||
retf ; MATCH00 set cs
|
||||
section LINUX990
|
||||
pop esi // MATCH02 restore
|
||||
pop edi // MATCH01 restore
|
||||
xor ebx, ebx // booting the 1st cpu
|
||||
lret // MATCH00 set cs
|
||||
|
||||
%define UNLAP 0x10
|
||||
%define ALIGN (~0<<4)
|
||||
; must have 0==(UNLAP &~ ALIGN)
|
||||
#define UNLAP 0x10
|
||||
#define ALIGN (~0<<4)
|
||||
// must have 0==(UNLAP &~ ALIGN)
|
||||
|
||||
move_up:
|
||||
pop esi ; MATCH06 &decompressor
|
||||
mov ecx,[-4+ esi] ; length of decompressor+unfilter
|
||||
mov ebp,eax ; &uncompressed
|
||||
add eax,[esp] ; MATCH05 ULEN + base; entry to decompressor
|
||||
add eax, byte ~ALIGN + UNLAP
|
||||
and eax, byte ALIGN
|
||||
pop esi // MATCH06 &decompressor
|
||||
mov ecx,[-4+ esi] // length of decompressor+unfilter
|
||||
mov ebp,eax // &uncompressed
|
||||
add eax,[esp] // MATCH05 ULEN + base; entry to decompressor
|
||||
add eax, ~ALIGN + UNLAP
|
||||
and eax, ALIGN
|
||||
|
||||
std
|
||||
; copy decompressor
|
||||
lea esi,[-1+ ecx + esi] ; unmoved top -1 of decompressor
|
||||
lea edi,[-1+ ecx + eax] ; moved top -1 of decompressor
|
||||
// copy decompressor
|
||||
lea esi,[-1+ ecx + esi] // unmoved top -1 of decompressor
|
||||
lea edi,[-1+ ecx + eax] // moved top -1 of decompressor
|
||||
rep
|
||||
movsb
|
||||
|
||||
mov ecx,[-4+ edx] ; length of compressed data
|
||||
add ecx, byte 3
|
||||
shr ecx,2 ; count of .long
|
||||
; copy compressed data
|
||||
lea esi,[-4+ 4*ecx + edx] ; unmoved top -4 of compressed data
|
||||
lea edi,[-4+ eax] ; moved top -4 of compressed data
|
||||
mov ecx,[-4+ edx] // length of compressed data
|
||||
add ecx, 3
|
||||
shr ecx,2 // count of .long
|
||||
// copy compressed data
|
||||
lea esi,[-4+ 4*ecx + edx] // unmoved top -4 of compressed data
|
||||
lea edi,[-4+ eax] // moved top -4 of compressed data
|
||||
rep
|
||||
movsd
|
||||
|
||||
cld
|
||||
lea esi,[4+ edi] ; &compressed [after move]
|
||||
mov edi,ebp ; &uncompressed
|
||||
or ebp, byte -1 ; decompressor assumption
|
||||
jmp eax ; enter moved decompressor
|
||||
lea esi,[4+ edi] // &compressed [after move]
|
||||
mov edi,ebp // &uncompressed
|
||||
or ebp, -1 // decompressor assumption
|
||||
jmp eax // enter moved decompressor
|
||||
|
||||
; =============
|
||||
; ============= CUT HERE
|
||||
; =============
|
||||
#include "include/header2.ash"
|
||||
|
||||
%include "include/header.ash"
|
||||
|
||||
eof:
|
||||
; __LITHEEND__
|
||||
section .data
|
||||
dd -1
|
||||
dw eof
|
||||
|
||||
|
||||
; vi:ts=8:et:nowrap
|
||||
// vi:ts=8:et:nowrap
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/*
|
||||
; l_vmlinz.asm -- loader & decompressor for the vmlinuz/i386 format
|
||||
;
|
||||
; This file is part of the UPX executable compressor.
|
||||
|
@ -24,32 +25,29 @@
|
|||
; Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
; <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
;
|
||||
*/
|
||||
|
||||
|
||||
%define jmps jmp short
|
||||
%define jmpn jmp near
|
||||
%include "arch/i386/macros.ash"
|
||||
#include "arch/i386/macros2.ash"
|
||||
|
||||
BITS 32
|
||||
SECTION .text
|
||||
ORG 0
|
||||
// =============
|
||||
// ============= ENTRY POINT
|
||||
// =============
|
||||
|
||||
; =============
|
||||
; ============= ENTRY POINT
|
||||
; =============
|
||||
|
||||
start:
|
||||
; __LINUZ000__
|
||||
;cli ;this must be true already
|
||||
section LINUZ000
|
||||
//cli // this must be true already
|
||||
|
||||
/*
|
||||
; The only facts about segments here, that are true for all kernels:
|
||||
; %cs is a valid "flat" code segment; no other segment reg is valid;
|
||||
; the next segment after %cs is a valid "flat" data segment, but
|
||||
; no segment register designates it yet.
|
||||
*/
|
||||
mov eax, cs
|
||||
add eax, byte 1<<3 ; the next segment after %cs
|
||||
add eax, 1<<3 // the next segment after %cs
|
||||
mov ds, eax
|
||||
mov es, eax
|
||||
/*
|
||||
; fs, gs set by startup_32 in arch/i386/kernel/head.S
|
||||
|
||||
; Linux Documentation/i386/boot.txt "SAMPLE BOOT CONFIGURATION" says
|
||||
|
@ -61,108 +59,99 @@ start:
|
|||
|
||||
; In any case, avoid EBDA (Extended BIOS Data Area) below 0xA0000.
|
||||
; boot.txt says 0x9A000 is the limit. LILO goes up to 0x9B000.
|
||||
*/
|
||||
lea ecx, [stack_offset + esi] // (0x9000 + 0x90000) typical
|
||||
mov [-8 + ecx], ecx // 32-bit offset for stack pointer
|
||||
mov [-4 + ecx], eax // segment for stack
|
||||
lss esp, [-8 + ecx] // %ss:%esp= %ds:0x99000
|
||||
|
||||
lea ecx, ['STAK' + esi] ; (0x9000 + 0x90000) typical
|
||||
mov [-8 + ecx], ecx ; 32-bit offset for stack pointer
|
||||
mov [-4 + ecx], eax ; segment for stack
|
||||
lss esp, [-8 + ecx] ; %ss:%esp= %ds:0x99000
|
||||
push 0
|
||||
popf // BIOS can leave random flags (such as NT)
|
||||
|
||||
push byte 0
|
||||
popf ; BIOS can leave random flags (such as NT)
|
||||
// do not clear .bss: at this point, .bss comes only from
|
||||
// arch/i386/boot/compressed/*.o which we are replacing entirely
|
||||
|
||||
; do not clear .bss: at this point, .bss comes only from
|
||||
; arch/i386/boot/compressed/*.o which we are replacing entirely
|
||||
or ebp, -1 // decompressor assumption
|
||||
mov eax, offset original_entry // 0x100000 : address of startup_32
|
||||
push cs // MATCH00
|
||||
push eax // MATCH00 entry address
|
||||
push edi // MATCH01 save
|
||||
push esi // MATCH02 save
|
||||
|
||||
or ebp, byte -1 ; decompressor assumption
|
||||
mov eax, 'KEIP' ; 0x100000 : address of startup_32
|
||||
push cs ; MATCH00
|
||||
push eax ; MATCH00 entry address
|
||||
push edi ; MATCH01 save
|
||||
push esi ; MATCH02 save
|
||||
|
||||
%ifdef __LZCALLT1__
|
||||
push eax ; MATCH03 src unfilter
|
||||
%endif; __LZDUMMY0__
|
||||
%ifdef __LZCKLLT1__
|
||||
push eax ; MATCH03 src unfilter
|
||||
push byte '?' ; MATCH04 cto unfilter
|
||||
push 'ULEN' ; MATCH05 len unfilter
|
||||
%endif; __LZDUMMY1__
|
||||
%ifdef __LBZIMAGE__
|
||||
mov esi, 'ESI0'
|
||||
mov edi, 'EDI0'
|
||||
mov ecx, 'ECX0'
|
||||
section LZCALLT1
|
||||
push eax // MATCH03 src unfilter
|
||||
section LZCKLLT1
|
||||
push eax // MATCH03 src unfilter
|
||||
//push offset filter_cto // MATCH04 cto unfilter
|
||||
.byte 0x6a, filter_cto // MATCH04 cto unfilter
|
||||
push offset filter_length // MATCH05 len unfilter
|
||||
section LBZIMAGE
|
||||
mov esi, offset copy_source
|
||||
mov edi, offset copy_dest
|
||||
mov ecx, offset words_to_copy
|
||||
|
||||
std
|
||||
rep
|
||||
movsd
|
||||
cld
|
||||
|
||||
mov esi, 'ESI1' ; esi = src for decompressor
|
||||
xchg eax, edi ; edi = dst for decompressor = 0x100000
|
||||
jmp .1 + 'JMPD' ; jump to the copied decompressor
|
||||
.1:
|
||||
%else; __LZIMAGE0__
|
||||
mov esi, offset src_for_decompressor
|
||||
xchg eax, edi // edi = dst for decompressor = 0x100000
|
||||
jmp decompressor // jump to the copied decompressor
|
||||
|
||||
; this checka20 stuff looks very unneccessary to me
|
||||
section LZIMAGE0
|
||||
|
||||
// this checka20 stuff looks very unneccessary to me
|
||||
checka20:
|
||||
inc edi ; change value
|
||||
mov [1 + ebp], edi ; store to 0x000000 (even megabyte)
|
||||
cmp [eax], edi ; compare 0x100000 ( odd megabyte)
|
||||
je checka20 ; addresses are [still] aliased
|
||||
inc edi // change value
|
||||
mov [1 + ebp], edi // store to 0x000000 (even megabyte)
|
||||
cmp [eax], edi // compare 0x100000 ( odd megabyte)
|
||||
je checka20 // addresses are [still] aliased
|
||||
|
||||
cld
|
||||
mov esi, 'ESI1'
|
||||
xchg eax, edi ; edi = dst for decompressor = 0x100000
|
||||
mov esi, offset src_for_decompressor
|
||||
xchg eax, edi // edi = dst for decompressor = 0x100000
|
||||
|
||||
%endif; __LZCUTPOI__
|
||||
section LZCUTPOI
|
||||
|
||||
; =============
|
||||
; ============= DECOMPRESSION
|
||||
; =============
|
||||
// =============
|
||||
// ============= DECOMPRESSION
|
||||
// =============
|
||||
|
||||
%include "arch/i386/nrv2b_d32.ash"
|
||||
%include "arch/i386/nrv2d_d32.ash"
|
||||
%include "arch/i386/nrv2e_d32.ash"
|
||||
%include "arch/i386/lzma_d.ash"
|
||||
//#include "arch/i386/nrv2b_d32.ash"
|
||||
//#include "arch/i386/nrv2d_d32.ash"
|
||||
//#include "arch/i386/nrv2e_d32.ash"
|
||||
#include "arch/i386/nrv2e_d32_2.ash"
|
||||
//#include "arch/i386/lzma_d.ash"
|
||||
|
||||
; =============
|
||||
; ============= UNFILTER
|
||||
; =============
|
||||
// =============
|
||||
// ============= UNFILTER
|
||||
// =============
|
||||
|
||||
%ifdef __LZCKLLT9__
|
||||
pop ecx ; MATCH05 len
|
||||
pop edx ; MATCH04 cto
|
||||
pop edi ; MATCH03 src
|
||||
section LZCKLLT9
|
||||
pop ecx // MATCH05 len
|
||||
pop edx // MATCH04 cto
|
||||
pop edi // MATCH03 src
|
||||
|
||||
ckt32 0, dl ; dl has cto8
|
||||
ckt32 0, dl // dl has cto8
|
||||
/*
|
||||
;0: Filter.addvalue = kernel_entry already did the 'add' at filter time
|
||||
;[the runtime address of the destination was known], so we save 4 bytes
|
||||
;(plus 1 cycle per instance) by not doing the 'add' when unfiltering.
|
||||
;If .addvalue was 0, then use 'edi' instead of 0 in call to ckt32,
|
||||
;to compensate for difference in origin of buffer.
|
||||
*/
|
||||
|
||||
%endif; __LZDUMMY2__
|
||||
%ifdef __LZCALLT9__
|
||||
pop edi ; MATCH03 src
|
||||
section LZCALLT9
|
||||
pop edi // MATCH03 src
|
||||
cjt32 0
|
||||
%endif; __LINUZ990__
|
||||
pop esi ; MATCH02 restore
|
||||
pop edi ; MATCH01 restore
|
||||
xor ebx, ebx ; booting the 1st cpu
|
||||
retf ; MATCH00 set cs
|
||||
|
||||
; =============
|
||||
; ============= CUT HERE
|
||||
; =============
|
||||
section LINUZ990
|
||||
pop esi // MATCH02 restore
|
||||
pop edi // MATCH01 restore
|
||||
xor ebx, ebx // booting the 1st cpu
|
||||
lret // MATCH00 set cs
|
||||
|
||||
%include "include/header.ash"
|
||||
#include "include/header2.ash"
|
||||
|
||||
eof:
|
||||
; __LITHEEND__
|
||||
section .data
|
||||
dd -1
|
||||
dw eof
|
||||
|
||||
|
||||
; vi:ts=8:et:nowrap
|
||||
// vi:ts=8:et:nowrap
|
||||
|
|
Loading…
Reference in New Issue
Block a user