Created
January 13, 2024 14:07
-
-
Save dzwdz/4c51df9cc491700fccc0d33db516e709 to your computer and use it in GitHub Desktop.
find SFX RAR header
This file contains hidden or 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
| import sys, struct | |
| ### some helper functions ### | |
| def die(*args): | |
| print(*args) | |
| exit(0) | |
| def pread(fp, size, offset): | |
| fp.seek(offset) | |
| return fp.read(size) | |
| def read_u32le(fp, offset): # unsigned, 32 bits, little endian | |
| return struct.unpack('<L', pread(fp, 4, offset))[0] | |
| def hexdump(buf, offset=0): | |
| for i in range(0, len(buf), 16): | |
| line = buf[i:i+16] | |
| print( | |
| '%08x' % (offset + i), | |
| ' '.join(["%02x" % c for c in line]), | |
| ''.join([(chr(c) if 0x20 <= c < 0x7F else '.') for c in line]), | |
| sep=' ' | |
| ) | |
| ### | |
| print(sys.argv[1]) | |
| fp = open(sys.argv[1], 'rb') | |
| if pread(fp, 2, 0) != b'MZ': die("no MZ") | |
| pe_header = read_u32le(fp, 0x3c) | |
| if pread(fp, 4, pe_header) != b'PE\0\0': die("no PE header") | |
| # not sure where the 0x140 came from | |
| sections_loc = pe_header + 0xf8 | |
| sections = pread(fp, 0x140, sections_loc) | |
| print("sections:") | |
| hexdump(sections, sections_loc) | |
| # find .rsrc's entry | |
| rsrc_header = sections_loc + sections.index(b'.rsrc') | |
| print(".rsrc header at 0x%x" % rsrc_header) | |
| # https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/Debug/pe-format.md#section-table-section-headers | |
| rsrc_loc = read_u32le(fp, rsrc_header + 20) # PointerToRawData | |
| rsrc_len = read_u32le(fp, rsrc_header + 16) # SizeOfRawData | |
| print('.rsrc', hex(rsrc_loc), hex(rsrc_len)) | |
| stub_end = rsrc_loc + rsrc_len | |
| print('stub_end', hex(stub_end)) | |
| if pread(fp, 4, stub_end) != b'Rar!': die("didn't find RAR header") | |
| print("ok, found RAR header") | |
| """ | |
| this works on the SFX that inspired this issue | |
| file(1) has two other ways of detecting SFXes, though | |
| 1. just looking for "Rar!" at 0x17888. I assume this targets a particular version | |
| of the SFX stub, and is probably redundant with the other rules? | |
| 2. "Skip to the end of the EXE", by reading some stuff from the MZ header. | |
| I can't figure out how it's supposed to work, though, and I don't have any | |
| archives that this checks works for handy. | |
| I think by "EXE" they might actually mean old DOS executables? | |
| That being said - you can get the Rar for DOS installers archive.org, | |
| and neither file(1) nor bsdtar seem to recognize them as SFX archives (which they are). | |
| https://web.archive.org/web/20030527011110/http://www.rarlab.com/download.htm | |
| https://web.archive.org/web/20070707133254/http://www.rarlab.com/download.htm | |
| """ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment