zoukankan      html  css  js  c++  java
  • c++ x86_x64挂钩函数 传递寄存器表

    #include "pch.h"
    #include <iostream>
    #include <Windows.h>
    #include "GameCheat.h"
    
    using namespace std;
    
    struct Regs
    {
    #ifdef _WIN64
      union
      {
        uint64_t rax;
        DWORD eax;
        WORD ax;
        // BYTE ah; // *(BYTE*)((BYTE*)(&r.ax) + 1)
        BYTE al;
      };
      uintptr_t rbx;
      uintptr_t rcx;
      uintptr_t rdx;
      uintptr_t rsi;
      uintptr_t rdi;
      uintptr_t rbp;
      uintptr_t rsp;
      uintptr_t r8;
      uintptr_t r9;
      uintptr_t r10;
      uintptr_t r11;
      uintptr_t r12;
      uintptr_t r13;
      uintptr_t r14;
      uintptr_t r15;
    #else
      uintptr_t eax;
      uintptr_t ebx;
      uintptr_t ecx;
      uintptr_t edx;
      uintptr_t esi;
      uintptr_t edi;
      uintptr_t ebp;
      uintptr_t esp;
    #endif // _WIN64
    
    };
    
    void __stdcall myHook(Regs* regs)
    {
    #ifdef _WIN64
      printf("rax: %x
    ", regs->rax);
      printf("rbx: %x
    ", regs->rbx);
      printf("rcx: %x
    ", regs->rcx);
      printf("rdx: %x
    ", regs->rdx);
      regs->eax = 100;
      *(DWORD*)(regs->rbx + 0x7F0) = regs->eax;
    #else
      printf("eax: %x
    ", regs->eax);
      printf("ebx: %x
    ", regs->ebx);
      printf("ecx: %x
    ", regs->ecx);
      printf("edx: %x
    ", regs->edx);
      regs->eax = 99;
      *(DWORD*)(regs->ebx + 0x4AC) = regs->eax;
    #endif // _WIN64
    }
    
    DWORD WINAPI MyThread(HMODULE hModule)
    {
    
    #ifdef _WIN64
      GameCheat gc{ "Tutorial-x86_64.exe" };
    #else
      GameCheat gc{ "Tutorial-i386.exe" };
    #endif // _WIN64
    
      FILE* f;
      gc.openConsole(&f);
      printf("INJECT OK
    ");
    
      // 钩住这里
      //x64 Tutorial-x86_64.exe+2B08C - 29 83 F0070000 - sub [rbx+000007F0],eax
      //x86 Tutorial-i386.exe+2578F - 29 83 AC040000 - sub [ebx+000004AC],eax
    
    #ifdef _WIN64
      BYTE* addr = (BYTE*)gc.mi.lpBaseOfDll + 0x2B08C;
      vector<BYTE> copyBytes = GameCheat::byteStr2Bytes("29 83 F0 07 00 00");
      BYTE* lpAddress = (BYTE*)gc.mi.lpBaseOfDll - 0x10000;
    #else
      BYTE* addr = (BYTE*)gc.mi.lpBaseOfDll + 0x2578F;
      vector<BYTE> copyBytes = GameCheat::byteStr2Bytes("29 83 AC 04 00 00");
      BYTE* lpAddress = 0;
    #endif // _WIN64
    
      BYTE* newHook = (BYTE*)VirtualAlloc(lpAddress, 500, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
      size_t position = 0;
    
    #ifdef _WIN64
      // 使用堆栈大小
      // 4*8=32=0x20
      // 16*8=128=0x80
      // 32+128=160=0xA0
    
      /*
     global Start
    section .text
        ; 1
      sub rsp,0xA0
      mov [rsp+0x20],rax
      mov [rsp+0x28],rbx
      mov [rsp+0x30],rcx
      mov [rsp+0x38],rdx
      mov [rsp+0x40],rsi
      mov [rsp+0x48],rdi
      mov [rsp+0x50],rbp
      mov [rsp+0x58],rsp
      mov [rsp+0x60],r8
      mov [rsp+0x68],r9
      mov [rsp+0x70],r10
      mov [rsp+0x78],r11
      mov [rsp+0x80],r12
      mov [rsp+0x88],r13
      mov [rsp+0x90],r14
      mov [rsp+0x98],r15
    
      ; 2
      lea rcx,[rsp+0x20]
      mov rax,myHook
      call rax
    
      ; 3
      mov rax,[rsp+0x20]
      mov rbx,[rsp+0x28]
      mov rcx,[rsp+0x30]
      mov rdx,[rsp+0x38]
      mov rsi,[rsp+0x40]
      mov rdi,[rsp+0x48]
      mov rbp,[rsp+0x50]
      mov rsp,[rsp+0x58]
      mov r8,[rsp+0x60]
      mov r9,[rsp+0x68]
      mov r10,[rsp+0x70]
      mov r11,[rsp+0x78]
      mov r12,[rsp+0x80]
      mov r13,[rsp+0x88]
      mov r14,[rsp+0x90]
      mov r15,[rsp+0x98]
      add rsp,0xA0
    
    myHook:
      */
    
      // 1
      string bytesStr1 = "48 81 EC A0 00 00 00
    " // sub rsp,0xA0
        "48 89 44 24 20
    " // mov [rsp+0x20],rax
        "48 89 5C 24 28
    " // mov [rsp+0x28],rbx
        "48 89 4C 24 30
    " // mov [rsp+0x30],rcx
        "48 89 54 24 38
    " // mov [rsp+0x38],rdx
        "48 89 74 24 40
    " // mov [rsp+0x40],rsi
        "48 89 7C 24 48
    " // mov [rsp+0x48],rdi
        "48 89 6C 24 50
    " // mov [rsp+0x50],rbp
        "48 89 64 24 58
    " // mov [rsp+0x58],rsp
        "4C 89 44 24 60
    " // mov [rsp+0x60],r8
        "4C 89 4C 24 68
    " // mov [rsp+0x68],r9
        "4C 89 54 24 70
    " // mov [rsp+0x70],r10
        "4C 89 5C 24 78
    " // mov [rsp+0x78],r11
        "4C 89 A4 24 80 00 00 00
    " // mov [rsp+0x80],r12
        "4C 89 AC 24 88 00 00 00
    " // mov [rsp+0x88],r13
        "4C 89 B4 24 90 00 00 00
    " // mov [rsp+0x90],r14
        "4C 89 BC 24 98 00 00 00
    " // mov [rsp+0x98],r15
        // 2
        "48 8D 4C 24 20
    " // lea rcx,[rsp+0x20]
        "48 B8"; // mov rax,
    
      vector<BYTE> bytes1 = GameCheat::byteStr2Bytes(bytesStr1);
      memcpy_s(newHook + position, bytes1.size(), bytes1.data(), bytes1.size());
      position += bytes1.size();
    
      *(uintptr_t*)(newHook + position) = (uintptr_t)myHook; // myHook
      position += sizeof(uintptr_t);
    
      // 3
      string bytesStr2 = "FF D0
    " // call rax
        "48 8B 44 24 20
    " // mov rax,[rsp+0x20]
        "48 8B 5C 24 28
    " // mov rbx,[rsp+0x28]
        "48 8B 4C 24 30
    " // mov rcx,[rsp+0x30]
        "48 8B 54 24 38
    " // mov rdx,[rsp+0x38]
        "48 8B 74 24 40
    " // mov rsi,[rsp+0x40]
        "48 8B 7C 24 48
    " // mov rdi,[rsp+0x48]
        "48 8B 6C 24 50
    " // mov rbp,[rsp+0x50]
        "48 8B 64 24 58
    " // mov rsp,[rsp+0x58]
        "4C 8B 44 24 60
    " // mov r8,[rsp+0x60]
        "4C 8B 4C 24 68
    " // mov r9,[rsp+0x68]
        "4C 8B 54 24 70
    " // mov r10,[rsp+0x70]
        "4C 8B 5C 24 78
    " // mov r11,[rsp+0x78]
        "4C 8B A4 24 80 00 00 00
    " // mov r12,[rsp+0x80]
        "4C 8B AC 24 88 00 00 00
    " // mov r13,[rsp+0x88]
        "4C 8B B4 24 90 00 00 00
    " // mov r14,[rsp+0x90]
        "4C 8B BC 24 98 00 00 00
    " // mov r15,[rsp+0x98]
        "48 81 C4 A0 00 00 00"; // add rsp,0xA0
      vector<BYTE> bytes2 = GameCheat::byteStr2Bytes(bytesStr2);
      memcpy_s(newHook + position, bytes2.size(), bytes2.data(), bytes2.size());
      position += bytes2.size();
    
    #else
      // 使用堆栈大小
    
    /*
    global Start
    section .text
      ; 1
      push esp
      push ebp
      push edi
      push esi
      push edx
      push ecx
      push ebx
      push eax
    
      ; 2
      push esp
      call myHook
    
      ; 3
      pop eax
      pop ebx
      pop ecx
      pop edx
      pop esi
      pop edi
      pop ebp
      add esp,0x04
    
    myHook:
    
    */
    
      // 1
      string bytesStr1 = "54
    " // push esp
        "55
    " // push ebp
        "57
    " // push edi
        "56
    " // push esi
        "52
    " // push edx
        "51
    " // push ecx
        "53
    " // push ebx
        "50
    " // push eax
        "54";  // push esp
    
      vector<BYTE> bytes1 = GameCheat::byteStr2Bytes(bytesStr1);
      memcpy_s(newHook + position, bytes1.size(), bytes1.data(), bytes1.size());
      position += bytes1.size();
    
      // call myHook
      DWORD callMyHookBytes = (BYTE*)myHook - (newHook + position) - 5;
      *(newHook + position) = 0xE8;
      position += sizeof(BYTE);
      *(DWORD*)(newHook + position) = callMyHookBytes;
      position += sizeof(DWORD);
    
    
    
      // 3
      string bytesStr2 = "58
    " // pop eax
        "5B
    " // pop ebx
        "59
    " // pop ecx
        "5A
    " // pop edx
        "5E
    " // pop esi
        "5F
    " // pop edi
        "5D
    " // pop ebp
        "83 C4 04"; // add esp,0x04
    
      vector<BYTE> bytes2 = GameCheat::byteStr2Bytes(bytesStr2);
      memcpy_s(newHook + position, bytes2.size(), bytes2.data(), bytes2.size());
      position += bytes2.size();
    
    #endif // _win64
    
      // 拷贝盗取的字节,看情况也可以不要
      /*
      memcpy_s(newHook + position, copyBytes.size(), copyBytes.data(), copyBytes.size());
      position += copyBytes.size();
      */
    
      // return
      DWORD jmpReturnBytes = (addr + copyBytes.size()) - (newHook + position) - 5;
      *(newHook + position) = 0xE9;
      position += sizeof(BYTE);
      *(DWORD*)(newHook + position) = jmpReturnBytes;
    
      DWORD jmpHookBytes = newHook - addr - 5;
      bool bEnable = false;
      printf("  F4 开启/关闭
    ");
      while (!GetAsyncKeyState(VK_F12))
      {
        if (GetAsyncKeyState(VK_F4) & 1)
        {
          bEnable = !bEnable;
          if (bEnable)
          {
            printf("挂钩
    ");
            // Tutorial-x86_64.exe+2B08C >> jmp newHook
            DWORD oldProc;
            VirtualProtect(addr, copyBytes.size(), PAGE_EXECUTE_READWRITE, &oldProc);
            memset(addr, 0x90, copyBytes.size());
            *addr = 0xE9;
            *(DWORD*)(addr + 1) = jmpHookBytes;
            VirtualProtect(addr, copyBytes.size(), oldProc, 0);
          }
          else
          {
            printf("脱钩
    ");
            DWORD oldProc;
            VirtualProtect(addr, copyBytes.size(), PAGE_EXECUTE_READWRITE, &oldProc);
            memcpy_s(addr, copyBytes.size(), copyBytes.data(), copyBytes.size());
            VirtualProtect(addr, copyBytes.size(), oldProc, 0);
          }
        }
        Sleep(10);
      }
    
      VirtualFree(newHook, 0, MEM_RELEASE);
      gc.closeConsole(f);
      FreeLibraryAndExitThread(hModule, 0);
      return 0;
    }
    
    BOOL APIENTRY DllMain(HMODULE hModule,
      DWORD  ul_reason_for_call,
      LPVOID lpReserved
    )
    {
      switch (ul_reason_for_call)
      {
      case DLL_PROCESS_ATTACH:
        CloseHandle(CreateThread(0, 0, (LPTHREAD_START_ROUTINE)MyThread, hModule, 0, 0));
      case DLL_THREAD_ATTACH:
      case DLL_THREAD_DETACH:
      case DLL_PROCESS_DETACH:
        break;
      }
      return TRUE;
    }
    
  • 相关阅读:
    php安全模式笔记
    ./configure,make,make install的作用(转)
    composer自动载入类库的方式
    Specified key was too long; max key length is 1000 bytes
    海量数据中找出前k大数(topk问题)
    斐波那契数列n项的值。(递归和非递归算法Golang实现)
    基于Docker和Golang搭建Web服务器
    Nginx简单介绍以及linux下使用Nginx进行负载均衡的搭建
    php实现商城秒杀
    一致性hash (PHP)
  • 原文地址:https://www.cnblogs.com/ajanuw/p/13619022.html
Copyright © 2011-2022 走看看