# Simple attempt emulate suspicious functions in widewine (4.10.2209.0). Adjust to taste (starting point, logs, etc) and run while project is open. #@author Satsuoni #@category Deobfuscation #@keybinding #@menupath #@toolbar from binascii import hexlify import logging from ghidra.app.emulator import EmulatorHelper #from ghidra.program.model.symbol import SymbolUtilities from ghidra.util.task import ConsoleTaskMonitor from ghidra.program.model.pcode import PcodeOp from ghidra.program.model.symbol import * from ghidra.program.model.pcode import JumpTable from java.util import LinkedList, Arrays, ArrayList from ghidra.app.cmd.function import CreateFunctionCmd from ghidra.app.cmd.disassemble import DisassembleCommand from ghidra.program.model.lang import Register from ghidra.program.model.lang import OperandType from ghidra.program.model.lang import RegisterManager import array import sys logger = logging.getLogger("") logger.setLevel(logging.DEBUG) handler1=logging.StreamHandler(sys.stdout) class WarnFormatter(logging.Formatter): err_fmt = "ERROR: %(msg)s" warn_fmt = "Warning: %(msg)s" dbg_fmt = "DBG: %(module)s: %(lineno)d: %(msg)s" info_fmt = "%(msg)s" def __init__(self, fmt="%(levelno)s: %(msg)s"): logging.Formatter.__init__(self, fmt) def format(self, record): # Save the original format configured by the user # when the logger formatter was instantiated format_orig = self._fmt # Replace the original format with one customized by logging level if record.levelno == logging.DEBUG: self._fmt = WarnFormatter.dbg_fmt elif record.levelno == logging.INFO: self._fmt = WarnFormatter.info_fmt elif record.levelno == logging.ERROR: self._fmt = WarnFormatter.err_fmt elif record.levelno == logging.WARNING: self._fmt = WarnFormatter.warn_fmt # Call the original formatter class to do the grunt work result = logging.Formatter.format(self, record) # Restore the original format configured by the user self._fmt = format_orig return result formatter = WarnFormatter('%(message)s') handler1.setFormatter(formatter) handler2=logging.FileHandler("trunlog.log", mode='w', encoding="utf-8") handler2.setFormatter(formatter) logger.addHandler(handler1) logger.addHandler(handler2) def getAddress(offset): return currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(offset) def getProgramRegisterList(currentProgram): pc = currentProgram.getProgramContext() return pc.registers def step(emu,monitor): success = emu.step(monitor) if (success == False): lastError = emu.getLastError() logger.error("Emulation Error: '{}'".format(lastError)) return success def isCallInstruction(instr): if instr is None: return False flowType = instr.getFlowType() if flowType.isCall(): return True return False # 009bc60e heap alloc. No free available or necessary class FakeMemory(object): def __init__(self,startpoint): self.start=startpoint self.curpoint=self.start def allocate(self,ln): rpoint=self.curpoint self.curpoint+=ln return rpoint mem=FakeMemory( 0x000000F02FFF0000) def EmuRet(emu,offs=0): pos=emu.readStackValue(0,8,False) emu.writeRegister(emu.getPCRegister(), pos) stack=emu.readRegister("RSP") emu.writeRegister("RSP",stack+8+offs) def OperatorNew(emu): bytes=emu.readRegister("RCX") ptr=mem.allocate(bytes) logger.info("Allocating (new) {} bytes to {:x}".format(bytes,ptr)) emu.writeRegister("RAX",ptr) EmuRet(emu) def HeapAlloc(emu): bytes=emu.readRegister("R8") logger.info("Allocating {} bytes".format(bytes)) ptr=mem.allocate(bytes) emu.writeRegister("RAX",ptr) EmuRet(emu) def MFree(emu): bt2=emu.readRegister("R8") logger.info("Freed something at {:x}".format(bt2)) emu.writeRegister("RAX",bt2) EmuRet(emu) def EnterCriticalSection(emu): EmuRet(emu) def TryAcquireSRWLockExclusive(emu): emu.writeRegister("RAX",1) EmuRet(emu) tlsval=1 tlsstorage={} def TlsAlloc(emu): global tlsval emu.writeRegister("RAX",tlsval) tlsval+=1 EmuRet(emu) def TlsSetValue(emu): global tlsval,tlsstorage index=emu.readRegister("RCX") value=emu.readRegister("RDX") tlsstorage[index]=value emu.writeRegister("RAX",1) EmuRet(emu) def TlsGetValue(emu): global tlsval,tlsstorage index=emu.readRegister("RCX") if index in tlsstorage: emu.writeRegister("RAX",tlsstorage[index]) else: emu.writeRegister("RAX",0) EmuRet(emu) def QueryPerformanceFrequency(emu): offs=emu.readRegister("RCX") emu.writeMemoryValue(getAddress(offs),8,1000) emu.writeRegister("RAX",1) EmuRet(emu) def Ret0(emu): emu.writeRegister("RAX",0) EmuRet(emu) def Ret1(emu): emu.writeRegister("RAX",1) EmuRet(emu) def Ret1st(emu): emu.writeRegister("RAX",emu.readRegister("RCX")) EmuRet(emu) time_cnt=0 def timeGetTime(emu): global time_cnt emu.writeRegister("RAX",time_cnt) time_cnt+=1 EmuRet(emu) last_error=-20 def LoadLibrary(emu): global last_error offs=emu.readRegister("RCX") lname=emu.readMemory(getAddress(offs),200) logger.info("Load library: {}".format(lname)) emu.writeRegister("RAX",0) last_error=-21 EmuRet(emu) def GetLastError(emu): global last_error emu.writeRegister("RAX",last_error) EmuRet(emu) def SetLastError(emu): global last_error last_error=emu.readRegister("RCX") EmuRet(emu) def getptd_noexit(emu): global mem tiddata=mem.allocate(256) # _tiddata emu.writeRegister("RAX",tiddata) EmuRet(emu) def findwindowA(emu): lpclass=emu.readRegister("RCX") lpname=emu.readRegister("RDX") logger.info(emu.readNullTerminatedString(getAddress(lpclass),200)) logger.info(emu.readNullTerminatedString(getAddress(lpname),200)) emu.writeRegister("RAX",0) EmuRet(emu) def InitThreadHeader(emu): mm=emu.readRegister("RCX") logger.info("Init Thread header?") emu.writeMemoryValue(getAddress(mm),4,-1) EmuRet(emu) def InitThreadFooter(emu): mm=emu.readRegister("RCX") logger.info("Init Thread footer?") emu.writeMemoryValue(getAddress(mm),4,-1) EmuRet(emu) def GetRandom(emu): ptr=emu.readRegister("RCX") len=emu.readRegister("RDX") logger.info("Random... kinda") for a in range(len): emu.writeMemoryValue(getAddress(ptr),1,0xaf) ptr+=1 emu.writeRegister("RAX",1) EmuRet(emu) dict={} dict[getAddress(0x009bc60e )]=HeapAlloc dict[getAddress(0x009bc1ec )]=EnterCriticalSection dict[getAddress(0x009bc61a )]=MFree dict[getAddress(0x009bcae2 )]=TlsAlloc dict[getAddress(0x009bcb06 )]=TlsSetValue dict[getAddress(0x009bcaf8 )]=TlsGetValue dict[getAddress(0x009bcb14 )]=TryAcquireSRWLockExclusive dict[getAddress(0x009bc8d6 )]=EnterCriticalSection #void dict[getAddress(0x009bc874 )]=QueryPerformanceFrequency dict[getAddress(0x009bccb6 )]=timeGetTime dict[getAddress(0x009bc7f6 )]=LoadLibrary dict[getAddress(0x009bc422 )]=GetLastError dict[getAddress(0x18052d44c)]=EnterCriticalSection #FlsSetValue dict[getAddress(0x009bc7ba )]=EnterCriticalSection #LeaveCriticalSection dict[getAddress(0x009bcce8 )]=findwindowA dict[getAddress(0x009bc4ae )]=Ret0 #GetModuleHandle dict[getAddress(0x009bc4e4 )]=Ret0 #GetProcAddress dict[getAddress(0x009bcc80 )]=GetRandom #SystemFunction036 dict[getAddress(0x009bc81c )]=EnterCriticalSection #OutputDebugString - void dict[getAddress(0x009bc392 )]=Ret1 #GetCurrentThreadId dict[getAddress(0x009bc100 )]=Ret0 #AcquireSRWLockExclusive dict[getAddress(0x18052cc50)]=getptd_noexit dict[getAddress(0x009bca2a )]=SetLastError dict[getAddress(0x180256270)]=Ret0 #GetCurrentDir?? dict[getAddress(0x18050f1c0)]=OperatorNew #dict[getAddress(0x180111f45)]=Ret1 #probably a table generator. Very slow, but nothing works after without it dict[getAddress(0x18050f330)]=InitThreadHeader dict[getAddress(0x18050f3c8)]=InitThreadFooter dict[getAddress(0x180256d10)]=Ret1st dict[getAddress(0x18050f580)]=EnterCriticalSection def allocLargeStdstring(emu,len): ptr=mem.allocate(24) emu.writeMemoryValue(getAddress(ptr+8),8,len) emu.writeMemoryValue(getAddress(ptr+16),8,len) buf=mem.allocate(len) emu.writeMemoryValue(getAddress(ptr),8,buf) return ptr def HostAllocate(emu): bytes=emu.readRegister("RDX") logger.info("HostAllocate: {} bytes".format(bytes)) ptr=mem.allocate(bytes) emu.writeRegister("RAX",ptr) EmuRet(emu) dict[getAddress(0x0aa01)]=HostAllocate def HostSetTimer(emu): delay=emu.readRegister("RDX") logger.info("HostSetTimer: {} msec".format(delay)) EmuRet(emu) dict[getAddress(0x0aa02)]=HostSetTimer def HostGetCurrentWallTime(emu): logger.info("HostGetCurrentWallTime") emu.writeRegister("XMM0",0) EmuRet(emu) dict[getAddress(0x0aa03)]=HostGetCurrentWallTime def HostOnInitialized(emu): success=emu.readRegister("EDX") logger.info("OnInitialized : maybe?: {}".format(success)) EmuRet(emu) dict[getAddress(0x0aa04)]=HostOnInitialized def HostOnResolveKeyStatusPromise(emu): prid=emu.readRegister("EDX") logger.info("HostOnResolveKeyStatusPromise : {}".format(prid)) EmuRet(emu) dict[getAddress(0x0aa05)]=HostOnResolveKeyStatusPromise def HostOnResolveNewSessionPromise(emu): prid=emu.readRegister("EDX") sesid=emu.readRegister("R8") logger.info("OnResolveNewSessionPromise : {} {}".format(prid,sesid)) EmuRet(emu) dict[getAddress(0x0aa06)]=HostOnResolveNewSessionPromise def HostOnResolvePromise(emu): prid=emu.readRegister("EDX") logger.info("HostOnResolvePromise : {}".format(prid)) EmuRet(emu) dict[getAddress(0x0aa07)]=HostOnResolvePromise def HostOnRejectPromise(emu): prid=emu.readRegister("EDX") ex=emu.readRegister("R8") sc=emu.readRegister("R9") logger.info("HostOnRejectPromise : {} Exc: {} sc: {}".format(prid,ex,sc )) EmuRet(emu,8) dict[getAddress(0x0aa08)]=HostOnRejectPromise def HostOnSessionMessage(emu): saveSnapshot(emu,"OnSessionMessage.gz") messSize=emu.readStackValue(0x30,8,False) print(messSize) messPtr=emu.readStackValue(0x28,8,False) mtype=emu.readRegister("R9") logger.info("message_type") logger.info(mtype) mm=emu.readMemory(getAddress(messPtr),int(messSize)) logger.info("OnSessionMessage {} {} ".format( mtype, mm)) rmsg="" for a in mm: if a<0: a=256+a rmsg+="{:02X}".format(a) logger.info(rmsg) raise 999 EmuRet(emu,8) dict[getAddress(0x0aa09)]=HostOnSessionMessage def HostOnSessionKeysChange(emu): logger.info("HostOnSessionKeysChange") EmuRet(emu,8) dict[getAddress(0x0aa0a)]=HostOnSessionKeysChange def HostOnExpirationChange(emu): logger.info("HostOnExpirationChange") EmuRet(emu) dict[getAddress(0x0aa0b)]=HostOnExpirationChange def HostOnSessionClosed(emu): logger.info("HostOnSessionClosed") EmuRet(emu) dict[getAddress(0x0aa0c)]=HostOnExpirationChange def HostSendPlatformChallenge(emu): logger.info("HostSendPlatformChallenge") EmuRet(emu) dict[getAddress(0x0aa0d)]=HostSendPlatformChallenge def HostEnableOutputProtection(emu): logger.info("HostEnableOutputProtection") EmuRet(emu) dict[getAddress(0x0aa0e)]=HostEnableOutputProtection def HostQueryOutputProtectionStatus(emu): logger.info("HostQueryOutputProtectionStatus") EmuRet(emu) dict[getAddress(0x0aa0f)]=HostQueryOutputProtectionStatus def HostOnDeferredInitializationDone(emu): logger.info("HostOnDeferredInitializationDone") EmuRet(emu) dict[getAddress(0x0aa10)]=HostOnDeferredInitializationDone def HostCreateFileIO(emu): logger.info("HostCreateFileIO") emu.writeRegister("RAX",0) EmuRet(emu) dict[getAddress(0x0aa11)]=HostCreateFileIO def HostRequestStorageId(emu): logger.info("HostRequestStorageId") EmuRet(emu) dict[getAddress(0x0aa12)]=HostRequestStorageId # create Host structure+vtable def allocHost(emu): vt_ptr=mem.allocate(8*16) ptr=vt_ptr emu.writeMemoryValue(getAddress(ptr),8,0x0aa01) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa02) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa03) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa04) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa05) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa06) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa07) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa08) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa09) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa0a) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa0b) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa0c) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa0d) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa0e) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa0f) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa10) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa11) ptr+=8 emu.writeMemoryValue(getAddress(ptr),8,0x0aa12) cls=mem.allocate(8) emu.writeMemoryValue(getAddress(cls),8,vt_ptr) return cls def makeHost(emu): logger.info("Getting host") ptr=allocHost(emu) emu.writeRegister("RAX",ptr) EmuRet(emu) def isCallOther(instr): if instr is None: return False raw_pcode = instr.getPcode() for code in raw_pcode: if code.getOpcode()==PcodeOp.CALLOTHER: return True return False def getCallOtherName(instr): if instr is None: return None raw_pcode = instr.getPcode() for code in raw_pcode: if code.getOpcode()==PcodeOp.CALLOTHER: return currentProgram.getLanguage().getUserDefinedOpName(code.getInput(0).getOffset()) return None def skip(emu): executionAddress = emu.getExecutionAddress() instr=getInstructionAt(executionAddress) nextInstr=instr.getNext() lval = int("0x{}".format(nextInstr.getAddress()), 16) emu.writeRegister(emu.getPCRegister(), lval) dict[getAddress(0xf0000)]=makeHost initCdm=getAddress(0x180001040) monitor=ConsoleTaskMonitor() rspStart=0x000000002FFF0000 emu=EmulatorHelper(currentProgram) startaddr=initCdm#getAddress(0x18017e3b0) cur_fun=getFunctionContaining(startaddr) mainFunctionEntryLong = int("0x{}".format(cur_fun.getEntryPoint()), 16) emu.writeRegister(emu.getPCRegister(), mainFunctionEntryLong) emu.writeRegister("RSP", rspStart) emu.writeRegister("RBP", 0x000000002FFF0000) datstring=allocLargeStdstring(emu,256) emu.writeRegister("RDX",datstring) #clearkeys = "org.w3.clearkey" import struct def readULL(emu,addr): dat=emu.readMemory(addr,8) cdv=struct.unpack("=instr.getNumOperands(): return tp=instr.getOperandType(num) objlist=instr.getOpObjects(num) ln=len(objlist) if ln==0: return if tp&OperandType.SCALAR: #const self.type="const" self.value=int(str(objlist[0]),16) return if tp&OperandType.REGISTER and len(objlist)==1: #pure register self.type="register" self.value=str(objlist[0]) return if len(objlist)==2 and str(objlist[0])=="RSP": self.type="stackvar" self.value="0x{:x}".format(int(str(objlist[1]),0)) self.offset=int(str(objlist[1]),0) self.len=1 oprep=instr.getDefaultOperandRepresentation(num) if "xword" in oprep: self.length=16 elif "qword" in oprep: self.length=8 elif "dword" in oprep: self.length=4 elif "word ptr" in oprep: self.length=2 elif "byte ptr" in oprep: self.length=1 return if len(objlist)==2 and tp&OperandType.DYNAMIC and tp&OperandType.ADDRESS : #dword ptr [RCX + -0x4] self.type="memconst" self.value=str(objlist[1]) self.olist=objlist return if len(objlist)==2 and str(objlist[0])=="GS": self.type="debugho" self.value="__0x{:x}".format(int(str(objlist[1]),0)) return if len(objlist)==3 and isinstance(objlist[0],Register): #not quite correct, but. uff self.type="register" self.value=str(objlist[0]) return logger.warning("{} {:x} {} needs operand implementation {}".format(instr,tp,num,objlist)) #not sure why only these are missing. def pshuflw(emu,instr): if instr is None: return if instr.getNumOperands()!=3: return reg_into=Operand(instr,0) reg_from=Operand(instr,1) shuf=Operand(instr,2) if reg_into.type!="register" or reg_from.type!="register" or shuf.type!="const" : raise 33 fr=emu.readRegister(reg_from.value) imm=shuf.value to=(fr&0xffffffffffffffff0000000000000000) to+=(fr>> (imm&4)*16 )&0xffff to+=((fr>> ( (imm>>2) & 4)*16 )&0xffff)<<16 to+=((fr>> ( (imm>>4) & 4)*16 )&0xffff)<<32 to+=((fr>> ( (imm>>8) & 4)*16 )&0xffff)<<48 emu.writeRegister(reg_into.value,to) skip(emu) def pmovmskb(emu,instr): if instr is None: return if instr.getNumOperands()!=2: return reg_into=Operand(instr,0) reg_from=Operand(instr,1) if reg_into.type!="register" or reg_from.type!="register": raise 34 fr=emu.readRegister(reg_from.value) cnt=1 val=0 for bt in range(16): idir=int((fr&(1<<(8*cnt-1)))!=0) val |= (idir<4: co=0x28 esp=emu.readRegister("ESP") for a in range(num-4): pars.append(readULL(emu,getAddress(esp+co))) co+=8 for a in range (num): logger.info("Param_{}: {:x}".format(a+1,pars[a])) def writeRegister(emu,reg,fl): nm=reg.getName() ln=reg.getMinimumByteSize() if ln >8: ln=16 elif ln>4: ln=8 elif ln >2: ln=4 else: ln=2 fl.write(struct.pack(">64)&0xffffffffffffffff )) fl.write(struct.pack("0: mbuf=emu.readMemory(getAddress(start),ln) fl.write(mbuf) def writeSnapshot(emu,fl): global mem, rspStart, currentProgram excl=set(["contextreg"]) br=set([e.getBaseRegister() for e in getProgramRegisterList(currentProgram) if e.getBaseRegister().getName() not in excl]) rsp=emu.readRegister("RSP") fl.write(struct.pack("0: dat=fl.read(ln) if len(dat)0: self.countdown-=1 else: #print("Grabbing at {}".format(addr)) if isinstance(self.ptrReg,list): if len(self.ptrReg)==2: dataAddr=emu.readRegister(self.ptrReg[0])+self.ptrReg[1] else: indirAddr=emu.readRegister(self.ptrReg[0])+self.ptrReg[1] dataAddr=readULL(emu,getAddress(indirAddr)) elif isinstance(self.ptrReg,(int,long)): dataAddr=self.ptrReg else: dataAddr=emu.readRegister(self.ptrReg) val=0 for a in range(32): dlt=readULL(emu,getAddress(dataAddr+8*self.table[a])) val=val+dlt*(1<<(64*a)) self.countdown=self.cntd if self.name is None: logger.info("Grabbed at {}: {:x}".format(self.grabAddr,val)) else: logger.info("Grabbed {} at {}: {:x}".format(self.name,self.grabAddr,val)) class BCollector(object): def __init__(self,name,startAddr,collectAddr,collectA,collectB,endAddr,paraCol=False): self.name=name self.startAddr=getAddress(startAddr) self.endAddr=getAddress(endAddr) self.collectAddr=getAddress(collectAddr) self.isCollecting=False self.collectA=collectA self.a=0 self.collectB=collectB self.b=0 self.cnt=0 self.cntb=0 self.paracol=paraCol def emget(self,emu, coll): lc=len(coll) if lc ==1: if isinstance(coll[0],int): return readULL(emu,getAddress(coll[0])) else: return emu.readRegister(coll[0]) elif lc==2: #[reg+const] addr=emu.readRegister(coll[0])+coll[1] return readULL(emu,getAddress(addr)) elif lc==3: #[reg+reg*const] addr=emu.readRegister(coll[0])+emu.readRegister(coll[1])*coll[2] #logger.info("Cll: {:x} {:x} {:x}".format(emu.readRegister(coll[0]),emu.readRegister(coll[1]),addr)) return readULL(emu,getAddress(addr)) elif lc==4: #[reg+reg*const+c2] addr=emu.readRegister(coll[0])+emu.readRegister(coll[1])*coll[2]+coll[3] return readULL(emu,getAddress(addr)) elif lc==5: # ["RSP",40,"RAX",8,"indir"] addr=emu.readRegister(coll[0])+coll[1] addr2=readULL(emu,getAddress(addr))+emu.readRegister(coll[2])*coll[3] return readULL(emu,getAddress(addr2)) def collect(self,emu,addr): if addr==self.startAddr: self.a=0 self.b=0 self.cntb=0 self.cnt=0 self.isCollecting=True elif addr==self.endAddr: logger.info("Collected as {} ,a : {:x}".format(self.name,self.a)) logger.info("Collected as {} ,b : {:x}".format(self.name,self.b)) logger.info("Collection rounds as {} , {}".format(self.name,self.cnt)) self.a=0 self.b=0 self.cnt=0 self.isCollecting=False elif addr==self.collectAddr and self.isCollecting: da=self.emget(emu,self.collectA) if not self.paracol: db=self.emget(emu,self.collectB) ml=(1<<(64*self.cnt)) self.a+=ml*da if not self.paracol: self.b+=ml*db self.cnt+=1 elif self.isCollecting and self.paracol and self.cntb<32 and addr>self.startAddr and addr> 0x24) & 0x3fff ln2=cnst >> 0x32 flen=ln+ln2 cclen=flen if ln>0: logger.info("Constant of offset {:x} len {} len2 {}".format(offset,ln,ln2)) logger.info("Constant input 1: ") dumpBuffer(emu,inp1,flen) logger.info("Constant input 2: ") dumpBuffer(emu,inp2,flen) if executionAddress==getAddress(0x18016b147): if coutp is not None and cclen>0: logger.info("Constant output: ") dumpBuffer(emu,coutp,cclen) coutp=None cclen=0 if executionAddress==getAddress(0x1801722bb): esp=emu.readRegister("RSP")+0x50e20 logger.info("Austack "); dumpBuffer(emu,esp,0x5d0) if executionAddress==getAddress(0x180172624): esp=emu.readRegister("RSP")+0x4faf0 logger.info("Austack 2"); dumpBuffer(emu,esp,0x5d0) if executionAddress==getAddress(0x18017df74): logger.info("Much bollockry reached") dumpParameters(emu,5) saveSnapshot(emu,"bollockrySnap.gz") for prm in prms: prm.grab(emu,executionAddress) if executionAddress==getAddress(0x1801f539b): saveSnapshot(emu,"snap1801f539b_{}.gz".format(snc)) snc+=1 if executionAddress==getAddress(0x18016dbc1): print(emu.readRegister("ECX")) #print(CALLED) if executionAddress==getAddress(0x1800779a0): saveSnapshot(emu,"Walltimeindir1801f539b_{}.gz".format(snc)) snc+=1 logger.info("Walltimeindir saved") if executionAddress==getAddress(0x180072a58): saveSnapshot(emu,"Irrel180072a58_{}.gz".format(snc)) snc+=1 logger.info("Irrel entry saved") if executionAddress==getAddress(0x18016d24d): saveSnapshot(emu,"Hasmulret18016d24d_2_{}.gz".format(snc)) snc+=1 logger.info("Mulret entry saved") if executionAddress==getAddress(0x180057514): logger.info("Sussery reached") dumpParameters(emu,2) saveSnapshot(emu,"susserySnap.gz") #trace=True if executionAddress==getAddress(0x1801a3556): saveSnapshot(emu,"paramBuggery.gz") if executionAddress==getAddress(0x180291490): #RSA encrypt? rcx=emu.readRegister("RCX") nptr=readULL(emu,getAddress(rcx)) eptr=readULL(emu,getAddress(rcx+8)) dptr=readULL(emu,getAddress(rcx+16)) logger.info("At RSA encrypt: {:x} {:x} {:x}".format(nptr,eptr,dptr)) saveSnapshot(emu,"rsaSnap.gz") if executionAddress==getAddress(0x1801d6780): rax=emu.readRegister("ESI") rsp=emu.readRegister("RSP") logger.info("Should be esi: {:x} at {:x}+".format(rax,rsp+0xc8)) if executionAddress==getAddress(0x18017e3b0): saveSnapshot(emu,"Longstringproc_{}.gz".format(snc)) snc+=1 if executionAddress==getAddress(0x1801720e0): saveSnapshot(emu,"ManyMults1801720e0_{}.gz".format(snc)) snc+=1 if executionAddress==getAddress(0x1801722bb): dat=emu.readMemory(getAddress(emu.readRegister("RSP")+0x70),0x5a0) dst="" for a in dat: if a<0: a+=256 dst+="{:02X}".format(a) #print("{:x}".format(eadr)) logger.info("Buffer: {}".format(dst)) dat=emu.readMemory(getAddress(emu.readRegister("RSP")+0x50e20),0x5a0) dst="" for a in dat: if a<0: a+=256 dst+="{:02X}".format(a) logger.info("Buffer2: {}".format(dst)) if executionAddress==getAddress(0x1801a35d0): rsp=emu.readRegister("RSP")+0x33a0 logger.info("Bollocks3:") dumpBuffer(emu,rsp,0x5a*4) if executionAddress==getAddress(0x18017a771): superTrace=True if superTrace: ein=getInstructionAt(executionAddress) xmm0=emu.readRegister("XMM0") xmm1=emu.readRegister("XMM1") xmm2=emu.readRegister("XMM2") xmm3=emu.readRegister("XMM3") xmm4=emu.readRegister("XMM4") xmm5=emu.readRegister("XMM5") xmm6=emu.readRegister("XMM6") xmm7=emu.readRegister("XMM7") xmm8=emu.readRegister("XMM8") xmm9=emu.readRegister("XMM9") xmm10=emu.readRegister("XMM10") logger.info("###############") logger.info("Address: 0x{} ({})".format(executionAddress, ein)) logger.info("Xmm0 ={:x} Xmm1 ={:x} Xmm2 ={:x} Xmm3 ={:x} ".format(xmm0,xmm1,xmm2,xmm3)) logger.info("Xmm4 ={:x} Xmm5 ={:x} Xmm6 ={:x} Xmm7 ={:x} ".format(xmm4,xmm5,xmm6,xmm7)) logger.info("Xmm8 ={:x} Xmm9 ={:x} Xmm10={:x}".format(xmm8,xmm9,xmm10)) regs=["RAX","RBX","RCX","RDX","R8","R9","R10","R11","R12","R13","R14","R15","RBP","RSI","RDI"] rt="" for r in regs: val=emu.readRegister(r) rt=rt+"{}: {:x} ".format(r,val) logger.info("Registers: {}".format(rt)) if executionAddress==getAddress(0x18017e440): saveSnapshot(emu,"Longstring_nearsha_{}.gz".format(snc)) snc+=1 addr=emu.readRegister("R8") dat=emu.readMemory(getAddress(addr),0x1c8) dst="" for a in dat: if a<0: a+=256 dst+="{:02X}".format(a) logger.info("Buffer before: {}".format(dst)) if executionAddress==getAddress(0x18017e454): saveSnapshot(emu,"Longstring_postsha_{}.gz".format(snc)) snc+=1 addr=emu.readRegister("RBP") dat=emu.readMemory(getAddress(addr),0x1c8) dst="" for a in dat: if a<0: a+=256 dst+="{:02X}".format(a) logger.info("Buffer After: {}".format(dst)) if executionAddress==getAddress(0x18017e473): saveSnapshot(emu,"Longstring_postfun_{}.gz".format(snc)) snc+=1 addr=emu.readRegister("RDI") dat=emu.readMemory(getAddress(addr),0x200) dst="" for a in dat: if a<0: a+=256 dst+="{:02X}".format(a) logger.info("Buffer other: {}".format(dst)) #if executionAddress==getAddress(0x1802c8d56): # rax=emu.readRegister("RAX") # logger.info("Index: {:x}".format(rax)) #if executionAddress==getAddress(0x18017b4cb): # rcx=emu.readRegister("RCX") # dat=emu.readMemory(getAddress(rcx),256) # logger.info("First array: {}".format(dat)) if executionAddress==getAddress(0x1801d67e4): rsp=emu.readRegister("RSP") strng=readULL(emu,getAddress(rsp+0xc0)) dat=emu.readMemory(getAddress(strng),91) logger.info("Shouldreallybestring: {:x} dat :{}".format(strng,dat)) if executionAddress==getAddress(0x1802ca455): rax=emu.readRegister("RAX") ptr=readULL(emu,getAddress(rax)) sz=readULL(emu,getAddress(rax+8)) cap=readULL(emu,getAddress(rax+16)) logger.info("Shouldbestring: {:x} sz: {} cap : {:x}".format(ptr,sz,cap)) stdat=emu.readMemory(getAddress(ptr),90) logger.info("Shouldbestringdata: {}".format(stdat)) if executionAddress==getAddress(0x1802c8af8) or executionAddress==getAddress(0x1802cbf37): rcx=emu.readRegister("RCX") rdx=emu.readRegister("RDX") r8=emu.readRegister("R8") r9=emu.readRegister("R9") logger.info("Thishere: {} {} {} {}".format(rcx,rdx,r8,r9)) if executionAddress in dict: logger.info("Substituting {}".format(executionAddress)) dict[executionAddress](emu) else: ein=getInstructionAt(executionAddress) cnt+=1 snapcnt+=1 if cnt>100000: cnt=0 logger.info("Address: 0x{} ({})".format(executionAddress, ein)) logger.info("RAX: {:x} RCX: {:x} RBP: {:x}".format(emu.readRegister("RAX"),emu.readRegister("RCX"),emu.readRegister("RBP"))) if snapcnt>1000000: saveSnapshot(emu,"Periodic2_{}.gz".format(snc)) snc+=1 snapcnt=0 logger.info("Periodic snapshot {} saved".format(snc-1)) con=getCallOtherName(ein) if con is not None: if con == "pshuflw": pshuflw(emu,ein) elif con == "pmovmskb": pmovmskb(emu,ein) else: logger.info("Skipping: {}".format(ein)) skip(emu) continue if trace: logger.info("Address: 0x{} ({})".format(executionAddress, ein)) elog=False if elog: if isCallInstruction(ein): logger.info("CAddress: 0x{} ({})".format(executionAddress, ein)) logger.info("RAX: {:x} RCX: {:x} RBP: {:x}".format(emu.readRegister("RAX"),emu.readRegister("RCX"),emu.readRegister("RBP"))) logger.info("RDX: {:x} RDI: {:x} RBX: {:x}".format(emu.readRegister("RDX"),emu.readRegister("RDI"),emu.readRegister("RBX"))) logger.info("R8 : {:x} R9 : {:x} R15: {:x}".format(emu.readRegister("R8"),emu.readRegister("R9"),emu.readRegister("R15"))) if isReturn(ein): logger.info("Returning: 0x{} {:x}".format(executionAddress, emu.readRegister("RAX"))) sn4file=os.path.join(basedir,"Longstringproc_620.gz") #from 250...586 Periodic2_1230.gz Hasmulret18016d24d_602.gz ManyMults1801720e0_1206.gz if os.path.isfile(sn4file): snc=1359 #trace=True runModule(initCdm,sn4file) else: runModule(initCdm) createCdmInstance=getAddress(0x1800010a0) emu.writeRegister("RCX",10) keys = "com.widevine.alpha"#"com.widevine.alpha" keyptr=get_cptr(emu,keys) emu.writeRegister("RDX",keyptr) emu.writeRegister("R8",len(keys)) emu.writeRegister("R9",0xf0000) EmuPush(emu,0) logger.info("Running CreateInstance") runModule(createCdmInstance) saveSnapshot(emu,"snapshot1.gz") cdmInst=emu.readRegister("RAX") logger.info("Instance: {:x}".format(cdmInst)) #vtable[0]=Initialize(true, false, false); #cdmVtableP=readULL(emu,getAddress(cdmInst)) cdmVtable=readULL(emu,getAddress(cdmInst)) logger.info("Vtable: {:x}".format(cdmVtable)) cdmInitialize=readULL(emu,getAddress(cdmVtable)) logger.info("cdmInitialize: {:x}".format(cdmInitialize)) emu.writeRegister("RCX",cdmInst) logger.info("Running Initialize") #trace=True emu.writeRegister("RDX",1) emu.writeRegister("R8",0) emu.writeRegister("R9",0) runModule(getAddress(cdmInitialize)) saveSnapshot(emu,"snapshot2.gz") #ContentDecryptionModule_10* cdm =(ContentDecryptionModule_10 *) create(10, keys.c_str(), keys.length(), #GetDummyHost, (void*) msg); #logger.info("First compare: {}".format(readULL(emu,getAddress(cdmInst+0x92)))) creses=readULL(emu,getAddress(cdmVtable+3*8))#CreateSessionAndGenerateRequest logger.info("CreateSessionAndGenerateRequest: {:x}".format(creses)) logger.info("Running CreateSession") emu.writeRegister("RCX",cdmInst) emu.writeRegister("RDX",11) emu.writeRegister("R8",0) emu.writeRegister("R9",0) idata= [0, 0, 0, 91, 112, 115, 115, 104, 0, 0, 0, 0, 237, 239, 139, 169, 121, 214, 74,206, 163, 200, 39, 220, 213, 29, 33, 237, 0, 0, 0, 59, 8, 1, 18, 16, 235, 103, 106, 187, 203, 52, 94, 150, 187, 207, 97, 102, 48, 241, 163, 218, 26, 13, 119, 105, 100, 101, 118, 105, 110, 101, 95, 116, 101, 115, 116, 34, 16, 102, 107,106, 51, 108, 106, 97, 83, 100, 102, 97, 108, 107, 114, 51, 106, 42, 2, 72, 68,50, 0] initdata=listToMem(emu,idata) EmuPush4(emu, 0) EmuPush4(emu, 91) rsp=emu.readRegister("RSP") logger.info("Pushed len to {:x}".format(rsp)) EmuPush(emu, initdata) rsp=emu.readRegister("RSP") logger.info("Pushed data to {:x}".format(rsp)) EmuPush(emu, 0) EmuPush(emu, 0) EmuPush(emu, 0) EmuPush(emu, 0) runModule(getAddress(creses))