LyScript 针对内存读写函数的封装功能并不多,只提供了内存读取和内存写入函数的封装,本篇文章将继续对API进行封装,实现一些在软件逆向分析中非常实用的功能,例如内存交换,内存区域对比,磁盘与内存镜像比较,特征码检索等功能。

LyScript项目地址:https://github.com/lyshark/LyScript

内存区域交换

实现被加载程序内特定一块内存区域的交换,该方法实现原理就是两个变量之间的交换,只是在交换时需要逐个字节进行,调用read_memory_byte()函数实现起了很容易。

from LyScript32 import MyDebug

# 交换两个内存区域
def memory_xchage(dbg,memory_ptr_x,memory_ptr_y,bytes):
    ref = False
    for index in range(0,bytes):
        # 读取两个内存区域
        read_byte_x = dbg.read_memory_byte(memory_ptr_x   index)
        read_byte_y = dbg.read_memory_byte(memory_ptr_y   index)

        # 交换内存
        ref = dbg.write_memory_byte(memory_ptr_x   index,read_byte_y)
        ref = dbg.write_memory_byte(memory_ptr_y   index, read_byte_x)
    return ref

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

    eip = dbg.get_register("eip")

    # 内存交换
    flag = memory_xchage(dbg, 6815744,6815776,4)
    print("内存交换状态: {}".format(flag))
    dbg.close()

PE文件头节点交换后如下:

内存区域对比

可用于对比该进程内存中的特定一块区域的差异,返回是列表中的字典形式,分别传入对比内存x,y以及需要对比的内存长度,此处建议不要超过1024字节。

from LyScript32 import MyDebug

# 对比两个内存区域
def memory_cmp(dbg,memory_ptr_x,memory_ptr_y,bytes):
    cmp_memory = []
    for index in range(0,bytes):

        item = {"addr":0, "x": 0, "y": 0}

        # 读取两个内存区域
        read_byte_x = dbg.read_memory_byte(memory_ptr_x   index)
        read_byte_y = dbg.read_memory_byte(memory_ptr_y   index)

        if read_byte_x != read_byte_y:
            item["addr"] = memory_ptr_x   index
            item["x"] = read_byte_x
            item["y"] = read_byte_y
            cmp_memory.append(item)
    return cmp_memory

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

    eip = dbg.get_register("eip")

    # 内存对比
    cmp_ref = memory_cmp(dbg, 6815744,6815776,4)
    for index in range(0,len(cmp_ref)):
        print("地址: 0x{:08X} -> X: 0x{:02x} -> y: 0x{:02x}".format(cmp_ref[index].get("addr"),cmp_ref[index].get("x"),cmp_ref[index].get("y")))

    dbg.close()

对比特定内存区域,返回差异字节地址:

内存与磁盘机器码比较

通过调用read_memory_byte()函数,或者open()打开文件,等就可以得到程序磁盘与内存中特定位置的机器码参数,然后通过对每一个列表中的字节进行比较,就可得到特定位置下磁盘与内存中的数据是否一致的判断。

#coding: utf-8
import binascii,os,sys
from LyScript32 import MyDebug

# 得到程序的内存镜像中的机器码
def get_memory_hex_ascii(address,offset,len):
    count = 0
    ref_memory_list = []
    for index in range(offset,len):
        # 读出数据
        char = dbg.read_memory_byte(address   index)
        count = count   1

        if count % 16 == 0:
            if (char) < 16:
                print("0"   hex((char))[2:])
                ref_memory_list.append("0"   hex((char))[2:])
            else:
                print(hex((char))[2:])
                ref_memory_list.append(hex((char))[2:])
        else:
            if (char) < 16:
                print("0"   hex((char))[2:]   " ",end="")
                ref_memory_list.append("0"   hex((char))[2:])
            else:
                print(hex((char))[2:]   " ",end="")
                ref_memory_list.append(hex((char))[2:])
    return ref_memory_list

# 读取程序中的磁盘镜像中的机器码
def get_file_hex_ascii(path,offset,len):
    count = 0
    ref_file_list = []

    with open(path, "rb") as fp:
        # file_size = os.path.getsize(path)
        fp.seek(offset)

        for item in range(offset,offset   len):
            char = fp.read(1)
            count = count   1
            if count % 16 == 0:
                if ord(char) < 16:
                    print("0"   hex(ord(char))[2:])
                    ref_file_list.append("0"   hex(ord(char))[2:])
                else:
                    print(hex(ord(char))[2:])
                    ref_file_list.append(hex(ord(char))[2:])
            else:
                if ord(char) < 16:
                    print("0"   hex(ord(char))[2:]   " ", end="")
                    ref_file_list.append("0"   hex(ord(char))[2:])
                else:
                    print(hex(ord(char))[2:]   " ", end="")
                    ref_file_list.append(hex(ord(char))[2:])
    return ref_file_list

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

    connect_flag = dbg.connect()
    print("连接状态: {}".format(connect_flag))

    module_base = dbg.get_base_from_address(dbg.get_local_base())
    print("模块基地址: {}".format(hex(module_base)))

    # 得到内存机器码
    memory_hex_byte = get_memory_hex_ascii(module_base,0,100)

    # 得到磁盘机器码
    file_hex_byte = get_file_hex_ascii("d://Win32Project1.exe",0,100)

    # 输出机器码
    print("\n内存机器码: ",memory_hex_byte)
    print("\n磁盘机器码: ",file_hex_byte)

    dbg.close()

读取后输出时会默认十六个字符一次换行,输出效果如下。

我们继续增加磁盘与内存对比过程,然后就能实现对特定内存区域与磁盘区域字节码一致性的判断。

#coding: utf-8
import binascii,os,sys
from LyScript32 import MyDebug

# 得到程序的内存镜像中的机器码
def get_memory_hex_ascii(address,offset,len):
    count = 0
    ref_memory_list = []
    for index in range(offset,len):
        # 读出数据
        char = dbg.read_memory_byte(address   index)
        count = count   1

        if count % 16 == 0:
            if (char) < 16:
                print("0"   hex((char))[2:])
                ref_memory_list.append("0"   hex((char))[2:])
            else:
                print(hex((char))[2:])
                ref_memory_list.append(hex((char))[2:])
        else:
            if (char) < 16:
                print("0"   hex((char))[2:]   " ",end="")
                ref_memory_list.append("0"   hex((char))[2:])
            else:
                print(hex((char))[2:]   " ",end="")
                ref_memory_list.append(hex((char))[2:])
    return ref_memory_list

# 读取程序中的磁盘镜像中的机器码
def get_file_hex_ascii(path,offset,len):
    count = 0
    ref_file_list = []

    with open(path, "rb") as fp:
        # file_size = os.path.getsize(path)
        fp.seek(offset)

        for item in range(offset,offset   len):
            char = fp.read(1)
            count = count   1
            if count % 16 == 0:
                if ord(char) < 16:
                    print("0"   hex(ord(char))[2:])
                    ref_file_list.append("0"   hex(ord(char))[2:])
                else:
                    print(hex(ord(char))[2:])
                    ref_file_list.append(hex(ord(char))[2:])
            else:
                if ord(char) < 16:
                    print("0"   hex(ord(char))[2:]   " ", end="")
                    ref_file_list.append("0"   hex(ord(char))[2:])
                else:
                    print(hex(ord(char))[2:]   " ", end="")
                    ref_file_list.append(hex(ord(char))[2:])
    return ref_file_list

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

    connect_flag = dbg.connect()
    print("连接状态: {}".format(connect_flag))

    module_base = dbg.get_base_from_address(dbg.get_local_base())
    print("模块基地址: {}".format(hex(module_base)))

    # 得到内存机器码
    memory_hex_byte = get_memory_hex_ascii(module_base,0,1024)

    # 得到磁盘机器码
    file_hex_byte = get_file_hex_ascii("d://Win32Project1.exe",0,1024)

    # 输出机器码
    for index in range(0,len(memory_hex_byte)):
        # 比较磁盘与内存是否存在差异
        if memory_hex_byte[index] != file_hex_byte[index]:
            # 存在差异则输出
            print("\n相对位置: [{}] --> 磁盘字节: 0x{} --> 内存字节: 0x{}".
                  format(index,memory_hex_byte[index],file_hex_byte[index]))
    dbg.close()

代码运行后即可输出,存在差异的相对位置:

内存ASCII码解析

通过封装的get_memory_hex_ascii得到内存机器码,然后再使用如下过程实现输出该内存中的机器码所对应的ASCII码。

from LyScript32 import MyDebug
import os,sys

# 转为ascii
def to_ascii(h):
    list_s = []
    for i in range(0, len(h), 2):
        list_s.append(chr(int(h[i:i 2], 16)))
    return ''.join(list_s)

# 转为16进制
def to_hex(s):
    list_h = []
    for c in s:
        list_h.append(hex(ord(c))[2:])
    return ''.join(list_h)

# 得到程序的内存镜像中的机器码
def get_memory_hex_ascii(address,offset,len):
    count = 0
    ref_memory_list = []
    for index in range(offset,len):
        # 读出数据
        char = dbg.read_memory_byte(address   index)
        count = count   1

        if count % 16 == 0:
            if (char) < 16:
                ref_memory_list.append("0"   hex((char))[2:])
            else:
                ref_memory_list.append(hex((char))[2:])
        else:
            if (char) < 16:
                ref_memory_list.append("0"   hex((char))[2:])
            else:
                ref_memory_list.append(hex((char))[2:])
    return ref_memory_list


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

    eip = dbg.get_register("eip")

    # 得到模块基地址
    module_base = dbg.get_base_from_address(dbg.get_local_base())

    # 得到指定区域内存机器码
    ref_memory_list = get_memory_hex_ascii(module_base,0,1024)

    # 解析ascii码
    break_count = 1
    for index in ref_memory_list:
        if break_count 2 == 0:
            print(to_ascii(hex(int(index, 16))[2:]))
        else:
            print(to_ascii(hex(int(index, 16))[2:]),end="")
        break_count = break_count   1

    dbg.close()

输出效果如下,如果换成中文,那就是一个中文搜索引擎了。

内存特征码匹配

通过二次封装get_memory_hex_ascii()实现扫描内存特征码功能,如果存在则返回True否则返回False。

from LyScript32 import MyDebug
import os,sys

# 得到程序的内存镜像中的机器码
def get_memory_hex_ascii(address,offset,len):
    count = 0
    ref_memory_list = []
    for index in range(offset,len):
        # 读出数据
        char = dbg.read_memory_byte(address   index)
        count = count   1

        if count % 16 == 0:
            if (char) < 16:
                ref_memory_list.append("0"   hex((char))[2:])
            else:
                ref_memory_list.append(hex((char))[2:])
        else:
            if (char) < 16:
                ref_memory_list.append("0"   hex((char))[2:])
            else:
                ref_memory_list.append(hex((char))[2:])
    return ref_memory_list


# 在指定区域内搜索特定的机器码,如果完全匹配则返回
def search_hex_ascii(address,offset,len,hex_array):
    # 得到指定区域内存机器码
    ref_memory_list = get_memory_hex_ascii(address,offset,len)

    array = []

    # 循环输出字节
    for index in range(0,len   len(hex_array)):

        # 如果有则继续装
        if len(hex_array) != len(array):
            array.append(ref_memory_list[offset   index])

        else:
            for y in range(0,len(array)):
                if array[y] != ref_memory_list[offset   index   y]:
                    return False

        array.clear()
    return False

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

    eip = dbg.get_register("eip")

    # 得到模块基地址
    module_base = dbg.get_base_from_address(dbg.get_local_base())
    
    re = search_hex_ascii(module_base,0,100,hex_array=["0x4d","0x5a"])
    
    dbg.close()

特征码扫描一般不需要自己写,自己写的麻烦,而且不支持通配符,可以直接调用我们API中封装好的scan_memory_one()它可以支持??通配符模糊匹配,且效率要高许多。

到此这篇关于LyScript实现内存交换与差异对比的方法详解的文章就介绍到这了,更多相关LyScript内存交换 对比内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

LyScript实现内存交换与差异对比的方法详解的更多相关文章

  1. Android中图片占用内存的深入分析

    我们在日常开发中应该经常思考这些问题,图片占用内存跟哪些东西有关?跟手机有关系么?这篇文章主要给大家介绍了关于Android中图片占用内存的相关资料,需要的朋友可以参考下

  2. LyScript实现Hook隐藏调试器的方法详解

    LyScript 插件集成的内置API函数可灵活的实现绕过各类反调试保护机制。本文将运用LyScript实现绕过大多数通用调试机制,实现隐藏调试器的目的,需要的可以参考一下

  3. php7和php5的详细对比

    这篇文章主要介绍了php7和php5详细对比,对此感兴趣的同学,可以自己研究下

  4. AJAX浅析数据交换的实现

    在AJAX中,最常用的就是JSON,XML因为比较冗杂所以用的比较少。所以我们先来说基于JSON的数据交换。最后我们还会提到在数据交换中出现乱码的形式

  5. IOS 调整内存中的图片大小实例详解

    这篇文章主要介绍了IOS 调整内存中的图片大小实例详解的相关资料,需要的朋友可以参考下

  6. 建立文件交换功能的脚本(一)

    因为工作的原因需要在局域网上安装一个文件交换的东西,也可以作成一个文件上下载的功能块。用的是php,mysql,apache现将程序编写过程贴出来,因为作这个参考来oso的一些文章,也算是一个补充,也表达我对前辈们的敬意。准备工作在你的mysql的yourdatabase库中建一个表upfile/*上传文件表CREATETABLEupfile*///这是该程序的主页面,用来显示上载的文件。//index.php文件交换

  7. PHP内存溢出的解决方法详解

    内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。本文为大家总结了PHP内存溢出的解决方法,需要的可以参考一下

  8. Android内存溢出及内存泄漏原因进解析

    这篇文章主要介绍了Android内存溢出及内存泄漏原因解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  9. CORBA对象生命周期之实现和内存管理

    显然,这个讨论和伺服对象的生命周期密切相关。不幸的是,这意味着瞬态Corba对象的生命周期紧密绑定到伺服对象的生命周期:瞬态Corba对象的创建必然导致伺服对象的立即激活,以实现对象。

  10. Java 对象在 JVM 中的内存布局超详细解说

    这篇文章主要介绍了Java 对象在 JVM 中的内存布局超详细解说,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部