views:

158

answers:

2

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?

+3  A: 

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.

Amber
How do I convert it to a list of bytes/bytestring and then output it to a file?
Clark Gaebel
`[i for i in x]` should make a list out of just about anything. Not sure if it's the best way, but it's one way.
Thanatos
Just use `bytearray(stuff)` or `list(stuff)` to convert `stuff` to a bytearray or list, respectively.
Amber
+4  A: 

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 read/write, the latter (which is what you're using now) is read-only.

Alex Martelli