|
发表于 2025-4-1 15:29:38
|
显示全部楼层
河南省郑州市
本帖最后由 神行 于 2025-4-1 15:37 编辑
我给你提点建议吧
1.你使用了大量的硬编码汇编指令(置入代码),这些指令高度依赖x86架构和特定编译器生成的函数序言/结尾,而不同编译器或优化级别可能生成不同的函数开头/结尾模式
2.安全性问题:直接操作内存地址和机器码可能不安全,没有检查内存访问是否越界
3.变量使用问题:截取长度 变量在函数开始时声明,但实际值是在汇编代码中通过MOV DWORD [EBP-4],ECX设置的,这种隐式的变量赋值方式容易出错
4.第一段汇编代码在寻找函数入口点,跳过可能的跳转指令(0xE8), 第二段汇编代码在查找函数结尾的典型模式(恢复栈帧和返回指令), 第三段汇编代码处理无参数情况的返回指令(0xC3),这种技术通常用于低级编程或hook操作,但在实际使用环境中使用时需要非常非常谨慎。
这种技术通常用于低级编程或hook操作,但在生产环境中使用时需要非常谨慎
建议:添加错误检查机制,确保内存访问安全,考虑使用更可靠的方式确定函数边界,添加注释说明这种技术的限制和假设,如果可能,使用更高级的API来实现类似功能,检查子针到字节集函数是否能正确处理获取的长度
我基于你本来的逻辑,大致修改了一下,添加了一些必要的安全检查和错误处理,但是使用这种接近硬件或机器层面的代码编写手段在实际使用过程中依然存在很大风险,不建议实际中使用,特别是一些特别安全敏感的环境:
窗口程序集名 | 保 留 | 保 留 | 备 注 | 窗口程序集_启动窗口 | | | |
变量名 | 类 型 | 静态 | 数组 | 备 注 | 截取结果 | 字节集 | | | 安全标志 | 逻辑型 | | |
安全标志 = 假 截取结果 = 截取代码 (到整数 (&子程序 ), 安全标志 ) 如果真 (安全标志 ) 调试输出 ("安全截取成功", 取字节集长度 (截取结果 ), "字节" ).否则 信息框 ("函数截取失败,可能是不支持的函数格式或内存访问错误", 0, "错误", ).如果真结束 |
子程序 | 双精度小数型 | | |
参数一 | 整数型 | | | | 参数二 | 双精度小数型 | | | | 返回 (参数一 + 参数二 )变量名 | 类 型 | 静态 | 数组 | 备 注 | 截取长度 | 整数型 | | | 最大长度 | 整数型 | | | 起始地址 | 整数型 | | | 结束地址 | 整数型 | | |
是否安全 = 假 最大长度 = 4096 如果真 (截取地址 ≤ 0 或 截取地址 ≥ 2147483647 ) 返回 ({ }).如果真结束 起始地址 = 截取地址 置入代码 ({ 139, 69, 8, 128, 56, 85, 116, 19, 139, 77, 8, 65, 128, 57, 232, 117, 250, 139, 65, 1, 141, 92, 1, 5, 137, 93, 8 }) 如果真 (起始地址 ≤ 0 或 起始地址 ≥ 2147483647 ) 返回 ({ }).如果真结束 置入代码 ({ 139, 77, 8, 137, 77, 252, 139, 85, 12, 138, 17, 65, 128, 250, 139, 117, 243, 128, 121, 255, 229, 117, 238, 128, 121, 254, 93, 117, 231, 128, 121, 253, 194, 117, 7, 131, 193, 3, 137, 77, 252, 235, 18 }) 置入代码 ({ 128, 121, 253, 195, 117, 213, 131, 193, 3, 137, 77, 252 }) 截取长度 = 结束地址 - 起始地址 如果真 (截取长度 ≤ 0 或 截取长度 > 最大长度 ) 返回 ({ }).如果真结束 是否安全 = 真 返回 (指针到字节集 (起始地址, 截取长度 )) 
所以,为了你的CPU硬件安全,我对这个代码又进行了一次改进。这次不使用可以直接操作CPU指令的这些低级代码,大致思路,没有经过测试。
窗口程序集名 | 保 留 | 保 留 | 备 注 | 高级函数分析器 | | | | 变量名 | 类 型 | 数组 | 备 注 | 内存保护属性 | 整数型 | | 最大扫描长度 | 整数型 | | 最小函数长度 | 整数型 | |
内存保护属性 = 取内存保护属性 (GetCurrentProcess ()) 最大扫描长度 = 4096 最小函数长度 = 16 返回 真 |
安全截取函数代码 | 字节集 | | |
函数指针 | 整数型 | | | | 结果状态 | 整数型 | | | |
变量名 | 类 型 | 静态 | 数组 | 备 注 | 函数长度 | 整数型 | | | 内存信息 | 内存基本信息 | | | 安全缓冲区 | 字节集 | | | 如果真 (函数指针 ≤ 0 ) 结果状态 = 1 返回 ({ }) 内存信息 = 取内存信息 (函数指针 ) 如果真 (位与 (内存信息.保护, 内存保护属性.PAGE_READABLE ) = 0 ) 结果状态 = 2 返回 ({ }) 函数长度 = 智能分析函数长度 (函数指针 ) 如果真 (函数长度 < 最小函数长度 或 函数长度 > 最大扫描长度 ) 结果状态 = 3 返回 ({ }) 安全缓冲区 = 取空白字节集 (函数长度 )复制内存 (取变量数据地址 (安全缓冲区 ), 函数指针, 函数长度 ) 如果真 (校验字节集 (安全缓冲区 ) = 假) 结果状态 = 4 返回 ({ }) 结果状态 = 0 返回 安全缓冲区 变量名 | 类 型 | 静态 | 数组 | 备 注 | 当前地址 | 整数型 | | | 扫描计数器 | 整数型 | | | 指令分析器 | 整数型 | | |
当前地址 = 起始地址 指令分析器 = 创建指令分析器 () 判断循环首 (当前地址 - 起始地址 < 最大扫描长度 )扫描计数器 = 扫描计数器 + 1 如果 (分析指令 (指令分析器, 当前地址 ) = "RET" ) 如果 (验证函数结尾 (当前地址 )) 跳出循环 ()
如果真 (扫描计数器 = 1 且 分析指令 (指令分析器, 当前地址 ) ≠ "PUSH EBP" ) 当前地址 = 查找真实入口 (当前地址 ) 当前地址 = 当前地址 + 取指令长度 (指令分析器 )释放指令分析器 (指令分析器 ) 如果 (当前地址 - 起始地址 ≥ 最小函数长度 且 当前地址 - 起始地址 ≤ 最大扫描长度 ) 返回 (当前地址 - 起始地址 ) 返回 (0 ) 返回 (取字节集长度 (指针到字节集 (地址, 4 )) = 4 且 指针到字节集 (地址, 4 ) = { 139, 229, 93, 195 }) 当前地址 = 疑似地址 判断循环首 (当前地址 - 疑似地址 < 32 )  如果 (指针到字节集 (当前地址, 2 ) = { 85, 139 })  返回 (当前地址 )  当前地址 = 当前地址 + 1    判断循环尾 返回 (疑似地址 ) 计次循环首 (取字节集长度 (代码块 ), i ) 校验和 = 位异或 (校验和, 取字节集数据 (代码块, i, #字节型 ))  计次循环尾 返回 (校验和 ≠ 0 )
.子程序
|
|