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\n", regs->rax);
  printf("rbx: %x\n", regs->rbx);
  printf("rcx: %x\n", regs->rcx);
  printf("rdx: %x\n", regs->rdx);
  regs->eax = 100;
  *(DWORD*)(regs->rbx + 0x7F0) = regs->eax;
#else
  printf("eax: %x\n", regs->eax);
  printf("ebx: %x\n", regs->ebx);
  printf("ecx: %x\n", regs->ecx);
  printf("edx: %x\n", 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\n");

  // 钩住这里
  //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\n" // sub rsp,0xA0
    "48 89 44 24 20\n" // mov [rsp+0x20],rax
    "48 89 5C 24 28\n" // mov [rsp+0x28],rbx
    "48 89 4C 24 30\n" // mov [rsp+0x30],rcx
    "48 89 54 24 38\n" // mov [rsp+0x38],rdx
    "48 89 74 24 40\n" // mov [rsp+0x40],rsi
    "48 89 7C 24 48\n" // mov [rsp+0x48],rdi
    "48 89 6C 24 50\n" // mov [rsp+0x50],rbp
    "48 89 64 24 58\n" // mov [rsp+0x58],rsp
    "4C 89 44 24 60\n" // mov [rsp+0x60],r8
    "4C 89 4C 24 68\n" // mov [rsp+0x68],r9
    "4C 89 54 24 70\n" // mov [rsp+0x70],r10
    "4C 89 5C 24 78\n" // mov [rsp+0x78],r11
    "4C 89 A4 24 80 00 00 00\n" // mov [rsp+0x80],r12
    "4C 89 AC 24 88 00 00 00\n" // mov [rsp+0x88],r13
    "4C 89 B4 24 90 00 00 00\n" // mov [rsp+0x90],r14
    "4C 89 BC 24 98 00 00 00\n" // mov [rsp+0x98],r15
    // 2
    "48 8D 4C 24 20\n" // 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\n" // call rax
    "48 8B 44 24 20\n" // mov rax,[rsp+0x20]
    "48 8B 5C 24 28\n" // mov rbx,[rsp+0x28]
    "48 8B 4C 24 30\n" // mov rcx,[rsp+0x30]
    "48 8B 54 24 38\n" // mov rdx,[rsp+0x38]
    "48 8B 74 24 40\n" // mov rsi,[rsp+0x40]
    "48 8B 7C 24 48\n" // mov rdi,[rsp+0x48]
    "48 8B 6C 24 50\n" // mov rbp,[rsp+0x50]
    "48 8B 64 24 58\n" // mov rsp,[rsp+0x58]
    "4C 8B 44 24 60\n" // mov r8,[rsp+0x60]
    "4C 8B 4C 24 68\n" // mov r9,[rsp+0x68]
    "4C 8B 54 24 70\n" // mov r10,[rsp+0x70]
    "4C 8B 5C 24 78\n" // mov r11,[rsp+0x78]
    "4C 8B A4 24 80 00 00 00\n" // mov r12,[rsp+0x80]
    "4C 8B AC 24 88 00 00 00\n" // mov r13,[rsp+0x88]
    "4C 8B B4 24 90 00 00 00\n" // mov r14,[rsp+0x90]
    "4C 8B BC 24 98 00 00 00\n" // 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\n" // push esp
    "55\n" // push ebp
    "57\n" // push edi
    "56\n" // push esi
    "52\n" // push edx
    "51\n" // push ecx
    "53\n" // push ebx
    "50\n" // 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\n" // pop eax
    "5B\n" // pop ebx
    "59\n" // pop ecx
    "5A\n" // pop edx
    "5E\n" // pop esi
    "5F\n" // pop edi
    "5D\n" // 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 开启/关闭\n");
  while (!GetAsyncKeyState(VK_F12))
  {
    if (GetAsyncKeyState(VK_F4) & 1)
    {
      bEnable = !bEnable;
      if (bEnable)
      {
        printf("挂钩\n");
        // 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("脱钩\n");
        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;
}
posted @ 2020-09-05 17:57  Ajanuw  阅读(355)  评论(0编辑  收藏  举报