forked from ReScrap/ScrapHacks
Daniel Seiller
7afdfb5869
- Add notes folder with MDBook documentation (the NOTES.md file was getting kind of large) - Add rz_analyze.py, does the same a r2_analyze.py just with Rizin instead of radare2 so the project can be loaded in Cutter (*and* it's faster) - Add Scrap.rzdb, Rizin database for the Scrap.exe executable - Add Scrapper_rs, Rust version of .packed extractor and repacker - replace helplib.txt with helplib.md - add Py_Docs folder which contains generated documentation for the binary python modules built into Scrap.exe
75 lines
2.3 KiB
Python
75 lines
2.3 KiB
Python
import msgpack as mp
|
|
import sys
|
|
import os
|
|
from tqdm import tqdm
|
|
import struct
|
|
import binascii
|
|
import string
|
|
import re
|
|
from binascii import hexlify
|
|
|
|
|
|
def gen():
|
|
with open(sys.argv[1], "rb") as fh:
|
|
size = os.stat(sys.argv[1]).st_size
|
|
progbar = tqdm(
|
|
total=size, unit="bytes", unit_scale=True, unit_divisor=1024, leave=False
|
|
)
|
|
pos = 0
|
|
for entry in mp.Unpacker(fh, raw=True):
|
|
progbar.update(fh.tell() - pos)
|
|
pos = fh.tell()
|
|
for k in entry.copy():
|
|
k_s = str(k, "utf8")
|
|
if k_s not in ["data", "stack", "timestamp"]:
|
|
entry[k] = str(entry.pop(k), "utf8")
|
|
entry[k_s] = entry.pop(k)
|
|
entry["stack"] = "|".join(
|
|
["{:08X}".format(int(str(v, "utf8"), 16)) for v in entry["stack"][::-1]]
|
|
)
|
|
yield entry
|
|
|
|
|
|
def strdump(data):
|
|
printable_chars = set(bytes(string.printable, "ascii")) - set(b"\n\r\t\x0b\x0c")
|
|
return "".join(chr(c) if c in printable_chars else "." for c in data)
|
|
|
|
|
|
# best=sorted(tqdm(gen(),ascii=True),key=lambda v:len(v['data']),reverse=True)
|
|
|
|
# def score(entry):
|
|
# return len(entry['data'])
|
|
|
|
# def analyze(entry):
|
|
# data=entry['data']
|
|
# entry['infos'] = {
|
|
# 'len':len(data),
|
|
# }
|
|
# for bo in "><":
|
|
# for t in "hHiIlLqQefd":
|
|
# fmt="{}{}".format(bo,t)
|
|
# if len(data)%struct.calcsize(fmt)==0:
|
|
# entry['infos'][fmt]=[v[0] for v in struct.iter_unpack(fmt,data)]
|
|
# return entry
|
|
|
|
filters = sys.argv[2:]
|
|
with open("all.log", "w") as of:
|
|
for entry in gen():
|
|
fm = any(
|
|
all(s.lower() in entry["filename"].lower() for s in f.split("|"))
|
|
for f in filters
|
|
)
|
|
if filters and not fm:
|
|
continue
|
|
is_magic = bytes(entry["block_id"], "utf8").ljust(4, b"\0") == entry["data"]
|
|
entry["data_len"] = len(entry["data"])
|
|
entry["str"] = strdump(entry["data"])
|
|
entry["data"] = entry["data"].hex().upper()
|
|
if is_magic:
|
|
print("#" * 50, file=of)
|
|
print(
|
|
"{timestamp} {block_id} {filename} {data_len:08X} {data} {str}".format(
|
|
**entry
|
|
),
|
|
file=of,
|
|
)
|