-
-
Save dougallj/bfbffffe8af7a08e322633d7d7f19af7 to your computer and use it in GitHub Desktop.
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
# pypy3 recommended for speed (210ms, vs 17 seconds with cpython) | |
# usage: | |
# ensure LOAD_BASE is correct, then: | |
# | |
# magic32grep.py '===1' kernelcache.release.mac13g | |
# | |
# lines starting with * are adjacent, compatible instructions, | |
# although non-adjacent instructions might be relevant too. | |
import sys | |
import struct | |
import re | |
LOAD_BASE = 0xFFFFFE0007004000 | |
def get_hw(d): return (d >> 21) & 3 | |
def get_imm16(d): return (d >> 5) & 0xFFFF | |
def is_MOVZ_32_movewide(d): return (d & 0xff800000) == 0x52800000 | |
def is_MOVK_32_movewide(d): return (d & 0xff800000) == 0x72800000 | |
def get_Rd(d): return (d >> 0) & 0x1F | |
def main(magicstr, filenames): | |
for filename in filenames: | |
find_magic(magicstr, filename) | |
def find_magic_in_file(filename, text, magic): | |
magic_high = magic >> 16 | |
magic_low = magic & 0xFFFF | |
last_result = None | |
last_hw = 0 | |
last_rd = 0 | |
last_movz = False | |
for i in range(0, len(text), 4): | |
d = struct.unpack_from('<I', text, i)[0] | |
if (is_MOVZ_32_movewide(d) or is_MOVK_32_movewide(d)) and ((get_imm16(d) == magic_high and get_hw(d) == 1) or (get_imm16(d) == magic_low and get_hw(d) == 0)): | |
prefix = ' ' | |
if i - 4 == last_result and get_hw(d) != last_hw and last_rd == get_Rd(d) and last_movz != is_MOVZ_32_movewide(d): | |
prefix = '*' | |
print(prefix, '%x' % (LOAD_BASE + i), ('MOVZ' if is_MOVZ_32_movewide(d) else 'MOVK'), 'W' + str(get_Rd(d)) + ',', hex(get_imm16(d) << (get_hw(d) * 16))) | |
last_rd = get_Rd(d) | |
last_result = i | |
last_hw = get_hw(d) | |
last_movz = is_MOVZ_32_movewide(d) | |
def find_magic(magicstr, filename): | |
text = open(filename, 'rb').read() | |
# little endian | |
magic = struct.unpack('<I', magicstr.encode('latin-1'))[0] | |
find_magic_in_file(filename, text, magic) | |
# big endian | |
magic = struct.unpack('>I', magicstr.encode('latin-1'))[0] | |
find_magic_in_file(filename, text, magic) | |
if __name__ == '__main__': | |
main(sys.argv[1], sys.argv[2:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment