|
|
本帖最后由 plshelloworld 于 2025-10-30 13:04 编辑
经过神秘修炼,冒险家逐渐掌握了特殊的战斗技巧,这些战斗技巧将赋予冒险家以下特性:
- “超强力量”,每20级提高1%触发的概率,增加一次攻击快速数量,增加1s持续时间。当触超强力量时,攻击间隔降低至10%,该效果在达到攻击次数达到或持续时间消失后结束。 内置冷却时间10s.
- “狂战士之血”,冒险家生命值每降低10%,相应的攻击间隔降低10%
- ~~“永恒”,冒险家在生命值低于1%时,会触发永恒效果,在接下来的5s内,任何伤害均不会导致死亡,内置冷却时间10s。~~
 
- #pragma once
- #include <thread>
- #include <chrono>
- #include"Hooks.h"
- class Dota2
- {
- public:
- static int ReadPointerSignedInt(ULONG ulBase, int iOffset) {
- __try { return *(LONG*)(*(ULONG*)ulBase + iOffset); }
- __except (EXCEPTION_EXECUTE_HANDLER) { return 0; }
- }
- static UINT8 readCharValueZtlSecureFuse(int at) {
- UINT8 result;
- try {
- UCHAR v2 = *(PUCHAR)at;
- at = *(PUINT8)(at + 1);
- result = at ^ v2;
- }
- catch (...) { return 0; }
- return result;
- }
- static void MakePageWritable(ULONG ulAddress, ULONG ulSize) {
- MEMORY_BASIC_INFORMATION* mbi = new MEMORY_BASIC_INFORMATION;
- VirtualQuery((PVOID)ulAddress, mbi, ulSize);
- if (mbi->Protect != PAGE_EXECUTE_READWRITE) {
- ULONG* ulProtect = new unsigned long;
- VirtualProtect((PVOID)ulAddress, ulSize, PAGE_EXECUTE_READWRITE, ulProtect);
- delete ulProtect;
- }
- delete mbi;
- }
- static void WriteMemory(ULONG ulAddress, ULONG ulAmount, ...) {
- va_list va;
- va_start(va, ulAmount);
- MakePageWritable(ulAddress, ulAmount);
- for (ULONG ulIndex = 0; ulIndex < ulAmount; ulIndex++)
- *(UCHAR*)(ulAddress + ulIndex) = va_arg(va, UCHAR);
- va_end(va);
- }
- static void Jump(ULONG ulAddress, PVOID Function, unsigned Nops) {
- MakePageWritable(ulAddress, Nops + 5);
- *(UCHAR*)ulAddress = 0xE9;
- *(ULONG*)(ulAddress + 1) = (int)(((int)Function - (int)ulAddress) - 5);
- memset((PVOID)(ulAddress + 5), 0x90, Nops);
- }
- public:
- // 静态函数启动定时器
- static void monitorAttackCount(int interval_ms = 100, int acceleration_probability = 20, int acceleration_cooldown_seconds = 10) {
- // 初始化随机数生成器
-
- std::srand(static_cast<unsigned int>(std::time(nullptr)));
- // 设置静态成员变量
- acceleration_probability_ = acceleration_probability;
- acceleration_cooldown_seconds_ = acceleration_cooldown_seconds;
- lastValue = -1;
- isAccelerating = false;
- // 设置定时器,每interval_ms毫秒调用一次TimerProc函数
- SetTimer(NULL, 1, interval_ms, (TIMERPROC)TimerProcStatic);
- // 程序结束时清除定时器
- KillTimer(NULL, 1);
- }
- private:
- // 存储必要的状态信息
- inline static int lastValue = -1;
- inline static bool isAccelerating = false;
- inline static std::chrono::steady_clock::time_point lastAccelerationTime;
- inline static int acceleration_probability_ = 20;
- inline static int acceleration_cooldown_seconds_ = 3;
- inline static ULONG UserLocalBaseex = 0xBEBF98;
- inline static ULONG OFS_AttackCount = 0x2B88;
- inline static ULONG attackDelayAddrex = 0x00454795;
- inline static int changeCount = 0;
- inline static const int maxChangeCount = 12;
- inline static ULONG CharacterStatBase = 0xBF3CD8;
- inline static ULONG OFS_Level = 0x33;
- inline static ULONG OFS_JobID = 0x39;
- inline static ULONG statHookAddr = 0x008D8581;
- inline static std::chrono::steady_clock::time_point lastTriggerTime;
- inline static std::atomic<bool> isUnyieldingActive;
- inline static std::atomic<bool> isTimerRunning;
- inline static std::atomic<bool> isAlive = true;
-
- // 定时器回调函数,静态成员函数
- static void CALLBACK TimerProcStatic(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
- TimerProc();
- TimerProcHSK();
- }
- #if 1
- //神灵武士
- static void TimerProcHSK() {
- int currentValue = ReadPointerSignedInt(UserLocalBaseex, OFS_AttackCount);
- //HP
- {
- Jump(statHookAddr, Assembly::StatHook, 0);
- if (Assembly::maxHP != 0) {
- double val = ((double)Assembly::curHP / Assembly::maxHP) * 100.0;
- ULONG targetValue = 0x01 + (ULONG)((val / 100.0) * 9);
- static ULONG previousTargetValue = 0x0A;
- if (targetValue != previousTargetValue) {
- previousTargetValue = targetValue;
- WriteMemory(attackDelayAddrex, 3, 0x83, 0xC0, previousTargetValue); //add ecx, [animDelay]
- }
- }
- }
- }
- #endif // 0
- //超强力量版本
- #if 1
- static void TimerProc() {
- int currentValue = ReadPointerSignedInt(UserLocalBaseex, OFS_AttackCount);
- //HP
- {
- Jump(statHookAddr, Assembly::StatHook, 0);
- if (Assembly::maxHP != 0) {
- double val = ((double)Assembly::curHP / Assembly::maxHP) * 100.0;
- // std::cout << " hp percent: " << val << "%" << std::endl;
- }
- }
- //获取玩家等级
- auto level = readCharValueZtlSecureFuse(*(ULONG*)CharacterStatBase + OFS_Level);
- // std::cout << "level: "<< (int)level << std::endl;
- if (currentValue != lastValue) {
- // 20%的概率打印 "加速"
- if (std::rand() % 100 < acceleration_probability_) {
- if (!isAccelerating || std::chrono::steady_clock::now() - lastAccelerationTime > std::chrono::seconds(acceleration_cooldown_seconds_)) {
-
- lastAccelerationTime = std::chrono::steady_clock::now(); // 更新加速时间
- isAccelerating = true; // 设置加速状态
- WriteMemory(attackDelayAddrex, 3, 0x83, 0xC0, 0x06); //add ecx, [animDelay]
- changeCount = 0;
- int maxCnt = level / 20;
- }
- }
- // 增加变化次数
- if (isAccelerating) {
- changeCount++;
- int maxCnt = level / 20;
- // 如果变化次数达到6次,则结束狂暴
- if (changeCount >= maxCnt) {
- //isAccelerating = false; // 结束狂暴
- // WriteMemory(attackDelayAddrex, 3, 0x83, 0xC0, 0x0A); // add eax, 0a
- //也许我应该把攻速调整至当前血量?
- //HP
- {
- Jump(statHookAddr, Assembly::StatHook, 0);
- if (Assembly::maxHP != 0) {
- double val = ((double)Assembly::curHP / Assembly::maxHP) * 100.0;
- ULONG targetValue = 0x01 + (ULONG)((val / 100.0) * 9);
- static ULONG previousTargetValue = 0x0A;
- if (targetValue != previousTargetValue) {
- previousTargetValue = targetValue;
- WriteMemory(attackDelayAddrex, 3, 0x83, 0xC0, previousTargetValue); //add ecx, [animDelay]
- }
- }
- }
- }
- }
- // 打印当前值
- lastValue = currentValue; // 更新上次的值
- }
- // 如果加速状态已经超过cooldown,允许再次触发"加速"
- if (isAccelerating && std::chrono::steady_clock::now() - lastAccelerationTime > std::chrono::seconds(acceleration_cooldown_seconds_)) {
- isAccelerating = false; // 重置加速状态
-
- // WriteMemory(attackDelayAddrex, 3, 0x83, 0xC0, 0x0A); //add eax,0a
- //HP
- {
- Jump(statHookAddr, Assembly::StatHook, 0);
- if (Assembly::maxHP != 0) {
- double val = ((double)Assembly::curHP / Assembly::maxHP) * 100.0;
- ULONG targetValue = 0x01 + (ULONG)((val / 100.0) * 9);
- static ULONG previousTargetValue = 0x0A;
- if (targetValue != previousTargetValue) {
- previousTargetValue = targetValue;
- WriteMemory(attackDelayAddrex, 3, 0x83, 0xC0, previousTargetValue); //add ecx, [animDelay]
- }
- }
- }
- }
- }
- #endif // 0
- };
复制代码 hooks.h 一些人物状态的hook
- #pragma once
- #include<Windows.h>
- #define CodeCaveEx(name) static void __declspec(naked) ##name() { _asm
- #define EndCodeCaveEx }
- namespace Assembly {
- extern ULONG curHP;
- extern ULONG maxHP;
- extern ULONG curMP;
- extern ULONG maxMP;
- extern ULONG curEXP;
- extern ULONG maxEXP;
- extern ULONG mapNameAddr;
- extern ULONG statHookAddr;
- extern ULONG statHookAddrRet;
- CodeCaveEx(StatHook) {
- push eax
- mov eax, [ebp + 0x08]
- mov[curHP], eax
- mov eax, [ebp + 0x0C]
- mov[maxHP], eax
- mov eax, [ebp + 0x10]
- mov[curMP], eax
- mov eax, [ebp + 0x14]
- mov[maxMP], eax
- mov eax, [ebp + 0x18]
- mov[curEXP], eax
- mov eax, [ebp + 0x1C]
- mov[maxEXP], eax
- pop eax
- lea ecx, [eax + eax * 0x4]
- cmp ecx, ebx
- jmp dword ptr[statHookAddrRet]
- } EndCodeCaveEx
- }
复制代码
补充一个遗漏的Hooks.cpp
- #include"Hooks.h"
- namespace Assembly {
- ULONG curHP = 0, maxHP = 0, curMP = 0, maxMP = 0, curEXP = 0, maxEXP = 0, mapNameAddr = 0x0;
- ULONG statHookAddr = 0x008D8581; //Inside CUIStatusBar::SetNumberValue
- ULONG statHookAddrRet = statHookAddr + 5;
- #pragma unmanaged
- /*CodeCaveEx(AnimDelay) {
- add eax, [animDelay]
- jmp dword ptr[animDelayAddrRet]
- } EndCodeCaveEx*/
-
- }
复制代码 |
评分
-
查看全部评分
|