10
votes

GAHH, code not working is bad code indeed!

  in RemoveRETNs
      toOutput[currentLoc - 0x00400000] = b'\xCC' TypeError: 'bytes' object does not support item assignment

How can I fix this?

inputFile = 'original.exe'
outputFile = 'output.txt'
patchedFile = 'original_patched.exe'

def GetFileContents(filename):
    f = open(filename, 'rb')
    fileContents = f.read()
    f.close()

    return fileContents

def FindAll(fileContents, strToFind):
    found = []

    lastOffset = -1

    while True:
        lastOffset += 1
        lastOffset = fileContents.find(b'\xC3\xCC\xCC\xCC\xCC', lastOffset)

        if lastOffset != -1:
            found.append(lastOffset)
        else:
            break

    return found

def FixOffsets(offsetList):
    for current in range(0, len(offsetList)):
        offsetList[current] += 0x00400000
    return offsetList

def AbsentFromList(toFind, theList):
    for i in theList:
        if i == toFind:
            return True
    return False

# Outputs the original file with all RETNs replaced with INT3s.
def RemoveRETNs(locationsOfRETNs, oldFilesContents, newFilesName):
    target = open(newFilesName, 'wb')

    toOutput = oldFilesContents

    for currentLoc in locationsOfRETNs:
        toOutput[currentLoc - 0x00400000] = b'\xCC'

    target.write(toOutput)

    target.close()

fileContents = GetFileContents(inputFile)
offsets = FixOffsets(FindAll(fileContents, '\xC3\xCC\xCC\xCC\xCC'))
RemoveRETNs(offsets, fileContents, patchedFile)

What am I doing wrong, and what can I do to fix it? Code sample?

2

2 Answers

31
votes

Change the return statement of GetFileContents into

return bytearray(fileContents)

and the rest should work. You need to use bytearray rather than bytes simply because the former is mutable (read/write), the latter (which is what you're using now) is immutable (read-only).

8
votes

Bytestrings (and strings in general) are immutable objects in Python. Once you create them, you can't change them. Instead, you have to create a new one that happens to have some of the old content. (For instance, with a basic string, newString = oldString[:offset] + newChar + oldString[offset+1:] or the like.)

Instead, you may want to convert the bytestring to a list of bytes first, or a bytearray, manipulate it, and then convert the bytearray/list back to a static string after all of the manipulations have been done. This avoids creating a new string for each replace operation.