Last active
January 11, 2022 04:07
-
-
Save xyb/bebbcd214268fc28a208afc834ade6ed to your computer and use it in GitHub Desktop.
Convert CRX to zip file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Convert CRX to zip file. | |
# Inspired by https://github.com/peerigon/unzip-crx/blob/master/src/index.js | |
# nim c -d:release --gc:none --stackTrace:off --lineTrace:off --opt:size uncrx.nim | |
import system | |
import os | |
import streams | |
import strutils | |
const | |
zipMagicNumber = "PK\x03\x04" | |
crxMagicNumber = "Cr24" | |
proc skipCrxHeader(stream: FileStream) = | |
let magicNumber = stream.peekStr(4) | |
if magicNumber == zipMagicNumber: | |
return | |
if magicNumber != crxMagicNumber: | |
raise newException(ValueError, | |
"Invalid header: Does not start with Cr24") | |
discard stream.readStr(4) | |
let version = stream.readStr(4) | |
var zip_start_offset: uint32 | |
if version == "\2\0\0\0": | |
let | |
public_key_length = stream.readUInt32() | |
signature_length = stream.readUInt32() | |
zip_start_offset = 16 + public_key_length + signatureLength | |
elif version == "\3\0\0\0": | |
let | |
header_size = stream.readUInt32() | |
zip_start_offset = 12 + header_size | |
else: | |
raise newException(ValueError, | |
"Unexpected crx format version number.") | |
stream.setPosition(int(zip_start_offset)) | |
proc crx2zip() = | |
proc usage() = | |
echo "Save or print zip content of a CRX (Chrome Extension) file" | |
echo "" | |
echo "Usage:" | |
echo " crx2zip <crx_filename> [<zip_filename> | -]" | |
quit() | |
var args = commandLineParams() | |
if len(args) == 0: | |
usage() | |
let crxFile = args[0] | |
let destFilename = | |
if len(args) > 1: | |
args[1] | |
else: | |
if len(crxFile) >= 4 and toLowerAscii(crxFile)[^4 .. ^1] == ".crx": | |
crxFile[0 .. ^5] & ".zip" | |
else: | |
crxFile & ".zip" | |
if not fileExists(crxFile): | |
echo "file not found" | |
quit(1) | |
var crx = newFileStream(crxFile, fmRead) | |
var destFile = | |
if destFilename == "-": | |
newFileStream(stdout) | |
else: | |
newFileStream(destFilename, fmWrite) | |
try: | |
skipCrxHeader(crx) | |
except ValueError as ex: | |
echo ex.msg | |
quit(2) | |
const bufferSize = 1024 | |
var buffer: string | |
buffer.setLen(bufferSize) | |
while true: | |
let readBytes = crx.readDataStr(buffer, 0..<bufferSize) | |
if readBytes == 0: | |
break | |
destFile.write(buffer[0..readBytes-1]) | |
when isMainModule: | |
crx2zip() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment