from idautils import * def XorIt(key, bStr): newstr = '' ctr = 0 for x in bStr: newstr += chr(bStr[ctr] ^ key) ctr += 1 return newstr def decoder(addr, bytes): strDecoded = '' # first byte is strlen and part of the key length = idaapi.get_byte(addr) key = idaapi.get_byte(addr) addr += 1 print length for i in range(0,length+1): aByte = idaapi.get_byte(addr) bytes.append(aByte) addr += 1 print "Byte val: 0x%x" % (aByte) print bytes key = key ^ bytes[length] print "Xor key: 0x%x" % key print "popping last element: 0x%x" % bytes[length] bytes.pop(length) decoded = XorIt(key, bytes) del bytes[:] return decoded # walk disassembly backwards until we find specific disasm # return it's addr def disasmBack(disAddr, dis): # we're passed a start addr & disasm to find i = 1 ndis = GetDisasm(disAddr - i) while (ndis.find(dis) == -1): i += 1 ndis = GetDisasm(disAddr - i) return (disAddr - i) def getRefsTo(fnAddr, refList): for ref in CodeRefsTo(fnAddr, 1): # add each ref to XorDecode our list refList.append(ref) def main(): byteList = [] addrList = [] # Get the address @ cursor ea = ScreenEA() if ea == idaapi.BADADDR: print("Could not get get_screen_ea()") return # populate the list of xrefs to the decode fn getRefsTo(ea, addrList) for addr in addrList: print ("XORDecode found at: 0x%x") % addr # get the addr of the first push param2 = disasmBack(addr, 'push') # then the addr of the 2nd push param1 = disasmBack(param2, 'push') # walk up to find the start of the addr codeStart = FindCode(param1, SEARCH_UP) # then get the operand of that disasm addrEncoded = GetOperandValue(codeStart, 0) print ("Param One at: 0x%x \n\tPoints to byte array at: 0x%x") % (codeStart, addrEncoded) newComment = decoder(addrEncoded, byteList) print ("Decoded String: \n" ) print newComment MakeRptCmt(addrEncoded, newComment) if __name__=='__main__': main()