IDA

代码

将函数传入的参数指针,取值后Xor3计算的结果,作为返回值的重命名参数:
image.png

汇编

取“push offset [地址]”中地址保存的值,Xor 3:
image.png

IDA Python

文件:544A6B033668548D57574702DD13E3BE

  1. import idc
  2. import idaapi
  3. import easygui
  4. def GetAdd_StrXored3(addr):
  5. # prev_head:获取上一行汇编
  6. addr = prev_head(addr)
  7. # print_insn_mnem:获取操作符
  8. # print_operand:获取操作数
  9. if print_insn_mnem(addr) == "push" and "offset" in print_operand(addr,0):
  10. #get_operand_value:获取操作值
  11. return get_operand_value(addr,0)
  12. else:
  13. return 0
  14. def GetStr_Xored3(addr):
  15. outChar = ""
  16. while(True):
  17. byte = idaapi.get_byte(addr)
  18. if byte != 0:
  19. outChar += chr(byte)
  20. else:
  21. break
  22. addr += 1
  23. return outChar
  24. def GetStr_Decoded(str):
  25. #加密Key值
  26. key = 3
  27. i = 0
  28. outChar = ""
  29. length = len(str)
  30. while i < length:
  31. outChar += chr(ord(str[i]) ^ key)
  32. i += 1
  33. return outChar
  34. if __name__ == '__main__':
  35. strFunction = easygui.enterbox("请输入解密函数地址:\r\n*544A6B033668548D57574702DD13E3BE样本为402901")
  36. addFunction = int(strFunction, 16)
  37. print("解密函数地址:", hex(addFunction).upper()[2:])
  38. for x in XrefsTo(addFunction, flags = 0):
  39. addStrXored3 = GetAdd_StrXored3(x.frm)
  40. if addStrXored3 != 0:
  41. strXored3 = GetStr_Xored3(addStrXored3)
  42. strDecoded = GetStr_Decoded(strXored3)
  43. print("加密 | 解密:", strXored3, " | ", strDecoded)
  44. set_cmt(prev_head(x.frm), strDecoded, 0)
  45. else:
  46. continue
  47. print("结束")

运行

image.png

打印

image.png

找BUG

个数不对,总共35处调用,打印结果是18个。
打印出交叉引用的函数地址和参数地址,发现有多个参数地址为0值:
image.png

汇编代码不同

即使是同一个函数,但是传输传递的方式有可能不同,该样本传递的参数有两种传参方式。
image.png

解决方案

对操作符为mov的上一行汇编,再取上一行地址。