首页 > 系统相关 >4.3 x64dbg 搜索内存可利用指令

4.3 x64dbg 搜索内存可利用指令

时间:2023-07-07 19:22:21浏览次数:54  
标签:4.3 dbg 机器码 base 搜索 内存 缓冲区 x64dbg local

发现漏洞的第一步则是需要寻找到可利用的反汇编指令片段,在某些时候远程缓冲区溢出需要通过类似于jmp esp等特定的反汇编指令实现跳转功能,并以此来执行布置好的ShellCode恶意代码片段,LyScript插件则可以很好的完成对当前进程内存中特定函数的检索工作。

一般而言远程缓冲区溢出攻击通常利用的是一些具有缓冲区溢出漏洞的函数或是特定的汇编指令片段,如:

  • strcpy:该函数将一个字符串复制到另一个字符串缓冲区中,但不会检查缓冲区的大小,因此很容易导致缓冲区溢出。
  • gets:该函数将用户输入的数据读入字符串缓冲区中,但不会检查缓冲区的大小,因此很容易导致缓冲区溢出。
  • sprintf:该函数将一个字符串格式化到字符串缓冲区中,但不会检查缓冲区的大小,因此很容易导致缓冲区溢出。

在远程缓冲区溢出攻击中,攻击者也可以利用汇编指令jmp esp来实现对攻击代码的执行。该指令允许攻击者跳转到堆栈中的任意位置,并从那里执行恶意代码。

4.3.1 搜索可利用汇编指令集

在默认情况下,LyScript插件并不具备搜索连续指令的能力,虽然提供了get_disasm_code()系列的反汇编函数,但此类函数通常仅仅只能实现简单的反汇编功能,读者如果需要实现其他附加功能,含需要自行动手去实现,首先我们自行实现一个简单的汇编指令检索功能,用于寻找可利用的指令片段"pop esp","jmp esp","jmp eax","pop ecx"等指令集。

这段代码实现的机制可总结为如下步骤;

  • 1.调用connect函数来连接到要调试的程序,并使用get_local_baseget_local_size函数获取程序的内存范围。
  • 2.定义一个名为search_asm的列表,该列表包含要搜索的汇编指令。
  • 3.使用一个while循环来遍历内存范围中的每一个地址,并调用get_disasm_one_code函数获取该地址处的反汇编代码。
  • 4.使用另一个for循环来遍历search_asm列表中的每一个指令,并检查当前反汇编代码是否与列表中的指令匹配。如果匹配,则输出该地址和反汇编代码。

代码很容易被理解和实现,本质上仅仅只是提取所内存中所有的汇编指令集,并依次枚举对比是否符合列表中的条件,其最终实现代码如下所示;

from LyScript32 import MyDebug

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

    local_base_start = dbg.get_local_base()
    local_base_end = local_base_start + dbg.get_local_size()
    print("开始地址: {} --> 结束地址: {}".format(hex(local_base_start),hex(local_base_end)))

    search_asm = ["pop esp","jmp esp","jmp eax","pop ecx"]

    while local_base_start <= local_base_end:
        disasm = dbg.get_disasm_one_code(local_base_start)
        # print("地址: 0x{:08x} --> 反汇编: {}".format(local_base_start,disasm))

        # 寻找指令
        for index in range(0, len(search_asm)):
            if disasm == search_asm[index]:
                print("地址: {} --> 反汇编: {}".format(hex(local_base_start), disasm))

        # 递增计数器
        local_base_start = local_base_start + dbg.get_disasm_operand_size(local_base_start)

    dbg.close()

如上代码被运行后,则会输出当前进程内所有可被利用的指令片段,其输出效果图如下图所示;

4.3.2 搜索可利用机器码

机器码的搜索与汇编指令集的搜索方式基本保持一致,但庆幸的是搜索指令集可使用scan_memory_all()这个官方函数,该函数可用于扫描当前EIP所处位置,也就是当前EIP所在模块的所有符合条件的机器码,需要注意的是,在搜索具有漏洞函数时,通常我们会搜索进程内的完整模块,则此时应该先得到该模块的入口地址,并通过set_register()设置到该模块所在内存,然后再次对该内存区域进行搜索,代码中opcode用于指定一段机器码序列,此处读者可指定搜索多种机器码,并将搜索结果放入到该列表内进行存储。

这段代码的实现原理可总结为如下所示的步骤;

  • 定义一个名为opcode的列表,该列表包含要搜索的机器码。
  • 然后使用一个for循环来遍历每个模块,并调用get_all_module函数获取程序中的模块列表。对于每个模块,它将eip寄存器设置为该模块的入口点,然后调用scan_memory_all函数搜索该模块中是否存在要搜索的机器码。
  • 如果找到了指定的机器码,则输出模块名称、匹配个数以及机器码,并输出该机器码所在的地址。

根据上述流程可总结为如下所示的代码片段;

from LyScript32 import MyDebug
import time

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

    # 需要搜索的指令集片段
    opcode = ['ff 25','ff 55 fc','8b fe']

    # 循环搜索指令集内存地址
    for index,entry in zip(range(0,len(opcode)), dbg.get_all_module()):
        eip = entry.get("entry")
        base_name = entry.get("name")
        if eip != 0:
            dbg.set_register("eip",eip)
            search_address = dbg.scan_memory_all(opcode[index])

            if search_address != False:
                print("搜索模块: {} --> 匹配个数: {} --> 机器码: {}"
            .format(base_name,len(search_address),opcode[index]))
                # 输出地址
                for search_index in search_address:
                    print("[*] {}".format(hex(search_index)))

        time.sleep(0.3)
    dbg.close()

strcpy函数为例,读者只需要搜索特征['57 8b 7c 24 08 eb 6e','ff 55 fc','8b fe']即可定位到当前模块内所有调用该函数机器其他函数的内存地址。

运行后即可输出当前模块内所有被调用机器码的详细地址,输出效果如下图所示;

原文地址

https://www.lyshark.com/post/af00a46a.html

标签:4.3,dbg,机器码,base,搜索,内存,缓冲区,x64dbg,local
From: https://www.cnblogs.com/LyShark/p/17535906.html

相关文章

  • 程序的内存布局
    程序在内存空间上的布局如下图:代码段(.text):这里存放的是CPU要执行的指令,代码是可共享的,相同的代码在内存中只有一份拷贝,同时这个段是只读的,防止程序误修改指令。初始化数据段(.data):这里存放是是程序中需要明确赋初始值的变量,例如全局变量。代码段和初始化数据段都位于程序......
  • 熟悉x64dbg调试器的使用
    阅读目录1.1如何启动调试1.2熟悉x64dbg窗口1.3熟悉x64dbg断点1.4熟悉x64dbg代码跟踪原文链接x64dbg是一款开源、免费、功能强大的动态反汇编调试器,它能够在Windows平台上进行应用程序的反汇编、调试和分析工作。与传统的调试器如Ollydbg相比,x64dbg调试器的出现填......
  • C++内存模型&空指针、野指针、函数指针和回调函数
    C++内存模型&空指针、野指针、函数指针和回调函数C++内存模型栈与堆的区别:1.管理方式不同栈是系统自动管理的,在超出作用域后,将自动被释放堆是手动释放,若程序中不释放,程序结束后将由操作系统回收2.空间大小不同堆的大小受限于物理内存范围栈小的可怜,一般为8M(可通过更改......
  • CST电磁仿真软件配置的CPU、内存、显卡显存越大越好吗?
    CST电磁仿真软件是一款功能强大的工具,用于模拟和计算电磁场。然而,软件的性能不仅取决于软件本身的优化,还与计算机的硬件配置有很大的关系。尤其是在进行大规模电磁场仿真时,硬件配置的高低直接影响到计算速度和精度。  在CST电磁仿真软件的配置中,CPU、内存和显存都是非常重要......
  • 正点原子内存管理实验室,keil mdk 和stm32cubeide gcc的函数替换
    https://www.cnblogs.com/RegressionWorldLine/p/11968467.html转载记录下 STM32.ld链接文件分析及一次bug解决过程问题描述原子板的代码中含有一个关于使用外部SRAM的功能,由于本人的开发板的SRAM只有512K,因此稍微修改了一下代码,同时使用GCC进行编译,但是这里却报错了,源码如......
  • memreduct内存优化工具
    适用平台:windows下载地址运行截图托盘菜单支持多种功能......
  • 4.3 Recurrent Neural Network (RNN) II
    1.RNN怎么学习1.1LossFunction  如果要做learning的话,你要定义一个costfunction来evaluate你的model是好还是不好,选一个parameter要让你的loss最小.那在RecurrentNeuralNetwork里面,你会怎么定义这个loss呢,下面我们先不写算式,先直接举个例子.  如下图所示,这是一......
  • 堆内存
    堆内存  程序员手动管理,足够大,使用麻烦。  为什么使用堆内存:    1.复杂数据量增多。    2.其他内存段申请释放不受控制,堆内存可以控制。  malloc的内存管理机制:    1.当首次向malloc申请内存时,malloc会向操作系统申请堆内存,操作系统会......
  • JAVA 调试高内存占用与CPU满载异常场景
    高内存占用,堆溢出,OOM代码: @RequestMapping(value="/oom",method={RequestMethod.GET}) publicResultBasegetMessage2()throwsInterruptedException{ List<String>strList=Lists.newArrayList(); for(inti=0;i<10240;i++){ strLi......
  • tomcat Filter内存马
    idea调试的时候加入源代码<dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-catalina</artifactId><version>8.5.81</version><scope>provided</scope></dependency>Servlet、......