diff --git a/guider/guider.py b/guider/guider.py index 1c055f85..931b0daa 100755 --- a/guider/guider.py +++ b/guider/guider.py @@ -7,7 +7,7 @@ __credits__ = "Peace Lee" __license__ = "GPLv2" __version__ = "3.9.8" -__revision__ = "240603" +__revision__ = "240604" __maintainer__ = "Peace Lee" __email__ = "iipeace5@gmail.com" __repository__ = "https://github.com/iipeace/guider" @@ -5934,57 +5934,76 @@ class ConfigMgr(object): IOCTL_TYPE_REVERSE = {} # ptrace request type # - PTRACE_TYPE = [ - "PTRACE_TRACEME", # 0 - "PTRACE_PEEKTEXT", - "PTRACE_PEEKDATA", - "PTRACE_PEEKUSR", - "PTRACE_POKETEXT", - "PTRACE_POKEDATA", - "PTRACE_POKEUSR", - "PTRACE_CONT", - "PTRACE_KILL", - "PTRACE_SINGLESTEP", # 9 - "", - "", - "PTRACE_GETREGS", # 12 - "PTRACE_SETREGS", # 13 - "PTRACE_GETFPREGS", # 14 - "PTRACE_SETFPREGS", # 15 - "PTRACE_ATTACH", # 16 - "PTRACE_DETACH", # 17 - "PTRACE_GETFPXREGS", # 18 - "PTRACE_SETFPXREGS", # 19 - "", - "", - "", - "PTRACE_SET_SYSCALL", # 23 - "PTRACE_SYSCALL", # 24 - "", - "", - "", - "", - "", - "", - "PTRACE_SYSEMU", # 31 - "PTRACE_SYSEMU_SINGLESTEP", # 32 - ] + PTRACE_TYPE = { + 0: "PTRACE_TRACEME", + 1: "PTRACE_PEEKTEXT", + 2: "PTRACE_PEEKDATA", + 3: "PTRACE_PEEKUSR", + 4: "PTRACE_POKETEXT", + 5: "PTRACE_POKEDATA", + 6: "PTRACE_POKEUSR", + 7: "PTRACE_CONT", + 8: "PTRACE_KILL", + 9: "PTRACE_SINGLESTEP", + 12: "PTRACE_GETREGS", + 13: "PTRACE_SETREGS", + 14: "PTRACE_GETFPREGS", + 15: "PTRACE_SETFPREGS", + 16: "PTRACE_ATTACH", + 17: "PTRACE_DETACH", + 18: "PTRACE_GETFPXREGS", + 19: "PTRACE_SETFPXREGS", + 23: "PTRACE_SET_SYSCALL", + 24: "PTRACE_SYSCALL", + 31: "PTRACE_SYSEMU", + 32: "PTRACE_SYSEMU_SINGLESTEP", + 0x4200: "PTRACE_SETOPTIONS", + 0x4201: "PTRACE_GETEVENTMSG", + 0x4202: "PTRACE_GETSIGINFO", + 0x4203: "PTRACE_SETSIGINFO", + 0x4204: "PTRACE_GETREGSET", + 0x4205: "PTRACE_SETREGSET", + 0x4206: "PTRACE_SEIZE", + 0x4207: "PTRACE_INTERRUPT", + 0x4208: "PTRACE_LISTEN", + 0x4209: "PTRACE_PEEKSIGINFO", + 0x420A: "PTRACE_GETSIGMASK", + 0x420B: "PTRACE_SETSIGMASK", + 0x420C: "PTRACE_SECCOMP_GET_FILTER", + 0x420D: "PTRACE_SECCOMP_GET_METADATA", + 0x420E: "PTRACE_GET_SYSCALL_INFO", + 0x4210: "PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG", + 0x4211: "PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG", + } + PTRACE_TYPE_LIST = {v: k for k, v in PTRACE_TYPE.items()} # ptrace event types # - PTRACE_EVENT_TYPE = ( - [ - "PTRACE_EVENT_NONE", - "PTRACE_EVENT_FORK", - "PTRACE_EVENT_VFORK", - "PTRACE_EVENT_CLONE", - "PTRACE_EVENT_EXEC", - "PTRACE_EVENT_VFORK_DONE", - "PTRACE_EVENT_EXIT", - "PTRACE_EVENT_SECCOMP", - ] - + ["NONE" for idx in xrange(120)] - + ["PTRACE_EVENT_STOP"] - ) + PTRACE_EVENT_TYPE = { + "PTRACE_EVENT_FORK": 1, + "PTRACE_EVENT_VFORK": 2, + "PTRACE_EVENT_CLONE": 3, + "PTRACE_EVENT_EXEC": 4, + "PTRACE_EVENT_VFORK_DONE": 5, + "PTRACE_EVENT_EXIT": 6, + "PTRACE_EVENT_SECCOMP": 7, + "PTRACE_EVENT_STOP": 128, + } + + # ptrace o types # + PTRACE_O_TYPE = { + "PTRACE_O_TRACESYSGOOD": 1, + "PTRACE_O_TRACEFORK": 1 << PTRACE_EVENT_TYPE["PTRACE_EVENT_FORK"], + "PTRACE_O_TRACEVFORK": 1 << PTRACE_EVENT_TYPE["PTRACE_EVENT_VFORK"], + "PTRACE_O_TRACECLONE": 1 << PTRACE_EVENT_TYPE["PTRACE_EVENT_CLONE"], + "PTRACE_O_TRACEEXEC": 1 << PTRACE_EVENT_TYPE["PTRACE_EVENT_EXEC"], + "PTRACE_O_TRACEVFORKDONE": 1 + << PTRACE_EVENT_TYPE["PTRACE_EVENT_VFORK_DONE"], + "PTRACE_O_TRACEEXIT": 1 << PTRACE_EVENT_TYPE["PTRACE_EVENT_EXIT"], + "PTRACE_O_TRACESECCOMP": 1 + << PTRACE_EVENT_TYPE["PTRACE_EVENT_SECCOMP"], + "PTRACE_O_EXITKILL": 1 << 20, + "PTRACE_O_SUSPEND_SECCOMP": 1 << 21, + } # perf event types # PERF_EVENT_TYPE = [ @@ -41309,6 +41328,9 @@ def _getDesc(s, t=0): - {2:1} without file-mapped pages # {0:1} {1:1} "a.out, java" -a -q SKIPFILE + - {2:1} with checking if the chunk is composed of a single character + # {0:1} {1:1} "a.out, java" -a -q CHECKSINGLECHAR + - {2:1} and print process summary list finally # {0:1} {1:1} "a.out, java" -q SKIPDUP, PRINTLIST @@ -60721,6 +60743,7 @@ def doCheckDup(): convNum = UtilMgr.convNum convColor = UtilMgr.convColor perProcInfo = SysMgr.environList.get("PERPROCINFO") + checkSingleChar = "CHECKSINGLECHAR" in SysMgr.environList memFilter = SysMgr.environList.get("MEMFILTER") if memFilter: memFilter = list(map(str.encode, memFilter)) @@ -60844,7 +60867,7 @@ def _printMemHist(mtable): origLen = len(key) # check zero chunk # - if len(set(key)) == 1: + if checkSingleChar and len(set(key)) == 1: key = "(%s * %s)" % ( key[0], convNum(len(key)), @@ -61220,7 +61243,7 @@ def _isValidPage(pagemap, idx): memTable = {} # check zero chunk # - if len(set(mem)) == 1: + if checkSingleChar and len(set(mem)) == 1: mem = "(%s * %s)" % (mem[0], convNum(len(mem))) mem = repr(mem).replace("\\x", "").strip("b'") SysMgr.printPipe((" " * 43) + mem, colorCtl=False) @@ -61873,7 +61896,7 @@ def _isValidPage(pagemap, idx): origLen = len(chunk) # check zero chunk # - if len(set(chunk)) == 1: + if checkSingleChar and len(set(chunk)) == 1: chunk = "(%s * %s)" % (chunk[0], convNum(len(chunk))) # convert to string # @@ -84768,21 +84791,30 @@ def __init__(self, pid=None, execCmd=None, attach=True, mode=None): ) # set ptrace indexes # - plist = ConfigMgr.PTRACE_TYPE - self.attachCmd = plist.index("PTRACE_ATTACH") - self.peekCmd = plist.index("PTRACE_PEEKTEXT") - self.pokeCmd = plist.index("PTRACE_POKEDATA") - self.contCmd = plist.index("PTRACE_CONT") - self.getregsCmd = plist.index("PTRACE_GETREGS") - self.getfpregsCmd = plist.index("PTRACE_GETFPREGS") - self.setregsCmd = plist.index("PTRACE_SETREGS") - self.syscallCmd = plist.index("PTRACE_SYSCALL") - self.sysemuCmd = plist.index("PTRACE_SYSEMU") - self.singlestepCmd = plist.index("PTRACE_SINGLESTEP") - self.seizeCmd = 0x4206 - self.interruptCmd = 0x4207 - self.listenCmd = 0x4208 + plist = ConfigMgr.PTRACE_TYPE_LIST + self.attachCmd = plist["PTRACE_ATTACH"] + self.contCmd = plist["PTRACE_CONT"] + self.detachCmd = plist["PTRACE_DETACH"] + self.geteventmsgCmd = plist["PTRACE_GETEVENTMSG"] + self.getfpregsCmd = plist["PTRACE_GETFPREGS"] + self.getregsCmd = plist["PTRACE_GETREGS"] + self.interruptCmd = plist["PTRACE_INTERRUPT"] + self.killCmd = plist["PTRACE_KILL"] + self.listenCmd = plist["PTRACE_LISTEN"] + self.peekCmd = plist["PTRACE_PEEKTEXT"] + self.pokeCmd = plist["PTRACE_POKEDATA"] + self.seizeCmd = plist["PTRACE_SEIZE"] + self.setoptionsCmd = plist["PTRACE_SETOPTIONS"] + self.setregsCmd = plist["PTRACE_SETREGS"] + self.getregsetCmd = plist["PTRACE_GETREGSET"] + self.setregsetCmd = plist["PTRACE_SETREGSET"] + self.getsiginfoCmd = plist["PTRACE_GETSIGINFO"] + self.setsiginfoCmd = plist["PTRACE_SETSIGINFO"] + self.singlestepCmd = plist["PTRACE_SINGLESTEP"] self.stopCmd = None + self.syscallCmd = plist["PTRACE_SYSCALL"] + self.sysemuCmd = plist["PTRACE_SYSEMU"] + self.tracemeCmd = plist["PTRACE_TRACEME"] # enable SEIZE and INTERRUPT commands # if False: @@ -84791,21 +84823,11 @@ def __init__(self, pid=None, execCmd=None, attach=True, mode=None): # set ptrace event indexes # pelist = ConfigMgr.PTRACE_EVENT_TYPE - self.sigExecFlag = ( - signal.SIGTRAP | pelist.index("PTRACE_EVENT_EXEC") << 8 - ) - self.sigCloneFlag = ( - signal.SIGTRAP | pelist.index("PTRACE_EVENT_CLONE") << 8 - ) - self.sigForkFlag = ( - signal.SIGTRAP | pelist.index("PTRACE_EVENT_FORK") << 8 - ) - self.sigVforkFlag = ( - signal.SIGTRAP | pelist.index("PTRACE_EVENT_VFORK") << 8 - ) - self.sigExitFlag = ( - signal.SIGTRAP | pelist.index("PTRACE_EVENT_EXIT") << 8 - ) + self.sigExecFlag = signal.SIGTRAP | pelist["PTRACE_EVENT_EXEC"] << 8 + self.sigCloneFlag = signal.SIGTRAP | pelist["PTRACE_EVENT_CLONE"] << 8 + self.sigForkFlag = signal.SIGTRAP | pelist["PTRACE_EVENT_FORK"] << 8 + self.sigVforkFlag = signal.SIGTRAP | pelist["PTRACE_EVENT_VFORK"] << 8 + self.sigExitFlag = signal.SIGTRAP | pelist["PTRACE_EVENT_EXIT"] << 8 # set task indexes # clist = ConfigMgr.PROCSTAT_ATTR @@ -84851,12 +84873,13 @@ def __init__(self, pid=None, execCmd=None, attach=True, mode=None): raise Exception("no ptrace perm") # trace flags # + # TODO: add more events and handle them # self.traceEventList = [ - "PTRACE_O_TRACEEXEC", "PTRACE_O_TRACESYSGOOD", - "PTRACE_O_TRACECLONE", "PTRACE_O_TRACEFORK", "PTRACE_O_TRACEVFORK", + "PTRACE_O_TRACECLONE", + "PTRACE_O_TRACEEXEC", "PTRACE_O_TRACEEXIT", ] @@ -87574,8 +87597,7 @@ def _getFunc(): def setTraceme(self): # WARN: This requires CAP_SYS_PTRACE with PTRACE_TRACEME # - cmd = ConfigMgr.PTRACE_TYPE.index("PTRACE_TRACEME") - ret = self.ptrace(cmd) + ret = self.ptrace(self.tracemeCmd) if ret != 0: if not self.comm: self.comm = SysMgr.getComm(self.pid, cache=True, save=True) @@ -89581,8 +89603,7 @@ def mprotect(self, maddr, size=0, perm="rwx"): return ret def kill(self): - cmd = ConfigMgr.PTRACE_TYPE.index("PTRACE_KILL") - ret = self.ptrace(cmd) + ret = self.ptrace(self.killCmd) if ret != 0: SysMgr.printWarn( "failed to kill %s(%s) because %s" @@ -89662,10 +89683,9 @@ def doDetach(self, pid, check=False): pid = self.pid self.attached = False - cmd = ConfigMgr.PTRACE_TYPE.index("PTRACE_DETACH") while 1: - ret = self.ptrace(cmd, pid=pid) + ret = self.ptrace(self.detachCmd, pid=pid) if ret != 0: SysMgr.printWarn( "failed to detach %s(%s) from guider(%s) because %s" @@ -99849,13 +99869,11 @@ def _updateTargets(taskList): pass def getSigInfo(self): - PTRACE_GETSIGINFO = 0x4202 - ret = self.ptrace(PTRACE_GETSIGINFO, data=addressof(self.sigObj)) + ret = self.ptrace(self.getsiginfoCmd, data=addressof(self.sigObj)) return ret def setSigInfo(self): - PTRACE_SETSIGINFO = 0x4203 - ret = self.ptrace(PTRACE_SETSIGINFO, data=addressof(self.sigObj)) + ret = self.ptrace(self.setsiginfoCmd, data=addressof(self.sigObj)) return ret def checkCloned(self, status): @@ -99879,11 +99897,10 @@ def isCloned(self, status): return status >> 8 == self.sigCloneFlag def getEventMsg(self): - PTRACE_GETEVENTMSG = 0x4201 data = c_long(0) addr = addressof(data) - self.ptrace(PTRACE_GETEVENTMSG, data=addr) + self.ptrace(self.geteventmsgCmd, data=addr) return data.value @@ -99951,7 +99968,9 @@ def setRegs(self, temp=False, newObj=None): addr = addressof(self.iovecObj) # PTRACE_SETREGSET # - ret = self.ptrace(0x4205, ConfigMgr.NT_TYPE["NT_PRSTATUS"], addr) + ret = self.ptrace( + self.setregsetCmd, ConfigMgr.NT_TYPE["NT_PRSTATUS"], addr + ) if ret != 0: raise Exception("setregset failure") except SystemExit: @@ -100020,7 +100039,9 @@ def getFpRegs(self, temp=False, new=False): addr = addressof(self.iovecFpObj) # PTRACE_GETREGSET # - ret = self.ptrace(0x4204, ConfigMgr.NT_TYPE["NT_PRFPREG"], addr) + ret = self.ptrace( + self.getregsetCmd, ConfigMgr.NT_TYPE["NT_PRFPREG"], addr + ) if ret != 0: raise Exception("getregset failure") except SystemExit: @@ -100078,7 +100099,9 @@ def getRegs(self, temp=False, new=False): addr = addressof(self.iovecObj) # PTRACE_GETREGSET # - ret = self.ptrace(0x4204, ConfigMgr.NT_TYPE["NT_PRSTATUS"], addr) + ret = self.ptrace( + self.getregsetCmd, ConfigMgr.NT_TYPE["NT_PRSTATUS"], addr + ) if ret != 0: raise Exception("getregset failure") except SystemExit: @@ -100305,34 +100328,29 @@ def dumpMemory(self, meminfo, output, verb=True): return total def ptraceEvent(self, reqList): - # define architect-independent constant # - PTRACE_SETOPTIONS = 0x4200 - option = 0 - plist = ConfigMgr.PTRACE_EVENT_TYPE + polist = ConfigMgr.PTRACE_O_TYPE for req in reqList: - if req == "PTRACE_O_TRACESYSGOOD": - option |= 1 - elif req == "PTRACE_O_TRACEEXEC": - option |= 1 << plist.index("PTRACE_EVENT_EXEC") - elif req == "PTRACE_O_TRACEEXIT": - option |= 1 << plist.index("PTRACE_EVENT_EXIT") - elif req == "PTRACE_O_TRACESECCOMP": - option |= 1 << plist.index("PTRACE_EVENT_SECCOMP") + if req in ( + "PTRACE_O_TRACESYSGOOD", + "PTRACE_O_TRACEEXEC", + "PTRACE_O_TRACEEXIT", + "PTRACE_O_TRACESECCOMP", + ): + option |= polist[req] elif Debugger.dbusEnable: - pass + continue elif SysMgr.cloneEnable or self.isBreakMode: - if req == "PTRACE_O_TRACEFORK": - option |= 1 << plist.index("PTRACE_EVENT_FORK") - elif req == "PTRACE_O_TRACEVFORK": - option |= 1 << plist.index("PTRACE_EVENT_VFORK") - elif req == "PTRACE_O_TRACECLONE": - option |= 1 << plist.index("PTRACE_EVENT_CLONE") - elif req == "PTRACE_O_TRACEVFORKDONE": - option |= 1 << plist.index("PTRACE_EVENT_VFORK_DONE") - - return self.ptrace(PTRACE_SETOPTIONS, 0, option) + if req in ( + "PTRACE_O_TRACEFORK", + "PTRACE_O_TRACEVFORK", + "PTRACE_O_TRACECLONE", + "PTRACE_O_TRACEVFORKDONE", + ): + option |= polist[req] + + return self.ptrace(self.setoptionsCmd, 0, option) def waitpid(self, pid=None): """