杀软静态对抗-去除敏感整数

admin 2025年3月3日09:40:14评论2 views字数 2669阅读8分53秒阅读模式

PE文件中,一些固定的整数也可能是一种静态特征,比如比较特定的整数大小,API hash的值等等。我们也可以使用类似字符串的加解密方法,来实现编译时加密整数,运行时解密。

下面是一个GitHub上不错的项目,crystr https://github.com/android1337/crystr,介绍其中的crynum和crynum_long,并测试实际效果。

以下代码分析部分由Grok3生成,这里不得说一句,大模型的发展确实提高了工作的效率。

crynum 和 crynum_long 是两个用于加密数字的宏,它们基于 crys::cryNum 模板类实现。它们的主要区别在于支持的数字类型和加密方式的细节。下是对这两个宏的详细解析:

1. crynum 宏

定义

#define crynum(num) []() {     constexpr thread_local auto val = num;     constexpr static auto const_str = crys::cryNum         <const_hash(__DATE__ __TIME__, __COUNTER__), decltype(val)>(std::bit_cast<unsigned int, decltype(val)>(num));     return const_str; }()
  • 功能
    : 用于加密一个数字(通常是 32 位整数类型,如 int 或 unsigned int)。
  • 输入
    num 是需要加密的数字。
  • 返回
    : 返回一个 crys::cryNum 类的实例,封装了加密后的数字。

分解

  1. 匿名函数
    :
    • 使用 Lambda 表达式 []() 创建一个匿名函数,确保每次调用时返回的对象是独立的。
    • 返回值是一个 crys::cryNum 实例。
  1. 模板参数
    :
    • const_hash(__DATE__ __TIME__, __COUNTER__)
      : 生成一个编译期唯一的 64 位整数作为 uniqueid
      • __DATE__ __TIME__
        : 编译时的日期和时间字符串。
      • __COUNTER__
        : 编译器内置计数器,每次使用时递增。
    • decltype(val)
      : 推导 num 的类型(如 int 或 unsigned int)。
  1. 加密过程
    :
    • std::bit_cast<unsigned int, decltype(val)>(num)
      : 将输入的 num 转换为 32 位无符号整数。
    • 传递给 crys::cryNum 构造函数,执行加密。

使用示例

auto encrypted = crynum(42);int decrypted = encrypted.decrypt(); // 解密后得到 42
  • 输入 42 被加密为一个 cryNum 对象,调用 decrypt() 后返回原始值。

2. crynum_long 宏

定义

#define crynum_long(num) []() {     constexpr thread_local auto val = num;     constexpr static auto const_str = crys::cryNum         <const_hash(__DATE__ __TIME__, __COUNTER__), decltype(val)>(std::bit_cast<unsigned long long, decltype(val)>(num));     return const_str; }()
  • 功能
    : 用于加密一个长整数(通常是 64 位整数类型,如 long long 或 unsigned long long)。
  • 输入
    num 是需要加密的数字。
  • 返回
    : 返回一个 crys::cryNum 类的实例,封装了加密后的 64 位数字。

分解

  1. 匿名函数
    :
    • 与 crynum 相同,使用 Lambda 表达式封装加密逻辑。
  1. 模板参数
    :
    • const_hash(__DATE__ __TIME__, __COUNTER__)
      : 与 crynum 相同,生成唯一的 64 位 uniqueid
    • decltype(val)
      : 推导 num 的类型(如 long long 或 unsigned long long)。
  1. 加密过程
    :
    • std::bit_cast<unsigned long long, decltype(val)>(num)
      : 将输入的 num 转换为 64 位无符号整数。
    • 传递给 crys::cryNum 构造函数,执行加密。

使用示例

auto encrypted = crynum_long(12345678901234LL);long long decrypted = encrypted.decrypt(); // 解密后得到 12345678901234
  • 输入一个 64 位整数,被加密为 cryNum 对象,解密后返回原始值。

3. crys::cryNum 类的实现

crynum 和 crynum_long 都依赖于 crys::cryNum 模板类。以下是其核心实现:

模板参数

  • uniqueid
    : 编译期生成的唯一标识符。
  • T
    : 数字的类型(如 int 或 long long)。

构造函数

__forceinline constexpr cryNum(unsigned long long value){    // 生成密钥并加密 value    auto v = uniqueid * double((3.1415926535897932f / (180.f)) / 2.f);    auto y = v - (2.0f * 3.1415926535897932f) * double((0.31830988618f * 0.5f) * v + 0.5f);    // ... (复杂的数学运算生成 z 和 w)    data = value ^ std::bit_cast<unsigned long long>(z * y + w);}
  • 输入
    : 一个 64 位无符号整数 value(由宏中的 std::bit_cast 提供)。
  • 加密
    : 使用数学运算生成密钥,然后通过 XOR 将 value 加密,存储到 data

解密方法

__forceinline T decrypt(){    thread_local auto ret = xor_decrypt();    return *(T*)&ret;}
  • 调用 xor_decrypt(),返回解密后的 64 位值,再通过类型转换返回原始类型 T

密钥生成

  • get_xor_key()
    : 与构造函数类似,使用 uniqueid 通过三角函数近似生成相同的密钥。
  • xor_decrypt()
    : 使用密钥对 data 进行 XOR 操作,返回解密结果。

4. crynum 与 crynum_long 的区别

原文始发于微信公众号(红蓝对抗技战术):杀软静态对抗-去除敏感整数

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月3日09:40:14
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   杀软静态对抗-去除敏感整数https://cn-sec.com/archives/3786486.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息