Last active
February 18, 2023 10:34
-
-
Save 196Ikuchil/2cd5e900541cff606bfa51a2f86e4e0a to your computer and use it in GitHub Desktop.
リバースエンジニアリング Pythonによるバイナリ解析技法 3.2 python3.7.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from ctypes import * | |
| # Let's map the Microsoft types to ctypes for clarity | |
| BYTE = c_ubyte | |
| WORD = c_ushort | |
| DWORD = c_ulong | |
| DWORD64 = c_ulonglong | |
| LPBYTE = POINTER(c_ubyte) | |
| LPTSTR = POINTER(c_char) | |
| HANDLE = c_void_p | |
| PVOID = c_void_p | |
| LPVOID = c_void_p | |
| UINT_PTR = c_ulong | |
| SIZE_T = c_ulong | |
| ULONG_PTR = c_ulong | |
| LONGLONG = c_longlong | |
| ULONGLONG = c_ulonglong | |
| # Constants | |
| DEBUG_PROCESS = 0x00000001 | |
| CREATE_NEW_CONSOLE = 0x00000010 | |
| PROCESS_ALL_ACCESS = 0x001F0FFF | |
| INFINITE = 0xFFFFFFFF | |
| DBG_CONTINUE = 0x00010002 | |
| DBG_EXCEPTION_NOT_HANDLED = 0x80010001 | |
| # Debug event constants | |
| EXCEPTION_DEBUG_EVENT = 0x1 | |
| CREATE_THREAD_DEBUG_EVENT = 0x2 | |
| CREATE_PROCESS_DEBUG_EVENT = 0x3 | |
| EXIT_THREAD_DEBUG_EVENT = 0x4 | |
| EXIT_PROCESS_DEBUG_EVENT = 0x5 | |
| LOAD_DLL_DEBUG_EVENT = 0x6 | |
| UNLOAD_DLL_DEBUG_EVENT = 0x7 | |
| OUTPUT_DEBUG_STRING_EVENT = 0x8 | |
| RIP_EVENT = 0x9 | |
| # debug exception codes. | |
| EXCEPTION_ACCESS_VIOLATION = 0xC0000005 | |
| EXCEPTION_BREAKPOINT = 0x80000003 | |
| EXCEPTION_GUARD_PAGE = 0x80000001 | |
| EXCEPTION_SINGLE_STEP = 0x80000004 | |
| # Thread constants for CreateToolhelp32Snapshot() | |
| TH32CS_SNAPHEAPLIST = 0x00000001 | |
| TH32CS_SNAPPROCESS = 0x00000002 | |
| TH32CS_SNAPTHREAD = 0x00000004 | |
| TH32CS_SNAPMODULE = 0x00000008 | |
| TH32CS_INHERIT = 0x80000000 | |
| TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE) | |
| THREAD_ALL_ACCESS = 0x001F03FF | |
| # Context flags for GetThreadContext() | |
| CONTEXT_AMD64 = 0x00100000 | |
| CONTEXT_CONTROL = CONTEXT_AMD64|0x00000001 | |
| CONTEXT_INTEGER = CONTEXT_AMD64|0x00000002 | |
| CONTEXT_SEGMENTS = CONTEXT_AMD64|0x00000004 | |
| CONTEXT_FLOATING_POINT = CONTEXT_AMD64|0x00000008 | |
| CONTEXT_DEBUG_REGISTERS = CONTEXT_AMD64|0x00000010 | |
| CONTEXT_FULL = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_FLOATING_POINT | |
| CONTEXT_ALL = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS|CONTEXT_FLOATING_POINT|CONTEXT_DEBUG_REGISTERS | |
| # Memory permissions | |
| PAGE_EXECUTE_READWRITE = 0x00000040 | |
| # Hardware breakpoint conditions | |
| HW_ACCESS = 0x00000003 | |
| HW_EXECUTE = 0x00000000 | |
| HW_WRITE = 0x00000001 | |
| # Memory page permissions, used by VirtualProtect() | |
| PAGE_NOACCESS = 0x00000001 | |
| PAGE_READONLY = 0x00000002 | |
| PAGE_READWRITE = 0x00000004 | |
| PAGE_WRITECOPY = 0x00000008 | |
| PAGE_EXECUTE = 0x00000010 | |
| PAGE_EXECUTE_READ = 0x00000020 | |
| PAGE_EXECUTE_READWRITE = 0x00000040 | |
| PAGE_EXECUTE_WRITECOPY = 0x00000080 | |
| PAGE_GUARD = 0x00000100 | |
| PAGE_NOCACHE = 0x00000200 | |
| PAGE_WRITECOMBINE = 0x00000400 | |
| # Structures for CreateProcessA() function | |
| # STARTUPINFO describes how to spawn the process | |
| class STARTUPINFO(Structure): | |
| _fields_ = [ | |
| ("cb", DWORD), | |
| ("lpReserved", LPTSTR), | |
| ("lpDesktop", LPTSTR), | |
| ("lpTitle", LPTSTR), | |
| ("dwX", DWORD), | |
| ("dwY", DWORD), | |
| ("dwXSize", DWORD), | |
| ("dwYSize", DWORD), | |
| ("dwXCountChars", DWORD), | |
| ("dwYCountChars", DWORD), | |
| ("dwFillAttribute",DWORD), | |
| ("dwFlags", DWORD), | |
| ("wShowWindow", WORD), | |
| ("cbReserved2", WORD), | |
| ("lpReserved2", LPBYTE), | |
| ("hStdInput", HANDLE), | |
| ("hStdOutput", HANDLE), | |
| ("hStdError", HANDLE), | |
| ] | |
| # PROCESS_INFORMATION receives its information | |
| # after the target process has been successfully | |
| # started. | |
| class PROCESS_INFORMATION(Structure): | |
| _fields_ = [ | |
| ("hProcess", HANDLE), | |
| ("hThread", HANDLE), | |
| ("dwProcessId", DWORD), | |
| ("dwThreadId", DWORD), | |
| ] | |
| class EXCEPTION_RECORD(Structure): | |
| pass | |
| EXCEPTION_RECORD._fields_ = [ | |
| ("ExceptionCode", DWORD), | |
| ("ExceptionFlags", DWORD), | |
| ("ExceptionRecord", POINTER(EXCEPTION_RECORD)), | |
| ("ExceptionAddress", PVOID), | |
| ("NumberParameters", DWORD), | |
| ("ExceptionInformation", ULONG_PTR*15), | |
| ] | |
| class _EXCEPTION_RECORD(Structure): | |
| _fields_ = [ | |
| ("ExceptionCode", DWORD), | |
| ("ExceptionFlags", DWORD), | |
| ("ExceptionRecord", POINTER(EXCEPTION_RECORD)), | |
| ("ExceptionAddress", PVOID), | |
| ("NumberParameters", DWORD), | |
| ("ExceptionInformation", ULONG_PTR*15), | |
| ] | |
| class EXCEPTION_DEBUG_INFO(Structure): | |
| _fields_ = [ | |
| ("ExceptionRecord", EXCEPTION_RECORD), | |
| ("dwFirstCance", DWORD), | |
| ] | |
| class U(Union): | |
| _fields_ = [ | |
| ("Exception", EXCEPTION_DEBUG_INFO), | |
| ] | |
| class DEBUG_EVENT(Structure): | |
| _fields_ = [ | |
| ("dwDebugEventCode", DWORD), | |
| ("dwProcessId", DWORD), | |
| ("dwThreadId", DWORD), | |
| ("u", U), | |
| ] | |
| class M128A(Structure): | |
| _fields_ = [ | |
| ("Low", ULONGLONG), | |
| ("High", LONGLONG), | |
| ] | |
| class XSAVE_FORMAT(Structure): | |
| _fields_ = [ | |
| ("ControlWord", WORD), | |
| ("StatusWord", WORD), | |
| ("TagWord", BYTE), | |
| ("Reservedl", BYTE), | |
| ("ErrorOpcode", WORD), | |
| ("ErrorOffset", DWORD), | |
| ("ErrorSelector", WORD), | |
| ("Reserved2", WORD), | |
| ("DataOffset", DWORD), | |
| ("DataSelector", WORD), | |
| ("Reserved3", WORD), | |
| ("MxCsr", DWORD), | |
| ("MxCsr_Mask", DWORD), | |
| ("FloatRegisters", M128A*8), | |
| ("XmmRegisters", M128A*16), | |
| ("Reserved4", BYTE*96), | |
| ] | |
| class DUMMYSTRUCTNAME(Structure): | |
| _fields_ = [ | |
| ("Header", M128A*2), | |
| ("Legacy", M128A*8), | |
| ("Xmm0", M128A), | |
| ("Xmm1", M128A), | |
| ("Xmm2", M128A), | |
| ("Xmm3", M128A), | |
| ("Xmm4", M128A), | |
| ("Xmm5", M128A), | |
| ("Xmm6", M128A), | |
| ("Xmm7", M128A), | |
| ("Xmm8", M128A), | |
| ("Xmm9", M128A), | |
| ("Xmm10", M128A), | |
| ("Xmm11", M128A), | |
| ("Xmm12", M128A), | |
| ("Xmm13", M128A), | |
| ("Xmm14", M128A), | |
| ("Xmm15", M128A), | |
| ] | |
| XMM_SAVE_AREA32 = XSAVE_FORMAT | |
| class DUMMYUNIONNAME(Union): | |
| _fields_ = [ | |
| ("FltSave", XMM_SAVE_AREA32), | |
| ("dummystructname", DUMMYSTRUCTNAME) | |
| ] | |
| class CONTEXT(Structure): | |
| _fields_ = [ | |
| ("P1Home", DWORD64), | |
| ("P2Home", DWORD64), | |
| ("P3Home", DWORD64), | |
| ("P4Home", DWORD64), | |
| ("P5Home", DWORD64), | |
| ("P6Home", DWORD64), | |
| ("ContextFlags", DWORD), | |
| ("MxCsr", DWORD), | |
| ("SegCs", WORD), | |
| ("SegDs", WORD), | |
| ("SegEs", WORD), | |
| ("SegFs", WORD), | |
| ("SegGs", WORD), | |
| ("SegSs", WORD), | |
| ("EFlags", DWORD), | |
| ("Dr0", DWORD64), | |
| ("Dr1", DWORD64), | |
| ("Dr2", DWORD64), | |
| ("Dr3", DWORD64), | |
| ("Dr6", DWORD64), | |
| ("Dr7", DWORD64), | |
| ("Rax", DWORD64), | |
| ("Rcx", DWORD64), | |
| ("Rdx", DWORD64), | |
| ("Rbx", DWORD64), | |
| ("Rsp", DWORD64), | |
| ("Rbp", DWORD64), | |
| ("Rsi", DWORD64), | |
| ("Rdi", DWORD64), | |
| ("R8", DWORD64), | |
| ("R9", DWORD64), | |
| ("R10", DWORD64), | |
| ("R11", DWORD64), | |
| ("R12", DWORD64), | |
| ("R13", DWORD64), | |
| ("R14", DWORD64), | |
| ("R15", DWORD64), | |
| ("Rip", DWORD64), | |
| ("dummyunionname", DUMMYUNIONNAME), | |
| ("VectorRegister", M128A*26), | |
| ("VectorControl", DWORD64), | |
| ("DebugControl", DWORD64), | |
| ("LastBranchToRip", DWORD64), | |
| ("LastBranchFromRip", DWORD64), | |
| ("LastExceptionToRip", DWORD64), | |
| ("LastExceptionFromRip", DWORD64), | |
| ] | |
| # THREADENTRY32 contains information about a thread | |
| # we use this for enumerating all of the system threads | |
| class THREADENTRY32(Structure): | |
| _fields_ = [ | |
| ("dwSize", DWORD), | |
| ("cntUsage", DWORD), | |
| ("th32ThreadID", DWORD), | |
| ("th32OwnerProcessID", DWORD), | |
| ("tpBasePri", DWORD), | |
| ("tpDeltaPri", DWORD), | |
| ("dwFlags", DWORD), | |
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from src.defines import* | |
| from ctypes import * | |
| from src import defines | |
| kernel32 = windll.kernel32 | |
| class Debugger(): | |
| def __init__(self): | |
| self.h_process = None | |
| self.pid = None | |
| self.debugger_active= False | |
| self.h_thread = None | |
| self.context = None | |
| self.exception_address=None | |
| self.software_breakpoints = {} | |
| def load(self,path_to_exe): | |
| #dwCreationFlag�ソスノゑソス�ソス | |
| #�ソスユろせ�ソス�ソス�ソス�ソス�ソスヌのよう�ソスノ撰ソス�ソス�ソス�ソス�ソス�ソス驍ゥ�ソス�ソス�ソス�ソス�ソスワゑソス | |
| #�ソスd�ソス�ソス�ソスGUI�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス | |
| # creation_flags = CREATE_NEW_CONSOLE�ソスニ設定す�ソス�ソス | |
| creation_flags = DEBUG_PROCESS | |
| #�ソス\�ソス�ソス�ソスフゑソス�ソスC�ソス�ソス�ソスX�ソス^�ソス�ソス�ソスX�ソス�ソス | |
| startupinfo= STARTUPINFO() | |
| process_information =PROCESS_INFORMATION() | |
| #�ソスツゑソス�ソスフ2�ソスツのオ�ソスv�ソスV�ソス�ソス�ソス�ソス�ソスノゑソス�ソスf�ソスN�ソス�ソス�ソス�ソス�ソス黷ス�ソスv�ソス�ソス�ソスZ�ソスX�ソス�ソス | |
| #�ソスハウ�ソスB�ソス�ソス�ソスh�ソスE�ソスニゑソス�ソスト表�ソス�ソス�ソス�ソス�ソス�ソス�ソス | |
| #STARTUPINFO�ソス\�ソス�ソス�ソスフにゑソス�ソス�ソス�ソス�ソスン定が�ソスf�ソスo�ソスb�ソスO�ソスホ象ゑソス | |
| #�ソスe�ソス�ソス�ソス�ソス�ソスy�ソスレゑソス�ソス�ソスナゑソス�ソス�ソス�ソス�ソス | |
| startupinfo.dwFlags = 0x1 | |
| startupinfo.wShowWindow = 0x0 | |
| #STARTUPINFO�ソス\�ソス�ソス�ソスフのゑソス�ソス�ソス�ソス�ソス�ソス�ソス\�ソス�ソス�ソスマ撰ソスcd�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス�ソス | |
| startupinfo.cb=sizeof(startupinfo) | |
| if kernel32.CreateProcessA(path_to_exe, | |
| None, | |
| None, | |
| None, | |
| None, | |
| creation_flags, | |
| None, | |
| None, | |
| byref(startupinfo), | |
| byref(process_information)): | |
| print ("*[*] PID: %d" % process_information.dwProcessId) | |
| self.h_process = self.open_process(process_information.dwProcessId) | |
| else: | |
| print ("*[*] Error:0x%08x." % kernel32.GetLastError()) | |
| def open_process(self,pid): | |
| handle = kernel32.OpenProcess(PROCESS_ALL_ACCESS,False,pid) | |
| if not handle: | |
| print (WinError(GetLastError())) | |
| return handle | |
| def attach(self,pid): | |
| self.handle = self.open_process(pid) | |
| if kernel32.DebugActiveProcess(pid): | |
| self.debugger_active=True | |
| self.pid=int(pid) | |
| return True | |
| else: | |
| print(WinError(GetLastError())) | |
| return False | |
| def run(self): | |
| while self.debugger_active: | |
| self.get_debug_event() | |
| def get_debug_event(self): | |
| debug_event = DEBUG_EVENT() | |
| if kernel32.WaitForDebugEvent(byref(debug_event),INFINITE): | |
| input("press a key to continue...") | |
| self.debugger_active=False | |
| kernel32.ContinueDebugEvent(debug_event.dwProcessId, | |
| debug_event.dwThreadId, | |
| DBG_CONTINUE) | |
| def detach(self): | |
| if kernel32.DebugActiveProcessStop(self.pid): | |
| print("[*] finished debugging. Exiting...") | |
| return True | |
| else: | |
| print(WinError(GetLastError())) | |
| return False | |
| def open_thread(self,thread_id): | |
| h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS,None,thread_id) | |
| if h_thread is not 0: | |
| return h_thread | |
| else: | |
| print("[*] Could not obtain a valid thread handle.") | |
| return False | |
| def enumerate_threads(self): | |
| thread_entry=THREADENTRY32() | |
| thread_list = [] | |
| snapshot =kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,self.pid) | |
| if snapshot is not None: | |
| thread_entry.dwSize = sizeof(thread_entry) | |
| success = kernel32.Thread32First(snapshot,byref(thread_entry)) | |
| while success: | |
| if thread_entry.th32OwnerProcessID == self.pid: | |
| thread_list.append(thread_entry.th32ThreadID) | |
| success = kernel32.Thread32Next(snapshot,byref(thread_entry)) | |
| kernel32.CloseHandle(snapshot) | |
| return thread_list | |
| else: | |
| return False | |
| def get_thread_context(self,thread_id=None,h_thread=None): | |
| context = CONTEXT() | |
| context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS | |
| #get thread handle | |
| if h_thread is None: | |
| h_thread = self.open_thread(thread_id) | |
| if kernel32.GetThreadContext(h_thread,byref(context)): | |
| kernel32.CloseHandle(h_thread) | |
| return context | |
| else: | |
| return False |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from src.my_debugger import * | |
| from src import my_debugger | |
| debugger = my_debugger.Debugger() | |
| # debugger.load("C:\\Windows\\System32\\calc.exe") | |
| pid = int(input("PID: ")) | |
| debugger.attach(pid) | |
| #debugger.run() | |
| list = debugger.enumerate_threads() | |
| for thread in list: | |
| context = debugger.get_thread_context(thread) | |
| print("[Rip]0x{:016X}".format(context.Rip)) | |
| print("[Rax]0x{:016X}".format(context.Rax)) | |
| print("[Rcx]0x{:016X}".format(context.Rcx)) | |
| print("[Rdx]0x{:016X}".format(context.Rdx)) | |
| print("[Rbx]0x{:016X}".format(context.Rbx)) | |
| print("[Rsp]0x{:016X}".format(context.Rsp)) | |
| print("[Rbp]0x{:016X}".format(context.Rsp)) | |
| print("[Rsi]0x{:016X}".format(context.Rsi)) | |
| print("[Rdi]0x{:016X}".format(context.Rdi)) | |
| debugger.detach() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment