functions/kernel32.py (516 lines of code) (raw):

#coding: utf-8 import ida_dbg import idc import idaapi import funcutils GENERIC_ALL = 0x10000000 GENERIC_EXECUTE = 0x20000000 GENERIC_WRITE = 0x40000000 GENERIC_READ = 0x80000000 FILE_SHARE_READ = 0x00000001 FILE_SHARE_WRITE = 0x00000002 FILE_SHARE_DELETE = 0x00000004 CREATE_NEW = 1 CREATE_ALWAYS = 2 OPEN_EXISTING = 3 OPEN_ALWAYS = 4 TRUNCATE_EXISTING = 5 FILE_ATTRIBUTE_READONLY = 0x00000001 FILE_ATTRIBUTE_HIDDEN = 0x00000002 FILE_ATTRIBUTE_SYSTEM = 0x00000004 FILE_ATTRIBUTE_ARCHIVE = 0x0000020 FILE_ATTRIBUTE_NORMAL = 0x00000080 FILE_ATTRIBUTE_TEMPORARY = 0x00000100 FILE_ATTRIBUTE_OFFLINE = 0x00001000 FILE_ATTRIBUTE_ENCRYPTED = 0x00004000 class Kernel32: def __init__(self): self.is_64bit = True if idaapi.BADADDR == 0xffffffffffffffff else False self.total_func = { # file "CreateFileA" : self.CreateFileA, "CreateFileW" : self.CreateFileW, "ReadFile" : self.ReadFile, "WriteFile" : self.WriteFile, # thread & process "CreateThread" : self.CreateThread, "CreateProcessA": self.CreateProcessA, "CreateProcessW": self.CreateProcessW, # memory "VirtualAlloc":self.VirtualAlloc, "VirtualFree":self.VirtualFree, "VirtualProtect":self.VirtualProtect, # debug "IsDebuggerPresent":self.IsDebuggerPresent } def get_result(self): if self.is_64bit: res = idc.get_reg_value("RAX") else: res = idc.get_reg_value("EAX") return res def get_func_args(self, nth): ida_dbg.refresh_debugger_memory() if self.is_64bit: four_args = ["RCX", "RDX", "R8", "R9"] if nth == 0: rsp = idc.get_reg_value("RSP") result = idc.get_qword(rsp) elif nth < 5: result = idc.get_reg_value(four_args[nth - 1]) else: rsp = idc.get_reg_value("RSP") result = idc.get_qword(rsp + nth * 8) else: esp = idc.get_reg_value("ESP") result = idc.get_wide_dword(esp + nth * 4) return result def CreateFileA(self, is_return = False): if is_return == True: return f"{hex(funcutils.get_result(self.is_64bit))} -> HANDLE" lpFileNameAddr = funcutils.get_func_args(1, self.is_64bit) _debug_info = f"lpFileName=" + idc.get_strlit_contents(lpFileNameAddr).decode('utf-8') access = funcutils.get_func_args(2, self.is_64bit) & 0xffffffff access_result = str() if access == GENERIC_ALL: access_result = "GENERIC_ALL" else: if access & GENERIC_READ: access_result += "GENERIC_READ|" if access & GENERIC_WRITE: access_result += "GENERIC_WRITE|" if access & GENERIC_EXECUTE: access_result += "GENERIC_EXECUTE|" if access_result.endswith('|'): access_result = access_result[:-1] _debug_info += f", dwDesiredAccess={access_result}" shared_mode = funcutils.get_func_args(3, self.is_64bit) & 0xffffffff shared_mode_result = str() if shared_mode == 0: shared_mode_result = "0" else: if shared_mode & FILE_SHARE_READ: shared_mode_result += "FILE_SHARE_READ|" if shared_mode & FILE_SHARE_WRITE: shared_mode_result += "FILE_SHARE_WRITE|" if shared_mode & FILE_SHARE_DELETE: shared_mode_result += "FILE_SHARE_DELETE|" if shared_mode_result.endswith("|"): shared_mode_result = shared_mode_result[:-1] _debug_info += f", dwShareMode={shared_mode_result}" lpSecurityAttributes = funcutils.get_func_args(4, self.is_64bit) _debug_info += f", lpSecurityAttributes={hex(lpSecurityAttributes)}" dwCreationDisposition = funcutils.get_func_args(5, self.is_64bit) & 0xffffffff creation_result = str() if dwCreationDisposition == CREATE_NEW: creation_result = "CREATE_NEW" elif dwCreationDisposition == CREATE_ALWAYS: creation_result = "CREATE_ALWAYS" elif dwCreationDisposition == OPEN_EXISTING: creation_result = "OPEN_EXISTING" elif dwCreationDisposition == OPEN_ALWAYS: creation_result = "OPEN_ALWAYS" elif dwCreationDisposition == TRUNCATE_EXISTING: creation_result = "TRUNCATE_EXISTING" _debug_info += f", dwCreationDisposition={creation_result}" dwFlagsAndAttributes = funcutils.get_func_args(6, self.is_64bit) & 0xffffffff attr_result = str() if dwFlagsAndAttributes & FILE_ATTRIBUTE_READONLY: attr_result += "FILE_ATTRIBUTE_READONLY|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_HIDDEN: attr_result += "FILE_ATTRIBUTE_HIDDEN|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_SYSTEM: attr_result += "FILE_ATTRIBUTE_SYSTEM|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_ARCHIVE: attr_result += "FILE_ATTRIBUTE_ARCHIVE|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_NORMAL: attr_result += "FILE_ATTRIBUTE_NORMAL|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_TEMPORARY: attr_result += "FILE_ATTRIBUTE_TEMPORARY|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_OFFLINE: attr_result += "FILE_ATTRIBUTE_OFFLINE|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_ENCRYPTED: attr_result += "FILE_ATTRIBUTE_ENCRYPTED|" if attr_result.endswith('|'): attr_result = attr_result[:-1] _debug_info += f", dwFlagsAndAttributes={attr_result}" hTemplateFile = funcutils.get_func_args(7, self.is_64bit) _debug_info += f", hTemplateFile={hex(hTemplateFile)}) = " return _debug_info def CreateFileW(self, is_return = False): if is_return == True: return f"{hex(funcutils.get_result(self.is_64bit))} => HANDLE" lpFileNameAddr = funcutils.get_func_args(1, self.is_64bit) _debug_info = f"lpFileName=" + idc.get_strlit_contents(ea = lpFileNameAddr, strtype=idc.STRTYPE_C16).decode("utf-8") access = funcutils.get_func_args(2, self.is_64bit) & 0xffffffff access_result = str() if access == GENERIC_ALL: access_result = "GENERIC_ALL" else: if access & GENERIC_READ: access_result += "GENERIC_READ|" if access & GENERIC_WRITE: access_result += "GENERIC_WRITE|" if access & GENERIC_EXECUTE: access_result += "GENERIC_EXECUTE|" if access_result.endswith('|'): access_result = access_result[:-1] _debug_info += f", dwDesiredAccess={access_result}" shared_mode = funcutils.get_func_args(3, self.is_64bit) & 0xffffffff shared_mode_result = str() if shared_mode == 0: shared_mode_result = "0" else: if shared_mode & FILE_SHARE_READ: shared_mode_result += "FILE_SHARE_READ|" if shared_mode & FILE_SHARE_WRITE: shared_mode_result += "FILE_SHARE_WRITE|" if shared_mode & FILE_SHARE_DELETE: shared_mode_result += "FILE_SHARE_DELETE|" if shared_mode_result.endswith("|"): shared_mode_result = shared_mode_result[:-1] _debug_info += f", dwShareMode={shared_mode_result}" lpSecurityAttributes = funcutils.get_func_args(4, self.is_64bit) _debug_info += f", lpSecurityAttributes={hex(lpSecurityAttributes)}" dwCreationDisposition = funcutils.get_func_args(5, self.is_64bit) & 0xffffffff creation_result = str() if dwCreationDisposition == CREATE_NEW: creation_result = "CREATE_NEW" elif dwCreationDisposition == CREATE_ALWAYS: creation_result = "CREATE_ALWAYS" elif dwCreationDisposition == OPEN_EXISTING: creation_result = "OPEN_EXISTING" elif dwCreationDisposition == OPEN_ALWAYS: creation_result = "OPEN_ALWAYS" elif dwCreationDisposition == TRUNCATE_EXISTING: creation_result = "TRUNCATE_EXISTING" _debug_info += f", dwCreationDisposition={creation_result}" dwFlagsAndAttributes = funcutils.get_func_args(6, self.is_64bit) & 0xffffffff attr_result = str() if dwFlagsAndAttributes & FILE_ATTRIBUTE_READONLY: attr_result += "FILE_ATTRIBUTE_READONLY|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_HIDDEN: attr_result += "FILE_ATTRIBUTE_HIDDEN|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_SYSTEM: attr_result += "FILE_ATTRIBUTE_SYSTEM|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_ARCHIVE: attr_result += "FILE_ATTRIBUTE_ARCHIVE|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_NORMAL: attr_result += "FILE_ATTRIBUTE_NORMAL|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_TEMPORARY: attr_result += "FILE_ATTRIBUTE_TEMPORARY|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_OFFLINE: attr_result += "FILE_ATTRIBUTE_OFFLINE|" if dwFlagsAndAttributes & FILE_ATTRIBUTE_ENCRYPTED: attr_result += "FILE_ATTRIBUTE_ENCRYPTED|" if attr_result.endswith('|'): attr_result = attr_result[:-1] _debug_info += f", dwFlagsAndAttributes={attr_result}" hTemplateFile = funcutils.get_func_args(7, self.is_64bit) _debug_info += f", hTemplateFile={hex(hTemplateFile)}) = " return _debug_info def ReadFile(self, is_return = False): if is_return: return f"{hex(funcutils.get_result(self.is_64bit))} -> BOOL" hFile = funcutils.get_func_args(1, self.is_64bit) lpBuffer = funcutils.get_func_args(2, self.is_64bit) nNumberOfBytesToRead = funcutils.get_func_args(3, self.is_64bit) lpNumberOfBytesRead = funcutils.get_func_args(4, self.is_64bit) lpOverlapped = funcutils.get_func_args(5, self.is_64bit) _debug_info = f"hFile={hex(hFile)}, " _debug_info += f"lpBuffer={hex(lpBuffer)}, " _debug_info += f"nNumberOfBytesToRead={nNumberOfBytesToRead}, " _debug_info += f"lpNumberOfBytesRead={hex(lpNumberOfBytesRead)}, " _debug_info += f"lpOverlapped={hex(lpOverlapped)}) = " return _debug_info def WriteFile(self, is_return = False): if is_return: return f"{hex(funcutils.get_result(self.is_64bit))} -> BOOL" hFile = funcutils.get_func_args(1, self.is_64bit) lpBuffer = funcutils.get_func_args(2, self.is_64bit) nNumberOfBytesToWrite = funcutils.get_func_args(3, self.is_64bit) lpNumberOfBytesWritten = funcutils.get_func_args(4, self.is_64bit) lpOverlapped = funcutils.get_func_args(5, self.is_64bit) buffer_preview = "" if lpBuffer != 0: buffer_bytes = idc.get_bytes(lpBuffer, min(5, nNumberOfBytesToWrite)) if buffer_bytes: buffer_preview = " ".join(f"{b:02X}" for b in buffer_bytes) if nNumberOfBytesToWrite > 5: buffer_preview += " ..." _debug_info = f"hFile={hex(hFile)}, " _debug_info += f"lpBuffer={hex(lpBuffer)}, Buffer Preview: [{buffer_preview}], " _debug_info += f"nNumberOfBytesToWrite={nNumberOfBytesToWrite}, " _debug_info += f"lpNumberOfBytesWritten={hex(lpNumberOfBytesWritten)}, " _debug_info += f"lpOverlapped={hex(lpOverlapped)}) = " return _debug_info def CloseHandle(self, is_return=False): if is_return: return f"{hex(funcutils.get_result(self.is_64bit))} -> BOOL" hObject = self.get_func_args(1) _debug_info = f"hObject={hex(hObject)}) = " return _debug_info def CreateThread(self, is_return = False): if is_return: lpThreadId = funcutils.get_func_args(5, self.is_64bit) if lpThreadId != 0: thread_id = idc.get_wide_dword(lpThreadId) return f"{hex(funcutils.get_result(self.is_64bit))} -> HANDLE, tid = {hex(thread_id)}" return f"{hex(funcutils.get_result(self.is_64bit))} -> HANDLE" lpThreadAttributes = funcutils.get_func_args(1, self.is_64bit) dwStackSize = funcutils.get_func_args(2, self.is_64bit) lpStartAddress = funcutils.get_func_args(3, self.is_64bit) lpParameter = funcutils.get_func_args(4, self.is_64bit) dwCreationFlags = funcutils.get_func_args(5, self.is_64bit) lpThreadId = funcutils.get_func_args(6, self.is_64bit) creation_flags_descr = [] if dwCreationFlags & 0x00000004: # CREATE_SUSPENDED creation_flags_descr.append("CREATE_SUSPENDED") if dwCreationFlags & 0x00010000: # STACK_SIZE_PARAM_IS_A_RESERVATION creation_flags_descr.append("STACK_SIZE_PARAM_IS_A_RESERVATION") if creation_flags_descr: creation_flags_descr = '|'.join(creation_flags_descr) else: creation_flags_descr = '0' _debug_info = f"lpThreadAttributes={hex(lpThreadAttributes)}, " _debug_info += f"dwStackSize={dwStackSize}, " _debug_info += f"lpStartAddress={hex(lpStartAddress)}, " _debug_info += f"lpParameter={hex(lpParameter)}, " _debug_info += f"dwCreationFlags={creation_flags_descr}, " _debug_info += f"lpThreadId={hex(lpThreadId)}) = " return _debug_info def CreateRemoteThread(self, is_return=False): if is_return: lpThreadIdAddr = funcutils.get_func_args(6, self.is_64bit) if lpThreadIdAddr != 0: thread_id = idc.get_wide_dword(lpThreadIdAddr) return f"{hex(funcutils.get_result(self.is_64bit))} -> HANDLE, tid = {hex(thread_id)}" return f"{hex(funcutils.get_result(self.is_64bit))} -> HANDLE" # 获取参数 hProcess = funcutils.get_func_args(1, self.is_64bit) lpThreadAttributes = funcutils.get_func_args(2, self.is_64bit) dwStackSize = funcutils.get_func_args(3, self.is_64bit) lpStartAddress = funcutils.get_func_args(4, self.is_64bit) lpParameter = funcutils.get_func_args(5, self.is_64bit) dwCreationFlags = funcutils.get_func_args(6, self.is_64bit) lpThreadId = funcutils.get_func_args(7, self.is_64bit) # 解析 dwCreationFlags 标志 creation_flags_descr = [] if dwCreationFlags & 0x00000004: # CREATE_SUSPENDED creation_flags_descr.append("CREATE_SUSPENDED") if dwCreationFlags & 0x00010000: # STACK_SIZE_PARAM_IS_A_RESERVATION creation_flags_descr.append("STACK_SIZE_PARAM_IS_A_RESERVATION") creation_flags_str = '|'.join(creation_flags_descr) if creation_flags_descr else '0' _debug_info = (f"hProcess={hex(hProcess)}, " f"lpThreadAttributes={hex(lpThreadAttributes)}, " f"dwStackSize={dwStackSize}, " f"lpStartAddress={hex(lpStartAddress)}, " f"lpParameter={hex(lpParameter)}, " f"dwCreationFlags={creation_flags_str}, " f"lpThreadId={hex(lpThreadId)}) = ") return _debug_info def CreateProcessA(self, is_return=False): def parse_creation_flags(dwCreationFlags): flags = [] if dwCreationFlags & 0x04000000: flags.append("CREATE_DEFAULT_ERROR_MODE") if dwCreationFlags & 0x00000010: flags.append("CREATE_NEW_CONSOLE") if dwCreationFlags & 0x00000200: flags.append("CREATE_NEW_PROCESS_GROUP") if dwCreationFlags & 0x08000000: flags.append("CREATE_NO_WINDOW") if dwCreationFlags & 0x00000004: flags.append("CREATE_SUSPENDED") if dwCreationFlags & 0x00000002: flags.append("DEBUG_ONLY_THIS_PROCESS") if dwCreationFlags & 0x00000001: flags.append("DEBUG_PROCESS") if dwCreationFlags & 0x00000008: flags.append("DETACHED_PROCESS") if dwCreationFlags & 0x00010000: flags.append("INHERIT_PARENT_AFFINITY") return '|'.join(flags) if flags else '0' if is_return: return_value = funcutils.get_result(self.is_64bit) success = "Success" if return_value else "Failure" return f"{success} -> BOOL" lpApplicationName = funcutils.get_func_args(1, self.is_64bit) lpCommandLine = funcutils.get_func_args(2, self.is_64bit) lpProcessAttributes = funcutils.get_func_args(3, self.is_64bit) lpThreadAttributes = funcutils.get_func_args(4, self.is_64bit) bInheritHandles = funcutils.get_func_args(5, self.is_64bit) dwCreationFlags = funcutils.get_func_args(6, self.is_64bit) lpEnvironment = funcutils.get_func_args(7, self.is_64bit) lpCurrentDirectory = funcutils.get_func_args(8, self.is_64bit) lpStartupInfo = funcutils.get_func_args(9, self.is_64bit) lpProcessInformation = funcutils.get_func_args(10, self.is_64bit) app_name = idc.get_strlit_contents(lpApplicationName).decode('utf-8') if lpApplicationName else "null" cmd_line = idc.get_strlit_contents(lpCommandLine).decode('utf-8') if lpCommandLine else "null" process_attr = f"{hex(lpProcessAttributes)}" thread_attr = f"{hex(lpThreadAttributes)}" inherit_handles = "TRUE" if bInheritHandles else "FALSE" creation_flags = parse_creation_flags(dwCreationFlags) environment = f"{hex(lpEnvironment)}" current_dir = idc.get_strlit_contents(lpCurrentDirectory).decode('utf-8') if lpCurrentDirectory else "null" startup_info = f"{hex(lpStartupInfo)}" process_info = f"{hex(lpProcessInformation)}" _debug_info = (f"lpApplicationName={app_name}, " f"lpCommandLine={cmd_line}, " f"lpProcessAttributes={process_attr}, " f"lpThreadAttributes={thread_attr}, " f"bInheritHandles={inherit_handles}, " f"dwCreationFlags={creation_flags}, " f"lpEnvironment={environment}, " f"lpCurrentDirectory={current_dir}, " f"lpStartupInfo={startup_info}, " f"lpProcessInformation={process_info}) = ") return _debug_info def CreateProcessW(self, is_return=False): def parse_creation_flags(dwCreationFlags): flags = [] if dwCreationFlags & 0x04000000: flags.append("CREATE_DEFAULT_ERROR_MODE") if dwCreationFlags & 0x00000010: flags.append("CREATE_NEW_CONSOLE") if dwCreationFlags & 0x00000200: flags.append("CREATE_NEW_PROCESS_GROUP") if dwCreationFlags & 0x08000000: flags.append("CREATE_NO_WINDOW") if dwCreationFlags & 0x00000004: flags.append("CREATE_SUSPENDED") if dwCreationFlags & 0x00000002: flags.append("DEBUG_ONLY_THIS_PROCESS") if dwCreationFlags & 0x00000001: flags.append("DEBUG_PROCESS") if dwCreationFlags & 0x00000008: flags.append("DETACHED_PROCESS") if dwCreationFlags & 0x00010000: flags.append("INHERIT_PARENT_AFFINITY") return '|'.join(flags) if flags else '0' if is_return: return_value = funcutils.get_result(self.is_64bit) success = "Success" if return_value else "Failure" return f"{success} -> BOOL" lpApplicationName = funcutils.get_func_args(1, self.is_64bit) lpCommandLine = funcutils.get_func_args(2, self.is_64bit) lpProcessAttributes = funcutils.get_func_args(3, self.is_64bit) lpThreadAttributes = funcutils.get_func_args(4, self.is_64bit) bInheritHandles = funcutils.get_func_args(5, self.is_64bit) dwCreationFlags = funcutils.get_func_args(6, self.is_64bit) lpEnvironment = funcutils.get_func_args(7, self.is_64bit) lpCurrentDirectory = funcutils.get_func_args(8, self.is_64bit) lpStartupInfo = funcutils.get_func_args(9, self.is_64bit) lpProcessInformation = funcutils.get_func_args(10, self.is_64bit) app_name = idc.get_strlit_contents(ea = lpApplicationName, strtype=idc.STRTYPE_C16).decode('utf-8') if lpApplicationName else "null" cmd_line = idc.get_strlit_contents(ea = lpCommandLine, strtype=idc.STRTYPE_C16).decode('utf-8') if lpCommandLine else "null" process_attr = f"{hex(lpProcessAttributes)}" thread_attr = f"{hex(lpThreadAttributes)}" inherit_handles = "TRUE" if bInheritHandles else "FALSE" creation_flags = parse_creation_flags(dwCreationFlags) environment = f"{hex(lpEnvironment)}" current_dir = idc.get_strlit_contents(ea=lpCurrentDirectory, strtype=idc.STRTYPE_C16).decode('utf-8') if lpCurrentDirectory else "null" startup_info = f"{hex(lpStartupInfo)}" process_info = f"{hex(lpProcessInformation)}" _debug_info = (f"lpApplicationName={app_name}, " f"lpCommandLine={cmd_line}, " f"lpProcessAttributes={process_attr}, " f"lpThreadAttributes={thread_attr}, " f"bInheritHandles={inherit_handles}, " f"dwCreationFlags={creation_flags}, " f"lpEnvironment={environment}, " f"lpCurrentDirectory={current_dir}, " f"lpStartupInfo={startup_info}, " f"lpProcessInformation={process_info}) = ") return _debug_info # anti debug def IsDebuggerPresent(self, is_return = False): if is_return: idc.set_reg_value(0, "EAX") return f"0 -> BOOL" _debug_info = ")=" return _debug_info def GetProcAddress(self, is_return = False): if is_return == True: return f" = {hex(funcutils.get_result(self.is_64bit))} -> FARPROC" hModule = funcutils.get_func_args(1, self.is_64bit) _debug_info = "kernel32!GetProcAddress(" _debug_info += f"hModule={hex(hModule)}, " lpProcNameAddr = funcutils.get_func_args(2, self.is_64bit) func_name += idc.get_strlit_contents(lpProcNameAddr).decode("utf-8") _debug_info += f"lpProcName={func_name})" return _debug_info # memory def VirtualAlloc(self, is_return=False): if is_return: return f"{hex(funcutils.get_result(self.is_64bit))} -> LPVOID" lpAddress = funcutils.get_func_args(1, self.is_64bit) dwSize = funcutils.get_func_args(2, self.is_64bit) flAllocationType = funcutils.get_func_args(3, self.is_64bit) flProtect = funcutils.get_func_args(4, self.is_64bit) allocation_flags = [] if flAllocationType & 0x00001000: allocation_flags.append("MEM_COMMIT") if flAllocationType & 0x00002000: allocation_flags.append("MEM_RESERVE") if flAllocationType & 0x00008000: allocation_flags.append("MEM_RESET") allocation_flags_str = '|'.join(allocation_flags) if allocation_flags else '0' protection_flags = [] if flProtect & 0x01: protection_flags.append("PAGE_NOACCESS") if flProtect & 0x02: protection_flags.append("PAGE_READONLY") if flProtect & 0x04: protection_flags.append("PAGE_READWRITE") if flProtect & 0x08: protection_flags.append("PAGE_WRITECOPY") protection_flags_str = '|'.join(protection_flags) if protection_flags else '0' _debug_info = (f"lpAddress={hex(lpAddress)}, " f"dwSize={dwSize}, " f"flAllocationType={allocation_flags_str}, " f"flProtect={protection_flags_str}) = ") return _debug_info def VirtualFree(self, is_return=False): if is_return: return f"{hex(funcutils.get_result(self.is_64bit))} -> BOOL" lpAddress = funcutils.get_func_args(1, self.is_64bit) dwSize = funcutils.get_func_args(2, self.is_64bit) dwFreeType = funcutils.get_func_args(3, self.is_64bit) free_flags = [] if dwFreeType & 0x00008000: free_flags.append("MEM_DECOMMIT") if dwFreeType & 0x00004000: free_flags.append("MEM_RELEASE") free_flags_str = '|'.join(free_flags) if free_flags else '0' _debug_info = (f"lpAddress={hex(lpAddress)}, " f"dwSize={dwSize}, " f"dwFreeType={free_flags_str}) = ") return _debug_info def VirtualProtect(self, is_return=False): if is_return: return f"{hex(funcutils.get_result(self.is_64bit))} -> BOOL" lpAddress = funcutils.get_func_args(1, self.is_64bit) dwSize = funcutils.get_func_args(2, self.is_64bit) flNewProtect = funcutils.get_func_args(3, self.is_64bit) lpflOldProtect = funcutils.get_func_args(4, self.is_64bit) protection_flags = [] if flNewProtect & 0x01: protection_flags.append("PAGE_NOACCESS") if flNewProtect & 0x02: protection_flags.append("PAGE_READONLY") if flNewProtect & 0x04: protection_flags.append("PAGE_READWRITE") if flNewProtect & 0x08: protection_flags.append("PAGE_WRITECOPY") if flNewProtect & 0x10: protection_flags.append("PAGE_EXECUTE") if flNewProtect & 0x20: protection_flags.append("PAGE_EXECUTE_READ") if flNewProtect & 0x40: protection_flags.append("PAGE_EXECUTE_READWRITE") if flNewProtect & 0x80: protection_flags.append("PAGE_EXECUTE_WRITECOPY") if flNewProtect & 0x100: protection_flags.append("PAGE_GUARD") if flNewProtect & 0x200: protection_flags.append("PAGE_NOCACHE") if flNewProtect & 0x400: protection_flags.append("PAGE_WRITECOMBINE") protection_flags_str = '|'.join(protection_flags) if protection_flags else 'UNKNOWN' _debug_info = (f"lpAddress={hex(lpAddress)}, " f"dwSize={dwSize}, " f"flNewProtect={protection_flags_str}, " f"lpflOldProtect={hex(lpflOldProtect)}) = ") return _debug_info