Skip to content

Instantly share code, notes, and snippets.

@3096
Last active June 17, 2024 10:54
Show Gist options
  • Save 3096/ffd6d257f148aab0b74bfc50dfe43e80 to your computer and use it in GitHub Desktop.
Save 3096/ffd6d257f148aab0b74bfc50dfe43e80 to your computer and use it in GitHub Desktop.
# If you see very long/bad variable names and questionable design choice, probably because I wrote this in sleep deprivation
import sys
def findBytesInTarget(findingBytes, target):
foundList = []
findingOffestInTarget = 0
while True:
offset = target.find(findingBytes, findingOffestInTarget)
if offset is -1:
break
foundList.append(offset)
if len(foundList) > 1:
break
findingOffestInTarget = offset + 1
return foundList
#return offset if found once, -1 if not found, (-1 - occurrence count) if found more than once
def findOffsetInTargetWithLen(source, target, offsetInSource, byteLen):
foundList = []
for shift in range(0, byteLen, 4):
findingOffestAfterShift = offsetInSource - shift
findingBytes = source[findingOffestAfterShift:findingOffestAfterShift+byteLen]
foundList = findBytesInTarget(findingBytes, target)
if len(foundList) is 1:
ret = findBytesInTarget(findingBytes, source)
if len(ret) is 1:
return foundList[0] + shift
else:
return -2
return -1 - len(foundList)
STARTING_FIND_LEN = 16
MAX_INCREASE = 0x40
# Return [offset, len searched], -1 if not found
def findOffestInTarget(source, target, offsetInSource):
MIN_FIND_LEN = 8
findLenIncrease = 0
findLenUpperStop = False
while True:
findLenUpper = STARTING_FIND_LEN + findLenIncrease + 4
if not findLenUpperStop:
ret = findOffsetInTargetWithLen(source, target, offsetInSource, findLenUpper)
if ret >= 0:
return [ret, findLenUpper]
if ret is -1:
findLenUpperStop = True
if findLenUpperStop is True:
break
findLenIncrease = findLenIncrease + 4
findLenIncrease = 0
findLenLowerStop = False
while True:
findLenLower = STARTING_FIND_LEN - findLenIncrease
if findLenLower < MIN_FIND_LEN:
break
if not findLenLowerStop:
ret = findOffsetInTargetWithLen(source, target, offsetInSource, findLenLower)
if ret >= 0:
return [ret, findLenLower]
if ret < -2:
findLenLowerStop = True
if findLenLowerStop is True:
break
findLenIncrease = findLenIncrease + 4
return [-1, -1]
def main(argc, argv):
if argc < 4:
print('Too few args')
print('Usage: %s [old_file] [new_file] [text_file] [(optional) start line #] [(optional) end line #]' % argv[0])
print(' or: %s [old_file] [new_file] [offset from old_file]' % argv[0])
return
fileByteFrom = argv[1]
fileFindOffstIn = argv[2]
lineNumberStart = 1
if argc >= 5:
lineNumberStart = int(argv[4], 10)
lineNumberEnd = -1
if argc >= 6:
lineNumberEnd = int(argv[5], 10)
offsetList = []
try:
offset = int(argv[3], 16)
offsetList.append(argv[3])
except ValueError:
with open(argv[3], 'r') as f:
offsetList = f.readlines()
if lineNumberEnd < 0 or lineNumberEnd > len(offsetList):
lineNumberEnd = len(offsetList)
with open(fileByteFrom, 'rb') as f:
sourceFile = f.read()
with open(fileFindOffstIn, 'rb') as f:
targetFile = f.read()
for lineIndex in range(lineNumberStart-1, lineNumberEnd):
offset = -1
try:
offset = int(offsetList[lineIndex][:8], 16)
ret = 0
increasing = 0
finding_offset = offset + increasing
while increasing <= MAX_INCREASE and finding_offset + STARTING_FIND_LEN < len(sourceFile):
ret = findOffestInTarget(sourceFile, targetFile, finding_offset)
if ret[0] >= increasing:
ret[0] = ret[0] - increasing
break
increasing = increasing + 4
finding_offset = offset + increasing
print('{:08X}'.format(ret[0]), end='')
print(offsetList[lineIndex][8:-1], end='')
if ret[0] is -1:
print('\nWARNING: ^ failed to find matching bytes for offset, please freak out')
else:
if increasing > 0:
print(' // Found match at {:08X}+{:X} ({:08X})'.format(ret[0], increasing, ret[0]+increasing), end='')
print(' // Confidence level: {}'.format(ret[1]))
except ValueError:
print(offsetList[lineIndex], end='')
if __name__ == '__main__':
main(len(sys.argv), sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment