본문 바로가기
파이썬 스터디 과제/파이썬 해킹 프로그래밍

4장-3 프로세스 스냅샷

by laoching 2015. 1. 24.
728x90
반응형

pydbg는 프로세스 스냅샷이라는 엄청난 기능을 보유하고있다고 한다.

프로세스 스냅샷

프로세스를 일시 중지시켜 메모리 내용을 얻을 수 있다.

다시 그 프로세스를 실행할 수 있다.


프로세스 스냅샷 얻기

대상 프로세스의 어떤 특정 시점에서의 정확한 상태 정보를 얻는 것

ㄴ 먼저 모든 스레드 리스트를 구하고 각 스레드의 CPU 컨텍스트 정보를 구해야 한다.

또 모든 프로세스 메모리 페이지와 내용을 구해야 한다.

어떤 정보를 복원할 것인지에 따라 저장할 정보를 판단하고 필요한 정보를 저장한다.


프로세스 스냅샷을 위한 정보를 구하기 전에 실행중인 모든 스레드를 일시 중지시켜야 한다.

그래야만 스냅샷 정보를 추출하는 동안에 데이터와 생태 정보가 변경되지 않기 때문이다.

pydbg에서 모든 스레드를 일시 정지시키려면 suspend_all_threads()를 사용한다.

다시 실행하려면 resume_all_threads()를 사용한다.

일단 스레드르 정지시킨 후에 process_snapshot()을 호출하면 된다.

그러면 각 스레드에 대한 모든 컨텍스트 정보와 그 순간의 모든 메모리 정보가 자동으로 추출된다.

그리고 프로세스 스냅샷을 만든 다음에는 모든 스레드가 다시 실행되게 만들면 된다.

프로세스를 스냅샷이 만들어진 시점으로 복원하고자 할 때는 모든 스레드를 일시 정지시키고 process_restore()를 호출한 후 다시 모든 스레드를 재실행 시키면 된다.

snapshot.py

-----------------------------------------------------------------------

#snapshot.py

from pydbg import *
from pydbg.defines import *

import threading
import time
import sys

class snapshotter(object):

    def __init__(self,exe_path):

        self.exe_path = exe_path
        self.pid         = None
        self.dbg         = None
        self.running     = True

        # 디버깅 스레드를 시작시키고,
        # 대상 프로세스의 PID가 설정딜 떄까지 루프를 돈다.
        pydbg_thread =threading.Thread(target = self.start_debugger)
        pydbg_thread.setDaemon(0)
        pydbg_thread.start()

        while self.pid == None:
            time.sleep(1)
        # 지금은 PID가 설정된 상태이고 대상 프로세스가 실행 중이다.
        # 스냅샷을 위한 두 번째 스레드를 실행시킨다.

        monitor_thread = threading.Thread(target = self.monitor_debugger)
        monitor_thread.setDaemon(0)
        monitor_thread.start()

    def monitor_debugger(self):

        while self.running ==True:

            input = raw_input("Enter : 'snap','restore', or 'quit'")
            input = input.lower().strip()

            if input == "quit" :
                print "[*] Exiting the snapshotter"
                self.running = False
                self.dbg.terminate_process()

            elif input == "snap":
                print "[*] Suspending all threads"
                self.dbg.suspend_all_threads()

                print "[*] Obtaining snapshot"
                self.dbg.process_snapshot()

                print "[*] Resuming operation"
                self.dbg.resume_all_threads()
       
            elif input == "restore":
                print "[*] Suspending all therads"
                self.dbg.suspend_all_threads()

                print "[*] Restoring snapshot"
                self.dbg.process_restore()

                print "[*] Resuming operation"
                self.dbg.resume_all_threads()

    def start_debugger(self)    :
        self.dbg = pydbg()
        pid = self.dbg.load(self.exe_path)
        self.pid = self.dbg.pid

        self.dbg.run()

    exe_path = "C:\\WINDOWS\\System32\\calc.exe"
    snapshotter(exe_path)
-------------------------------------------------------------------

1. 디버거 스레드하에서 대상 애플리케이션 실행

2. 디버거 스레드가 유효한 PID를 반환하면 사용자 입력을 받아들일 새로운 스레드를 실행

3. 스냅샷을 만들 것인지, 스냅샷 시점으로 복원할 것인지, 종료할 것인지 명령 입력


728x90
반응형

댓글