《python灰帽子》源码三,获取寄存器状态

本文详细介绍了一个基于Python3.5-32位的调试器实现,包括定义Microsoft类型映射、结构体、常量及调试器类的方法。通过具体实例展示了如何加载、依附进程,枚举并获取线程上下文,特别指出在不同环境下调试器的表现差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天才发现自己的python3是64位的,一直以为是32位的,所以我后面的代码都将使用python 3.5 - 32位

win10系统,python3.5-32位,编码软件vscode

因为跟上一章代码有重复的就以。。。带过了,新添加的代码都会显示出来

上代码

首先my_debugger_defines.py文件

from ctypes import *

# 为了清晰起见,让我们将Microsoft类型映射到ctypes
BYTE                            = c_ubyte
WORD                            = c_ushort
DWORD                           = c_ulong
LPBYTE                          = POINTER(c_ubyte)
LPTSTR                          = POINTER(c_char)
HANDLE                          = c_void_p

LONG = c_long
PVOID = c_void_p
ULONG_PTR =c_ulong
ULONG = c_ulong

DEBUG_PROCESS                   = 0x00000001
CREATE_NEW_CONSOLE              = 0x00000010

# 常量
PROCESS_ALL_ACCESS              = 0x001F0FFF
INFINITE                        = 0xFFFFFFFF

DBG_CONTINUE                    = 0x00010002
TH32CS_SNAPTHREAD               = 0x00000004    # 包括快照中系统中的所有线程。要枚举线程

# 线程常量
THREAD_ALL_ACCESS               = 0x001F03FF

# GetThreadContext()的上下文标志   
CONTEXT_FULL                    = 0x00010007   
CONTEXT_DEBUG_REGISTERS         = 0x00010010

。。。。。。。。。

class THREADENTRY32(Structure):
    _fields_ = [
        ("dwSize",DWORD),
        ("cntUsage",DWORD),
        ("th32ThreadID",DWORD),
        ("th32OwnerProcessID",DWORD),
        ("tpBasePri",LONG),
        ("tpDeltaPri",LONG),
        ("dwFlags",DWORD),
    ]

# Used by the CONTEXT structure   
class FLOATING_SAVE_AREA(Structure):   
   _fields_ = [
        ("ControlWord", DWORD),   
        ("StatusWord", DWORD),   
        ("TagWord", DWORD),   
        ("ErrorOffset", DWORD),   
        ("ErrorSelector", DWORD),   
        ("DataOffset", DWORD),   
        ("DataSelector", DWORD),   
        ("RegisterArea", BYTE * 80),   
        ("Cr0NpxState", DWORD),   
]   
   
# The CONTEXT structure which holds all of the    
# register values after a GetThreadContext() call   
class CONTEXT(Structure):   
    _fields_ = [
        ("ContextFlags", DWORD),   
        ("Dr0", DWORD),   
        ("Dr1", DWORD),   
        ("Dr2", DWORD),   
        ("Dr3", DWORD),   
        ("Dr6", DWORD),   
        ("Dr7", DWORD),   
        ("FloatSave", FLOATING_SAVE_AREA),   
        ("SegGs", DWORD),   
        ("SegFs", DWORD),   
        ("SegEs", DWORD),   
        ("SegDs", DWORD),   
        ("Edi", DWORD),   
        ("Esi", DWORD),   
        ("Ebx", DWORD),   
        ("Edx", DWORD),   
        ("Ecx", DWORD),   
        ("Eax", DWORD),   
        ("Ebp", DWORD),   
        ("Eip", DWORD),   
        ("SegCs", DWORD),   
        ("EFlags", DWORD),   
        ("Esp", DWORD),   
        ("SegSs", DWORD),   
        ("ExtendedRegisters", BYTE * 512),   
]

定义的常量,类型,以及新增结构体都贴了出来,但是还有很多结构体可以从上一章中获取到,就不贴出来。

my_debugger.py文件

from ctypes import * 
from my_debugger_defines import * 
kernel32 = windll.kernel32 
class debugger(): 
    def __init__(self): 
        self.h_process              = None          # 进程句柄
        self.pid                    = None          # 进程pid
        self.debugger_active        = False         # 进程活跃状态
        self.h_thread               = None          # 线程id
        self.context                = None          # 寄存器内容
        pass 

    def load(self,path_to_exe):

        
    def open_process(self,pid):

    
    def attach(self,pid):


    def run(self):

    
    def get_debug_event(self):

    
    def detach(self):

    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)
            # 通过Thread32First列举出线程
            success = kernel32.Thread32First(snapshot,byref((thread_entry)))
            while success:
                # 线程拥有的进程id必须与我们输入的pid相同
                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):
        """
        获取寄存器内容
        """
        context                 = CONTEXT()
        context.ContextFlags    = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
        # 获得一个线程句柄
        h_thread = self.open_thread(thread_id)
        if kernel32.GetThreadContext(h_thread,byref(context)):
            kernel32.CloseHandle(h_thread)
            return context
        else:
            return False

    def open_thread(self,thread_id):
        """
        打开线程,获取线程句柄
        :param thread_id 线程id类似进程pid
        :return 线程句柄
        """
        h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS,None,thread_id)
        if h_thread is not None:
            return h_thread
        else:
            print("[*] 无法获得有效的线程句柄")
            return False
    

新添加的属性以及方法都贴了出来,有些方法可以从上一章找,不然贴出来就太长了。

最后my_test.py

from my_debugger import debugger
debugger = debugger() 

pid = input("输入需要依附的程序的pid:")
debugger.attach(int(pid))

list = debugger.enumerate_threads()
for thread in list:
    thread_context = debugger.get_thread_context(thread)
    print("[*] 线程id:0x%08x" % thread)
    print("[*] EIP:0x%08x" % thread_context.Eip)
    print("[*] ESP:0x%08x" % thread_context.Esp)
    print("[*] EBP:0x%08x" % thread_context.Ebp)
    print("[*] EAX:0x%08x" % thread_context.Eax)
    print("[*] EBX:0x%08x" % thread_context.Ebx)
    print("[*] ECX:0x%08x" % thread_context.Ecx)
    print("[*] EDX:0x%08x" % thread_context.Edx)

debugger.detach()

我觉得运行这次代码最主要是确定python是32位的,刚开始我是用python3.6的64位运行,一直都有问题出现,后来换成32位就成功了,但是换了之后却不能用在系统自带的计算器上了,老是在attach()这个函数报错,根据kernel32.GetLastError()返回来的值是50,表示不支持该请求,用在系统自带的截图工具软件上也是一样,但是使用酷狗这些软件就可以。

本书是由知名安全机构ImmunityInc的资深黑帽JustinSeitz先生主笔撰写的一本关于编程语言Python如何被广泛应用于黑客与逆向工程领域的书籍.老牌黑客,同时也是Immunity Inc的创始人兼首席技术执行官(CTO)Dave Aitel为本书担任了技术编辑一职。本书的绝大部分篇幅着眼于黑客技术领域中的两大经久不衰的话题:逆向工程与漏洞挖掘,并向读者呈现了几乎每个逆向工程师或安全研究人员在日常工作中所面临的各种场景,其中包括:如何设计?构建自己的调试工具,如何自动化实现烦琐的逆向分析任务,如何设计与构建自己的fuzzing工具,如何利用fuzzing测试来找出存在于软件产品中的安全漏洞,一些小技巧诸如钩子与注入技术的应用,以及对一些主流Python安全工具如PyDbg、Immunity Debugger、Sulley、IDAPython、PyEmu等的深入介绍。作者借助于如今黑客社区中备受青睐的编程语言Python引领读者构建出精悍的脚本程序来——应对上述这些问题。出现在本书中的相当一部分Python代码实例借鉴或直接来源于一些优秀的开源安全项目,诸如Pedram Amini的Paimei,由此读者可以领略到安全研究者?是如何将黑客艺术与工程技术优雅融合来解决那些棘手问题的。   本书适合热衷于黑客技术,特别是与逆向工程与漏洞挖掘领域相关的读者,以及所有对Python编程感兴趣的读者阅读与参考。 目录 第1章 搭建开发环境   1.1 操作系统要求   1.2获取和安装Python 2.5   1.2.1 在Windows下安装Python   1.2.2 在Linux下安装Python   1.3 安装Eclipse和PyDev   1.3.1 黑客挚友:ctype库   1.3.2 使用动态链接库   1.3.3 构建C数据类型   1.3.4 按引用传参   1.3.5 定义结构体和联合体   第2章 调试器原理和设计   2.1 通用寄存器   2.2 栈   2.3 调试事件   2.4 断点   2.4.1 软断点   2.4.2 硬件断点   2.4.3 内存断点   第3? 构建自己的Windows调试器   3.1 Debugee,敢问你在何处   3.2 获取寄存器状态信息   3.2.1 线程枚举   3.2.2功能整合   3.3 实现调试事件处理例程   3.4 无所不能的断点   3.4.1 软断点   3.4.2 硬件断点   3.4.3 内存断点   3.5 总结   第4章 PyDbg——WindoWS下的纯Python调试器   4.1 扩展断点处理例程   4.2 非法内存操作处理例程   4.3 进程快照   4.3.1 获取进程快照   4.3.2汇总与整合   第5章 Immunity Debugger一两极世界的最佳选择   5.1 安装Immunity Debugger   5.2 Immunity Debugger l01   5.2.1 PyCommand命令   5.2.2 PyHooks   5.3 Exploit(漏洞利用程序)开发   5.3.1 搜寻exploit友好指令   5.3.2“坏”字符过滤   5.3.3 绕过Windows下的DEP机制   5.4 破除恶意软件中的反调试例程   5.4 1 lsDebuugerPresent   5.4.2 破除进程枚举例程   第6章 钩子的艺术   6.1 使用PyDbg部署软钩子   6.2 使用Immunity Debugger部署硬钩子   第7章 DLL注入与代码注入技术   7.1 创建远程线程   7.1.1 DLL注入   7.1.2 代码注入   第8章 Fuzzing   第9章 Sulley   第10章 面向Windows驱动的Fuzzing测试技术   第11章 IDAPyrhon——IDA PRO环境下的Pyrhon   第12章 PYEmu——脚本驱动式仿真器
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值