4.6 x64dbg 内存扫描与查壳实现

这篇具有很好参考价值的文章主要介绍了4.6 x64dbg 内存扫描与查壳实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

LyScript 插件中默认提供了多种内存特征扫描函数,每一种扫描函数用法各不相同,在使用扫描函数时应首先搞清楚不同函数之间的差异,本章内容将分别详细介绍每一种内存扫描函数是如何灵活运用,并实现一种内存查壳脚本,可快速定位目标程序加了什么壳以及寻找被加壳程序的入口点。

计算机中的壳定义

加壳通常指对可执行文件或者动态链接库等二进制文件进行加密或压缩等处理,以使得这些文件难以被反汇编或破解。通常情况下,加壳会增加二进制文件的大小,并在程序运行时增加一定的开销。加壳技术通常被用于保护软件的知识产权和防止软件被盗版。通过加壳,软件开发者可以使得软件更难被破解和复制,从而保护自己的商业利益。

计算机中查壳的原理

软件查壳的实现原理可以分为静态分析和动态分析两种方式。静态分析是指在不运行被加壳程序的情况下,通过对程序的二进制代码进行解析,识别出程序是否被加壳,以及加壳的种类和方法。动态分析是指通过运行被加壳程序,并观察程序运行时的行为,识别程序是否被加壳,以及加壳的种类和方法。

静态分析的实现原理通常包括以下几个步骤:

  • 提取被分析程序的二进制代码;
  • 识别程序的文件格式,并解析文件头等元数据信息;
  • 根据文件格式,从程序代码中提取节区、导入表、导出表等重要信息;
  • 分析程序的代码段,并检查代码中是否存在加壳相关的特征,如代码的执行流程、加密算法等;
  • 根据分析结果,判断程序是否被加壳,以及加壳的种类和方法。

静态分析的优点是分析速度快,不需要运行程序,可以有效地识别出程序中的加壳。但是它也有一些缺点,例如无法识别动态加载的加壳、易受代码混淆和反调试等技术的影响。

动态分析的实现原理通常包括以下几个步骤:

  • 启动被分析程序,并在程序运行期间捕捉程序的行为;
  • 跟踪程序的执行流程,并分析程序的内存、寄存器、堆栈等状态信息;
  • 检查程序的内存中是否存在加壳相关的特征,如解密函数、加壳程序等;
  • 根据分析结果,判断程序是否被加壳,以及加壳的种类和方法。

动态分析的优点是可以识别动态加载的加壳,并且可以有效地避免代码混淆和反调试等技术的影响。但是它也有一些缺点,例如需要运行被分析程序,因此可能会影响程序的性能和稳定性,并且可能会被加壳程序的反调试技术所绕过。

本例中将采用scan_memory_all()函数对特定内存进行动态扫描,该函数用来扫描当前进程内EIP所指向位置处整个内存段中符合条件的特征,如果找到了则返回一个列表,如果没有找到则返回False,该函数与scan_memory_one()函数原理是一致的,唯一的不同是all以列表形式返回所有匹配到的行,one则只返回匹配到的第一条记录,这两个函数都支持??模糊匹配。

如果载入一个程序,默认停留在系统领空,则调用该函数你所能得到的特征记录只能是系统领空当前dll内的特征集。

4.6 x64dbg 内存扫描与查壳实现

例如在程序被载入后,其EIP指针默认会停留在ntdll.dll模块上,需要注意的是,函数scan_memory_one用于扫描并返回第一段符合条件的内存,函数scan_memory_all则用于扫描并输出当前所有符合条件的内存地址;

>>> from LyScript32 import MyDebug
>>>
>>> dbg = MyDebug()
>>> conn = dbg.connect()
>>>
>>> ref_one = dbg.scan_memory_one("55 8b ec")
>>> ref_one
1995793090
>>>
>>> ref_all = dbg.scan_memory_all("55 8b ec")
>>> ref_all
[1995793090, 1995793298, 1995793455, 1995793799, 1995794214]

而有时,我们需要指定扫描某个模块,例如扫描进程内的msvcr120.dll模块里面的特征,则此时读者可调用scan_memory_any()函数,该函数无需切换到模块入口处即可实现扫描特定模块内的特征,不过该函数只能返回找到的第一条记录,且需要传入扫描起始位置以及扫描长度,不过得到这些参数并不难。

from LyScript32 import MyDebug

if __name__ == "__main__":
    dbg = MyDebug()
    conn = dbg.connect()

    # 得到进程模块
    local_module = dbg.get_all_module()[0]

    # 得到模块参数
    module_base = local_module.get("base")
    module_size = local_module.get("size")
    print("基地址: {} 长度: {} 结束地址: {}".format(hex(module_base),hex(module_size),hex(module_base+module_size)))

    # 扫描内存
    ref = dbg.scan_memory_any(module_base,module_size,"55 8b ec ??")
    if ref != False:
        print("找到内存: {}".format(hex(ref)))
    dbg.close()

运行如上所示的代码片段,则默认会扫描进程内第一个模块也就是主程序模块内的,特征55 8b ec ??指令集,当找到后会输出如下图所示的提示信息;

4.6 x64dbg 内存扫描与查壳实现

如上代码中的内存扫描方法如果能被读者理解,那么查壳这个功能就变得很简单了,市面上的查壳软件PEID等基本都是采用特征码定位的方式,所以我们想要实现查壳以及检测编译器特征可以采用特征码扫描法,只需要将上述代码更改一下,即可实现查壳功能。

from LyScript32 import MyDebug

# 查壳功能
def Scan(dbg, string):
    # 得到进程模块
    local_module = dbg.get_all_module()[0]

    # 得到模块参数
    module_base = local_module.get("base")
    module_size = local_module.get("size")
    # print("基地址: {} 长度: {} 结束地址: {}".format(hex(module_base),hex(module_size),hex(module_base+module_size)))

    # 扫描内存
    ref = dbg.scan_memory_any(module_base,module_size,string)
    if ref != False:
        return True
    return False

if __name__ == "__main__":
    dbg = MyDebug()
    conn = dbg.connect()

    # 存储特征码
    signs = [
        {"key": "Microsoft Visual C++ 2013", "value": "e8 ?? ?? ?? ?? e9 ?? ?? ?? ?? 55 8b ec"},
        {"key": "UPX 3.96w", "value": "60 be ?? ?? ?? ?? 8d be 00 90 ff ff 57"}
    ]

    for index in signs:
        check = Scan(dbg, index.get("value"))
        if check == True:
            print("编译特征: {}".format(index.get("key")))

    dbg.close()

当运行上述代码片段,则将会寻找特定指令集,如果找到则说明采用的是特定的加壳程序或特定编译器编译生成的,输出效果图如下所示;

4.6 x64dbg 内存扫描与查壳实现

通过运用scan_memory_one()函数,读者何以很容易的实现对特定内存区域的寻找,以32为代码为例,通过get_register函数获取到当前EIP的内存地址,并通过read_memory_word读入前四个字节的数据,当前四个字节的数据为0xBE60此时说明是UPX壳的开头,通过scan_memory_one("83 EC ?? E9")匹配特征码,当找到后顺势在此处set_breakpoint(patternAddr)下一个断点,程序通过不断地运行,最终即可定位到程序真正的入口地址;

from LyScript32 import MyDebug

if __name__ == "__main__":
    # 初始化
    dbg = MyDebug()

    # 连接到调试器
    connect_flag = dbg.connect()
    print("连接状态: {}".format(connect_flag))

    # 检测套接字是否还在
    ref = dbg.is_connect()
    print("是否在连接: ", ref)

    is_64 = False

    # 判断是否时64位数
    if is_64 == False:
        currentIP = dbg.get_register("eip")

        if dbg.read_memory_word(currentIP) != int(0xBE60):
            print("[-] 可能不是UPX")
            dbg.close()

        patternAddr = dbg.scan_memory_one("83 EC ?? E9")
        print("匹配到的地址: {}".format(hex(patternAddr)))

        dbg.set_breakpoint(patternAddr)
        dbg.set_debug("Run")
        dbg.set_debug("Wait")
        dbg.delete_breakpoint(patternAddr)

        dbg.set_debug("StepOver")
        dbg.set_debug("StepOver")
        print("[+] 程序OEP = 0x{:x}".format(dbg.get_register("eip")))

    else:
        currentIP = dbg.get_register("rip")

        if dbg.read_memory_dword(currentIP) != int(0x55575653):
            print("[-] 可能不是UPX")
            dbg.close()

        patternAddr = dbg.scan_memory_one("48 83 EC ?? E9")
        print("匹配到的地址: {}".format(hex(patternAddr)))

        dbg.set_breakpoint(patternAddr)
        dbg.set_debug("Run")
        dbg.set_debug("Wait")
        dbg.delete_breakpoint(patternAddr)

        dbg.set_debug("StepOver")
        dbg.set_debug("StepOver")
        print("[+] 程序OEP = 0x{:x}".format(dbg.get_register("eip")))

    dbg.close()

运行上述代码片段,则会看到如下图所示的输出效果,并以自动跳转到了程序的真正入口位置0x40153e,此时用户只需要脱壳转存即可;

4.6 x64dbg 内存扫描与查壳实现文章来源地址https://www.toymoban.com/news/detail-537449.html

到了这里,关于4.6 x64dbg 内存扫描与查壳实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 4.9 x64dbg 内存处理与差异对比

    LyScript 插件中针对内存读写函数的封装功能并不多,只提供了最基本的 内存读取 和 内存写入 系列函数的封装,本章将继续对API接口进行封装,实现一些在软件逆向分析中非常实用的功能,例如ShellCode代码写出与置入,内存交换,内存区域对比,磁盘与内存镜像比较,内存特

    2024年02月16日
    浏览(40)
  • 逆向学习X64DBG

    目标游戏:焰影神兵 目的:更改玩家名称(中文名称) 使用X64dbg可以快速搜索游戏人名,所以本次逆向使用该工具进行工作。  原来的名字:平家物语  现在我们想改成:源氏物语。所以打开X32/64dbg 附加后,选择shadowFlare。 点击 内存映射   右键, 点击 \\\"查找特征码\\\"    然

    2024年02月01日
    浏览(42)
  • 4.5 x64dbg 探索钩子劫持技术

    钩子劫持技术是计算机编程中的一种技术,它们可以让开发者拦截系统函数或应用程序函数的调用,并在函数调用前或调用后执行自定义代码,钩子劫持技术通常用于病毒和恶意软件,也可以让开发者扩展或修改系统函数的功能,从而提高软件的性能和增加新功能。 4.5.1 探索

    2024年02月13日
    浏览(41)
  • 1.1 熟悉x64dbg调试器

    x64dbg 是一款开源、免费、功能强大的动态反汇编调试器,它能够在 Windows 平台上进行应用程序的反汇编、调试和分析工作。与传统的调试器如 Ollydbg 相比,x64dbg调试器的出现填补了 Ollydbg 等传统调试器的不足,为反汇编调试工作提供了更高效、更可靠的解决方案。正是因为有

    2024年02月12日
    浏览(38)
  • 4.4 x64dbg 绕过反调试保护机制

    在Windows平台下,应用程序为了保护自己不被调试器调试会通过各种方法限制进程调试自身,通常此类反调试技术会限制我们对其进行软件逆向与漏洞分析,下面是一些常见的反调试保护方法: IsDebuggerPresent:检查当前程序是否在调试器环境下运行。 OutputDebugString:向调试器发

    2024年02月12日
    浏览(37)
  • 4.10 x64dbg 反汇编功能的封装

    LyScript 插件提供的反汇编系列函数虽然能够实现基本的反汇编功能,但在实际使用中,可能会遇到一些更为复杂的需求,此时就需要根据自身需要进行二次开发,以实现更加高级的功能。本章将继续深入探索反汇编功能,并将介绍如何实现反汇编代码的检索、获取上下一条代

    2024年02月13日
    浏览(43)
  • OllyDbg 与 x64Dbg 与 Windbg 与 IDA 区别是什么?

    OllyDbg 和 x64Dbg 大致属于同一类别。它们的主要优势是在没有符号信息的情况下进行调试(尽管它们也可以使用符号信息进行调试)。OllyDbg(封闭源代码)已经很久没有维护了,并且仅限于 x86 32 位。另一方面,x64Dbg 被积极维护,开源并且可以处理 x86 和 x64。两者都支持插件

    2024年02月08日
    浏览(41)
  • win10 x64实现内存注入DLL

    1:win10最新版本 2:vs2019 dll配置环境 一:属性–链接器–常规–启用增量链接:否 二:属性–链接器–高级–随机地址:否 固定基址:是 三:属性–c/c+±-代码生成–基本运行时检查:默认值 安全检查:禁用安全检查(G/S) 注入成功后会创建一个线程打印:jinrule字符串 不

    2024年02月12日
    浏览(36)
  • getKernel32Address自实现(x64下写法)

    注意事项: UNICODE_STRING* FullName;这个结构体要用到#include ntdef.h,但是我们已经包含了#include windows.h,一个内核级的一个windows的,那么会有很多函数重定义,会有重合,所以我们不要直接#include ntdef.h,而是使用将需要的复制出来单独写一个头文件 比如这样,我将需要的全部写

    2024年02月11日
    浏览(35)
  • (超详细版)树莓派4b烧录Ubuntu Desktop 22.04 LTS (x64)+换清华源+安装VScode+安装Todesk并实现远程控制

    提前准备 树莓派4b TF卡 读卡器 显示器(支持HDMI接口) 键鼠(USB接口) 下载 Raspberry Pi Imager           这里选择对应你电脑系统的版本        开始烧录 !!! 注意 !!!         先连接显示器再上电(pi不支持热拔插)         如果不明白如何操作,请参考 树小

    2024年03月13日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包