Skip to content

Instantly share code, notes, and snippets.



Created May 1, 2019
What would you like to do?
Do memory diffing on specific block sizes
import struct
import sys
def diffing(oldbuff, newbuff, op):
offsets = set()
for i in range(0, min(len(oldbuff), len(newbuff))):
if op(oldbuff[i], newbuff[i]):
return offsets
def alignbuff(buff, blksize):
""" Aligns a buffer on a blocksize and returns a list of values """
pattern = {
1: 'B',
2: 'H',
4: 'I'
if len(buff) % blksize != 0:
buff = buff[:-(len(buff) % blksize)]
count = len(buff) // blksize
fmt = '<' + str(count) + pattern[blksize]
return struct.unpack(fmt, buff)
def main():
if len(sys.argv) < 5:
print("usage: memdiff (8/16/32) 'pattern' file1 file2 ...")
size = sys.argv[1]
pattern = sys.argv[2]
files = sys.argv[3:]
if size not in ["8", "16", "32"]:
print("Invalid size: {}".format(size))
bytesize = int(size) // 8
if len(pattern) != len(files)-1:
print("Pattern has a wrong size of {}. Should be {}".format(len(pattern), len(files)-1))
cmpmap = {
'+': lambda o, n: o < n,
'-': lambda o, n: o > n,
'=': lambda o, n: o == n
cur_offsets = None # Contains the currently active values after the search
offsets_lst = {} # Contains the offset, and the chain of changed values
for i, p in enumerate(pattern):
if p not in cmpmap:
print("invalid pattern char '{}'. Should be either '+' or '-'".format(p))
oldfile = files[i]
newfile = files[i+1]
oldbytes = open(oldfile, "rb").read()
oldbytes = alignbuff(oldbytes, bytesize)
newbytes = open(newfile, "rb").read()
newbytes = alignbuff(newbytes, bytesize)
offsets = diffing(oldbytes, newbytes, cmpmap[p])
if cur_offsets is None:
# When we have the first run we simply copy offsets
cur_offsets = set()
for o in offsets:
offsets_lst[o] = [oldbytes[o]]
# If we already have existing offsets we do the union
cur_offsets = cur_offsets.intersection(offsets)
# Now we fill our offset_lst with the new entries
for o in cur_offsets:
newe = newbytes[o]
for o in cur_offsets:
values = " -> ".join(map(lambda a: "0x{:08x}".format(a), offsets_lst[o]))
print("0x{:08x} : {}".format(o*bytesize, values))
if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.