Advertising (This ad goes away for registered users. You can Login or Register)

Rebuild PSP LZ decompression from C code via Python's LZMA module

Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
Post Reply
TD2
Posts: 7
Joined: Sat Mar 24, 2018 9:06 pm

Rebuild PSP LZ decompression from C code via Python's LZMA module

Post by TD2 » Thu Apr 25, 2019 5:56 pm

Trying to rebuild the PSP's LZ decompression from pkg2zip's existing C code.
Found a short compressed example with only 80/0x50 bytes that becomes 32768/0x8000 bytes with a simple pattern: first 28672/0x7000 bytes are 0x00, while the other 4096/0x1000 are 0x20.
Also found one single occurrence [1] on the internet with a similar issue, but it's "solution" doesn't work for me.
This is all with Python 3 under Windows and Linux. Test script available below.

Can anyone help where I missed something to adapt the solution? Or any other ideas?

Thanks in advance
TD

[1] https://www.reddit.com/r/learnpython/co ... g/?depth=1

Code: Select all

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
### ^^^ see https://www.python.org/dev/peps/pep-0263/

import sys
import binascii
import lzma
#import _lzma

print("Python Version", sys.version)

CONST_INPUT_BYTES = bytes.fromhex("05ff80010ed6e737043f530bbce7a37214dc388e0caa949346bff87215047e9ce0ec8b6c7deef07a90910eb3c78bd8089d6809e59efe43035b0b7c52e4fefe663a31665fdfdce21da39e05cdc2c8002e")
## First 5 Bytes:
## Input_Bytes[0] = 05 = rc->lc
## Input_Bytes[1:1+4] = ff80010e = rc->code (Big Endian)
CONST_EXPECTED_BYTES = bytearray(b"\x00" * 0x7000)
CONST_EXPECTED_BYTES.extend(b"\x20" * 0x1000)
CONST_EXPECTED_BYTES = bytes(CONST_EXPECTED_BYTES)
#f = open("expected.hex","wb")
#f.write(CONST_EXPECTED_BYTES)
#f.close()

### Display length of bytes
print("input: length", len(CONST_INPUT_BYTES), type(CONST_INPUT_BYTES))
print("expected result: length", len(CONST_EXPECTED_BYTES), type(CONST_EXPECTED_BYTES))


##### Goal:
## Rebuild LZ decompression from https://github.com/lusid1/pkg2zip/blob/master/pkg2zip_psp.c#L26

## Tried:
## a) https://www.reddit.com/r/learnpython/comments/91bmar/lzma_raw_decoding/?depth=1
##    no access to lzma._decode_filter_properties()

LZ_Filter = lzma._decode_filter_properties(lzma.FILTER_LZMA1, CONST_INPUT_BYTES[0:0+5])
Decompressed_Bytes = lzma.decompress(CONST_INPUT_BYTES[5:], format=lzma.FORMAT_RAW, filters=LZ_Filter)

## Checks
print("decompressed: length", len(Decompressed_Bytes), type(Decompressed_Bytes))
if Decompressed_Bytes == CONST_EXPECTED_BYTES:
    print("Decompression SUCCESSFUL")
else:
    print("Decompressed:", len(Decompressed_Bytes), type(Decompressed_Bytes))
    print(binascii.hexlify(Decompressed_Bytes))
    print("Decompression FAILED")
Advertising

Post Reply

Return to “Programming and Security”