pydbgでAnti-Anti-Debugging
マルウェアなどがデバッグを難しくするためのテクニックの1つにAnti-Debuggingといわれるものがあります。
その名の通りデバッグを中止させるためのテクニックです。
Windows Anti-Debug Reference
リンク先で紹介されているIsDebuggerPresent()を用いたAnti-Debuggingの無効化をpydbgでやってみます。
基礎知識
IsDebuggerPresent()はデバッグされていたら1、されていなければ0を返すAPI。
どう実装されているかというと、PEB(Process Enviroment Block)のBeingDebugged byte-flagを読んでいるだけ。
つまりIsDebuggerPresent()を使ったAnti-Debuggingを無効にするにはこのフラグを0に書き変えてやればいいいのです。
PEBははFSレジスタの中のTIB(Thread Information Block)のさらにその中にあります。
TIBのFSレジスタからのオフセットは0x18、PEBのTIBからのオフセットは0x30、フラグのPEBからのオフセットは0x2と固定さているので簡単に書き換えができるのです。
実装
from pydbg import * from pydbg.defines import * def hide_debugger(self): selector_entry = LDT_ENTRY() # a current thread context is required. if not self.context: raise pdx("hide_debugger(): a thread context is required. Call me from a breakpoint handler.") if not kernel32.GetThreadSelectorEntry(self.h_thread, self.context.SegFs, byref(selector_entry)): self.win32_error("GetThreadSelectorEntry()") fs_base = selector_entry.BaseLow fs_base += (selector_entry.HighWord.Bits.BaseMid << 16) + (selector_entry.HighWord.Bits.BaseHi << 24) peb = self.read_process_memory(fs_base + 0x30, 4) peb = self.flip_endian_dword(peb) self.write_process_memory(peb+2, "\x00", 1) return self.ret_self() def handler_bp (dbg): if dbg.first_breakpoint: dbg.hide_debugger() return DBG_CONTINUE if __name__ == "__main__": dbg = pydbg() dbg.set_callback(EXCEPTION_BREAKPOINT, handler_bp) dbg.load("IsDebuggerPresent.exe") dbg.run()
pydbgだとこんなコードになります。
Immunity Debuggerを使うと・・・
imm.WriteMemory(img.getPEBaddress() + 2, "\x00")
これだけで済みます。便利ですね。