Last active
June 17, 2024 10:54
-
-
Save 3096/ffd6d257f148aab0b74bfc50dfe43e80 to your computer and use it in GitHub Desktop.
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
# 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