Cracker Drive 开发文档

核心特性

✔ 全系统兼容
  • Windows 7/10/11 全系统
  • 支持32位/64位系统架构
  • 支持AMD/Intel全平台
✔ 性能优化
  • 内核级通信加速
  • 多线程并发处理
  • 智能内存管理

安全规范

重要提醒
  • 需以管理员权限运行
  • 禁止修改内核签名
  • 使用前请关闭内核隔离功能

Cracker - S 使用示例

C++ 调用示例
#include "CrackerUserCall.h"

int main()
{
    // 1 ------------ 初始化用户调用部分 ------------
    printf("[ Cracker ] 开始初始化用户调用部分.\n");
    if (!Cracker_InitUserCall()) {
        printf("[ Cracker ] 用户调用部分初始化失败, 可能是网络问题或者被拦截!\n");
        system("pause");
        return 0;
    }
    printf("[ Cracker ] 初始化用户调用部分成功.\n");

    // -----------------------------------------------

    // 1+ ------------ (可选)可以在登陆平台前获取机器码, 来绑定自己的验证, 避免多余的扣费 ------------
    char MachineCodeBuffer[32]{};                                          //本节可选
    int MachineCodeStatus = Cracker_GetMachineFeature(MachineCodeBuffer);      //本节可选
    if (MachineCodeStatus != 0x0A000001) {                                 //本节可选
        printf("[ Cracker ] 机器码获取失败, 错误代码 %x!\n", MachineCodeStatus); //本节可选
        system("pause");                                                   //本节可选
        return 0;                                                          //本节可选
    }                                                                      //本节可选
    printf("[ Cracker ] 用户机器码: %s\n", MachineCodeBuffer);                       //本节可选
    // -----------------------------------------------

    // 2 ------------ 通过SecretKey登录平台 ------------
    printf("[ Cracker ] 开始登录平台.\n");
    int CrackerStatus = Cracker_InitAppKey("key"); // 这里请填写自己的SecretKey
    if (CrackerStatus != 0x0A000001) {
        printf("[ Cracker ] 平台登录失败, 错误代码 %x!\n", CrackerStatus);
        system("pause");
        return 0;
    }
    printf("[ Cracker ] 登录平台成功.\n");
    // -----------------------------------------------

    // 3 ------------ 选择平台中的应用进行安装 ------------
    printf("[ Cracker ] 接下来开始功能演示, 请按下任意键\n");
    system("pause");
    // ------------ CrackerDriver(Cracker驱动) 安装 ------------
    printf("[ Cracker ] 开始安装 Cracker驱动\n");
    int AppStatus = Cracker_Install();
    if (AppStatus != 0x0A000001) {
        printf("[ Cracker ] Cr Driver 安装失败, 错误代码 %x!\n", AppStatus);
        system("pause");
        return 0;
    }
    printf("[ Cracker ] 安装 Cracker驱动 成功\n");
    // -----------------------------------------------
    
    // ------------ CrackerDriver(Cracker驱动) 设置进程 ------------
    // 重点: 所有针对进程的操作前请设置进程,第二个参数为是否需要解密CR3
    printf("[ Cracker ] 开始设置进程\n");
    if (!Cracker_SetProcess(GetCurrentProcessId(), true)) {
        printf("[Cracker] 设置进程失败!\n");
        system("pause");
        return 0;
    }
    printf("[ Cracker ] 设置进程成功\n");
    // -----------------------------------------------

    // ------------ CrackerDriver(Cracker驱动) 获取PEB ------------
    // 如果你不知道Peb是什么, 说明这个函数对你无用, 可以忽略这条演示!
    printf("[ Cracker ] 当前进程 Peb -> %llx\n", Cracker_GetProcessEnvironmentBlock());
    // -----------------------------------------------

    // ------------ CrackerDriver(Cracker驱动) 获取模块地址 ------------
    // 这里分两种: 获取主进程exe模块地址 和 获取其他模块地址
    // 要取主进程exe模块地址时尽可能用 Cracker_GetMainModuleBase (最可靠的方式), 获取其他模块地址时尽可能用 Cracker_GetModuleAddress 物理内存方式(第二个参数false)
    // 实在取不到的情况下再设置 Cracker_GetModuleAddress 第二个参数为true(虚拟内存也就是附加方式)
    // Cracker_GetModuleAddress 第三个参数 要取64位进程的模块地址用true, 32位用false
    __int64 MainModule = Cracker_GetMainModuleBase();
    printf("[ Cracker ] 当前进程 主模块 -> %llx\n", MainModule);
    // 64位第三个填true, 32位填false
    // Method=0 Mapping, Method=1 附加 Method=2 刷页
    __int64 NtdllModule = Cracker_GetModuleAddress("ntdll.dll", 0, true);
    printf("[ Cracker ] 当前进程 ntdll.dll -> %llx\n", NtdllModule);

    // ------------ CrackerDriver(Cracker驱动) 读写物理内存 ------------
    // 最可靠稳定的读写方式
    int Target = 0; int Src = 0;
    Target = 0; Src = 0xB8;
    printf("[ Cracker ] 读物理内存\n");
    Cracker_ReadPhysicalMemory((__int64)&Src, &Target, sizeof(int));
    printf("Target -> %x, Src -> %x\n", Target, Src);

    Target = 0xB8; Src = 0;
    printf("[ Cracker ] 写物理内存\n");
    Cracker_WritePhysicalMemory((__int64)&Src, &Target, sizeof(int));
    printf("Target -> %x, Src -> %x\n", Target, Src);

    // 如果你需要强写(写入只读内存) 请使用下面的函数
    Target = 0xB8; Src = 0;
    printf("[ Cracker ] 强写物理内存\n");
    Cracker_WritePhysicalMemory_X((__int64)&Src, &Target, sizeof(int));
    printf("Target -> %x, Src -> %x\n", Target, Src);
    // -----------------------------------------------

    // ------------ CrackerDriver(Cracker驱动) 读写虚拟内存 ------------
    // 附加(虚拟内存)读写方式, 这种方式会被进程发现, 但可以让进程中已经进入磁盘的内存重新回到物理内存中, 有时有奇效
    // 如果你不了解这个函数的作用, 请勿轻易使用
    Target = 0; Src = 0xB8;
    printf("[ Cracker ] 读虚拟内存\n");
    Cracker_ReadVirtualMemory((__int64)&Src, &Target, sizeof(int));
    printf("Target -> %x, Src -> %x\n", Target, Src);

    Target = 0xB8; Src = 0;
    printf("[ Cracker ] 写虚拟内存\n");
    Cracker_WriteVirtualMemory((__int64)&Src, &Target, sizeof(int));
    printf("Target -> %x, Src -> %x\n", Target, Src);
    // -----------------------------------------------

     // ------------ CrackerDriver(Cracker驱动) CR3方式读写内存 ------------
    // 附加(虚拟内存)读写方式, 这种方式会被进程发现, 但可以让进程中已经进入磁盘的内存重新回到物理内存中, 有时有奇效
    // 如果你不了解这个函数的作用, 请勿轻易使用
    Target = 0; Src = 0xB8;
    printf("[ Cracker ] 读CR3内存\n");
    Cracker_ReadPagefulMemory((__int64)&Src, &Target, sizeof(int));
    printf("Target -> %x, Src -> %x\n", Target, Src);

    Target = 0xB8; Src = 0;
    printf("[ Cracker ] 写CR3内存\n");
    Cracker_WritePagefulMemory((__int64)&Src, &Target, sizeof(int));
    printf("Target -> %x, Src -> %x\n", Target, Src);
    // -----------------------------------------------

    // ------------ CrackerDriver(Cracker驱动) 申请/修改属性/释放虚拟内存 ------------
    // 和ZwAllocateVirtualMemory等系统函数用法完全一致.
    
    ULONG64 AllocateMem = 0; // 预期的申请地址 可以为0, 如果为0则地址由系统决定
    ULONG64 AllocateSize = 0x1000; // 预期的申请大小, 实际大小由系统决定并返回

    Cracker_AllocateMemory(&AllocateMem, &AllocateSize, MEM_COMMIT | MEM_RESERVE, 4);
    printf("[ Cracker ] 申请得到的地址: %p, 大小: 0x%llx\n", AllocateMem, AllocateSize);

    UINT OldProtect = 0;
    Cracker_ProtectMemory(&AllocateMem, &AllocateSize, PAGE_EXECUTE_READ, &OldProtect);
    printf("[ Cracker ] 修改地址 %p 内存属性为 PAGE_EXECUTE_READ 原本的内存属性为 %x\n", AllocateMem, OldProtect);

    Cracker_FreeMemory(&AllocateMem, &AllocateSize, MEM_RELEASE);
    printf("[ Cracker ] 释放已经申请的地址: %p, 大小: 0x%llx\n", AllocateMem, AllocateSize);

    // ------------ CrackerDriver(Cracker驱动) 鼠标移动 ------------
    printf("[ Cracker ] 接下来开始内核鼠标移动, 可能导致蓝屏, 请演示前备份数据.\n");
    system("pause");
    Cracker_MouseMove(100, 100);
    // -----------------------------------------------

    // ------------ CrackerDriver(Cracker驱动) 获取内核模块地址 ------------
    // 如果你不了解这个函数的作用, 请勿轻易使用
    ULONG64 win32k = Cracker_GetKernelModuleAddress("win32k.sys");
    printf("[ Cracker ] win32k.sys 的模块地址位于 %llx\n", win32k);
    // -----------------------------------------------

    // ------------ CrackerDriver(Cracker驱动) 读写内核内存 ------------
    // 如果你不了解这个函数的作用, 请勿轻易使用
    Target = 0;
    Cracker_ReadKernelMemory(win32k, &Target, sizeof(int));
    printf("[ Cracker ] win32k.sys 的模块地址处的内存为 %x\n", Target);
    // -----------------------------------------------

    printf("[ Cracker ] 演示完毕\n");
    system("pause");
}

Cracker - S 申请内存 · 使用示例

易语言 调用示例
.版本 2
.支持库 spec

.程序集 启动
.程序集变量 演示进程名, 文本型
.程序集变量 驱动授权密钥, 文本型

.子程序 _启动子程序, 整数型

驱动授权密钥 = “Key”
演示进程名 = “Dwm.exe”
.如果 (信息框 (“你是否是新手?”, #是否钮, “内存操作Demo”, ) = #是钮)
    新手操作 ()
.否则
    大佬操作 ()
.如果结束
返回 (0)  ' 可以根据您的需要返回任意数值

.子程序 新手操作
.局部变量 结果_安装驱动, 逻辑型
.局部变量 ProcessID, 整数型
.局部变量 结果_申请地址, 长整数型
.局部变量 结果_写入内存, 逻辑型
.局部变量 结果_读取内存, 字节集
.局部变量 结果_修改保护, 逻辑型
.局部变量 结果_释放内存, 逻辑型

' --------------------以下来演示一下CRACKER - S申请内存,以及申请内存后如何进行读写操作,以解决各位用户遇到的问题-------------------------
' -
' -
' --------------------第一步(安装驱动) - 演示驱动 CrAcker - S ---------------------
结果_安装驱动 = Drv.驱动_安装驱动 (驱动授权密钥)
.如果 (结果_安装驱动)
    标准输出 (, “[ √ ] 驱动安装成功” + #换行符)
.否则
    标准输出 (, “[ × ] 驱动安装失败 按回车键退出测试程序...” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
' --------------------到这里驱动就安装成功了可以进行下一步操作---------------------
' -
' -
' --------------------获取目标进程ProcessID (Pid)并绑定进程 这里我们以Dwm.exe为例---------------------
ProcessID = 进程_名取ID (演示进程名)
.如果 (ProcessID ≠ 0)
    .如果 (Drv.初始化_设置进程 (ProcessID, 假))
        标准输出 (, “[ √ ] 设置进程成功 ProcessID = >” + 到文本 (ProcessID) + #换行符)
    .否则
        标准输出 (, “[ × ] 设置进程失败,按回车键退出测试程序....” + #换行符)
        标准输入 ()
        结束 ()
    .如果结束

.否则
    ' ---------------------这里没有取到进程ID----------------
    标准输出 (, “[ × ] 进程ProcessID获取失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
' --------------------到这里我们就完成了进程ProcessID绑定操作---------------------
' -
' -
' --------------------对目标进程进行申请内存操作,详细操作与VirtualProtect函数一致---------------------
' 新手操作方式↓
结果_申请地址 = Drv.内存_申请内存 (0, 4096, 位或 (#MEM_COMMIT, #MEM_RESERVE), #PAGE_EXECUTE_READWRITE)
.如果 (结果_申请地址 ≠ 0)
    标准输出 (, “[ √ ] 申请内存成功 内存地址 = >” + 到文本 (结果_申请地址) + “十六 = >” + 十到十六 (结果_申请地址) + #换行符)
.否则
    标准输出 (, “[ × ] 申请内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
' --------------------到这里我们申请内存就操作成功了---------------------
' -
' -
' --------------------接下来我们来演示如何对申请到的地址进行读写操作---------------------
' 对申请到的地址首次进行内存读写操作需要所以(Virtual = >操作虚拟内存方式)
' 因为在内存结构中首次申请到的内存在物理内存页(页表)中是不存在的
' 所以首次我们只能所以操作虚拟内存的方式对内存地址进行操作
结果_写入内存 = Drv.内存_写字节集Virtual (结果_申请地址, { 144, 144 })
.如果 (结果_写入内存)
    标准输出 (, “[ √ ] (虚拟)写入内存成功” + #换行符)
.否则
    标准输出 (, “[ × ] (虚拟)写入内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
' 进行读取操作
结果_读取内存 = Drv.内存_读字节集Virtual (结果_申请地址, 2)
.如果 (结果_读取内存 ≠ { 0, 0 })
    标准输出 (, “[ √ ] (虚拟)读取内存成功 = >” + 字节集_字节集到十六进制 (结果_读取内存) + #换行符)
.否则
    标准输出 (, “[ × ] (虚拟)读取内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束

结果_读取内存 = Drv.内存_读字节集 (结果_申请地址, 2)  ' 已经操作过虚拟内存了,所以申请的内存在物理内存页也存在了,现在可以用任何读写方式进行操作
.如果 (结果_读取内存 ≠ { 0, 0 })
    标准输出 (, “[ √ ] (物理)读取内存成功 = >” + 字节集_字节集到十六进制 (结果_读取内存) + #换行符)
.否则
    标准输出 (, “[ × ] (物理)读取内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束

' --------------------到这里我们就学会了如何对申请到的地址进行 读/写 操作---------------------
' -
' -
' --------------------接下来我们演示如何修改内存属性---------------------
结果_修改保护 = Drv.内存_修改内存属性 (结果_申请地址, 4096, #PAGE_NOACCESS)  ' 修改属性为不可读写
.如果 (结果_修改保护)
    标准输出 (, “[ √ ] 修改内存属性成功” + #换行符)
.否则
    标准输出 (, “[ × ] 修改内存属性失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束

结果_读取内存 = Drv.内存_读字节集Virtual (结果_申请地址, 2)  ' 我们在进行一下读取操作看看修改的内存属性是否有效果
.如果 (结果_读取内存 ≠ { 0, 0 })
    标准输出 (, “[ × ] 读取内存成功 = >” + 字节集_字节集到十六进制 (结果_读取内存) + #换行符)
.否则
    标准输出 (, “[ √ ] 读不到!就对了!” + #换行符)
.如果结束

' --------------------CrAcker - S 内存基础操作演示完毕 可以释放内存了---------------------
结果_释放内存 = Drv.内存_释放内存 (结果_申请地址, 4096, 位或 (#MEM_COMMIT, #MEM_RESERVE))
.如果 (结果_释放内存)
    标准输出 (, “[ √ ] 释放内存成功 操作测试完毕,按回车键退出Demo” + #换行符)
.否则
    标准输出 (, “[ × ] 释放内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()

.如果结束

标准输入 ()
结束 ()

.子程序 大佬操作
.局部变量 结果_安装驱动, 逻辑型
.局部变量 ProcessID, 整数型
.局部变量 结果_预期大小, 长整数型
.局部变量 结果_申请地址, 长整数型
.局部变量 结果_写入内存, 逻辑型
.局部变量 结果_读取内存, 字节集
.局部变量 结果_修改保护, 逻辑型
.局部变量 结果_旧的属性, 长整数型
.局部变量 结果_修改大小, 长整数型
.局部变量 结果_修改地址, 长整数型
.局部变量 结果_释放内存, 逻辑型

' --------------------以下来演示一下CRACKER - S全系列申请内存,以及申请内存后如何进行读写操作,以解决各位用户遇到的问题-------------------------
' -
' -
' --------------------第一步(安装驱动) - 演示驱动 CrAcker - S ---------------------
结果_安装驱动 = Drv.驱动_安装驱动 (驱动授权密钥)
.如果 (结果_安装驱动)
    标准输出 (, “[ √ ] 驱动安装成功” + #换行符)
.否则
    标准输出 (, “[ × ] 驱动安装失败 按回车键退出测试程序...” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
' --------------------到这里驱动就安装成功了可以进行下一步操作---------------------
' -
' -
' --------------------获取目标进程ProcessID (Pid)并绑定进程 这里我们以Dwm.exe为例---------------------
ProcessID = 进程_名取ID (演示进程名)
.如果 (ProcessID ≠ 0)
    .如果 (Drv.初始化_设置进程 (ProcessID, 假))
        标准输出 (, “[ √ ] 设置进程成功 ProcessID = >” + 到文本 (ProcessID) + #换行符)
    .否则
        标准输出 (, “[ × ] 设置进程失败,按回车键退出测试程序....” + #换行符)
        标准输入 ()
        结束 ()
    .如果结束

.否则
    ' ---------------------这里没有取到进程ID----------------
    标准输出 (, “[ × ] 进程ProcessID获取失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
' --------------------到这里我们就完成了进程ProcessID绑定操作---------------------
' -
' -
' --------------------对目标进程进行申请内存操作,详细操作与VirtualProtect函数一致---------------------
' 新手操作方式↓
结果_申请地址 = 0
结果_预期大小 = 4096
Drv.内存_申请内存Variable (取变量数据地址 (结果_申请地址), 取变量数据地址 (结果_预期大小), 位或 (#MEM_COMMIT, #MEM_RESERVE), #PAGE_EXECUTE_READWRITE)
.如果 (结果_申请地址 ≠ 0)
    标准输出 (, “[ √ ] 申请内存成功 内存地址 = > ” + 到文本 (结果_申请地址) + “ 十六 = > ” + 十到十六 (结果_申请地址) + #换行符)
.否则
    标准输出 (, “[ × ] 申请内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
' --------------------到这里我们申请内存就操作成功了---------------------
' -
' -
' --------------------接下来我们来演示如何对申请到的地址进行读写操作---------------------
' 对申请到的地址首次进行内存读写操作需要所以(Virtual = >操作虚拟内存方式)
' 因为在内存结构中首次申请到的内存在物理内存页(页表)中是不存在的
' 所以首次我们只能所以操作虚拟内存的方式对内存地址进行操作
结果_写入内存 = Drv.内存_写字节集Virtual (结果_申请地址, { 144, 144 })
.如果 (结果_写入内存)
    标准输出 (, “[ √ ] (虚拟)写入内存成功” + #换行符)
.否则
    标准输出 (, “[ × ] (虚拟)写入内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
' 进行读取操作
结果_读取内存 = Drv.内存_读字节集Virtual (结果_申请地址, 2)
.如果 (结果_读取内存 ≠ { 0, 0 })
    标准输出 (, “[ √ ] (虚拟)读取内存成功 = > ” + 字节集_字节集到十六进制 (结果_读取内存) + #换行符)
.否则
    标准输出 (, “[ × ] (虚拟)读取内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束

结果_读取内存 = Drv.内存_读字节集 (结果_申请地址, 2)  ' 已经操作过虚拟内存了,所以申请的内存在物理内存页也存在了,现在可以用任何读写方式进行操作
.如果 (结果_读取内存 ≠ { 0, 0 })
    标准输出 (, “[ √ ] (物理)读取内存成功 = > ” + 字节集_字节集到十六进制 (结果_读取内存) + #换行符)
.否则
    标准输出 (, “[ × ] (物理)读取内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束

' --------------------到这里我们就学会了如何对申请到的地址进行 读/写 操作---------------------
' -
' -
' --------------------接下来我们演示如何修改内存属性---------------------
结果_修改地址 = 结果_申请地址
结果_修改大小 = 4096
结果_修改保护 = Drv.内存_修改内存属性Variable (取变量数据地址 (结果_修改地址), 取变量数据地址 (结果_修改大小), #PAGE_NOACCESS, 取变量数据地址 (结果_旧的属性))  ' 修改属性为不可读写
.如果 (结果_修改保护)
    标准输出 (, “[ √ ] 修改内存属性成功 先前属性 = > ” + 到文本 (结果_旧的属性) + “ 修改地址 = > ” + 到文本 (结果_修改地址) + #换行符)
.否则
    标准输出 (, “[ × ] 修改内存属性失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束

结果_读取内存 = Drv.内存_读字节集Virtual (结果_申请地址, 2)  ' 我们在进行一下读取操作看看修改的内存属性是否有效果
.如果 (结果_读取内存 ≠ { 0, 0 })
    标准输出 (, “[ × ] 读取内存成功 = >” + 字节集_字节集到十六进制 (结果_读取内存) + #换行符)
.否则
    标准输出 (, “[ √ ] 读不到!就对了!” + #换行符)
.如果结束

' --------------------CrAcker - S 内存基础操作演示完毕 可以释放内存了---------------------
结果_释放内存 = Drv.内存_释放内存 (结果_申请地址, 4096, 位或 (#MEM_COMMIT, #MEM_RESERVE))
.如果 (结果_释放内存)
    标准输出 (, “[ √ ] 释放内存成功 操作测试完毕,按回车键退出Demo” + #换行符)
.否则
    标准输出 (, “[ × ] 释放内存失败,按回车键退出测试程序....” + #换行符)
    标准输入 ()
    结束 ()
.如果结束
标准输入 ()
结束 ()