#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;
}

c++ x86_x64挂钩函数 传递寄存器表的更多相关文章

  1. python 函数传递参数的多种方法

    python中函数根据是否有返回值可以分为四种:无参数无返回值,无参数有返回值,有参数无返回值,有参数有返回值. Python中函数传递参数的形式主要有以下五种,分别为位置传递,关键字传递,默认值传递 ...

  2. sql:除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询

    执行sql语句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date ...

  3. C++向main函数传递参数的方法(实例已上传至github)

    通常情况下,我们定义的main函数都只有空形参列表: int main(){...} 然而,有时我们确实需要给mian传递实参,一种常见的情况是用户设置一组选项来确定函数所要执行的操作.例如,假定ma ...

  4. scrapy回调函数传递参数

    scrapy.Request 的callback传参的两种方式 1.使用 lambda方式传递参数 def parse(self, response): for sel in response.xpa ...

  5. linux中probe函数传递参数的寻找(下)

    点击打开链接 linux中probe函数传递参数的寻找(下) 通过追寻driver的脚步,我们有了努力的方向:只有找到spi_bus_type的填充device即可,下面该从device去打通,当两个 ...

  6. SQL Server -- 回忆笔记(二):增删改查,修改表结构,约束,关键字使用,函数,多表联合查询

    SQL Server知识点回忆篇(二):增删改查,修改表结构,约束,关键字使用,函数,多表联合查询 1. insert 如果sql server设置的排序规则不是简体中文,必须在简体中文字符串前加N, ...

  7. Delphi过程函数传递参数的几种方式

    Delphi过程函数传递参数的几种方式  在Delphi过程.函数中传递参数几个修饰符为Const.Var.Out. 另一种不加修饰符的为默认按值传递参数. 一.默认方式以值方式传递参数 proced ...

  8. CreateThread给线程函数传递的参数

      HANDLE WINAPI CreateThread ( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指向SECURITY_ATTR ...

  9. flask 在视图函数中验证表单

    在视图函数中验证表单 因为现在的basic_form视图同时接受两种类型的请求:GET请求和POST请求.所以我们要根据请求方法的不同执行不同的代码.具体来说,首先是实例化表单,如果是GET请求,就渲 ...

随机推荐

  1. 题解 P1248 【加工生产调度】

    题目 某工厂收到了 n 个产品的订单,这 n 个产品分别在 A.B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工. 某个产品 i 在 A.B 两车间加工的时间分别为 Ai,Bi 怎 ...

  2. 前端基础之html学习一:

    网站的建站流程 页面图例 网页的结构 WEB标准 WEB标准是网页制作的标准,它不是一个标准,它是根据网页的不同组成部分生成的一系列标准.这些标准大部分由W3C起草发布,也有部分标准由ECMA起草发布 ...

  3. WinformGDI+入门级实例——扫雷游戏(附源码)

    写在前面: 本文将作为一个入门级的.结合源码的文章,旨在为刚刚接触GDI+编程或对相关知识感兴趣的读者做一个入门讲解.游戏尚且未完善,但基本功能都有,完整源码在文章结尾的附件中. 整体思路: 扫雷的游 ...

  4. MiniProfiler性能分析工具— .Net Core中用法

    前言: 在日常开发中,应用程序的性能是我们需要关注的一个重点问题.当然我们有很多工具来分析程序性能:如:Zipkin等:但这些过于复杂,需要单独搭建. MiniProfiler就是一款简单,但功能强大 ...

  5. 小希的迷宫B - B

    上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了 ...

  6. 搜索Ex (洛谷提高历练地)

    搜索Ex P1120 小木棍 题意:不超过65根长度小于50的小木棍(是由一批等长木棍砍断得到的),求原始木棍的最小可能长度 分析:优化+减枝爆搜 搜索状态要记录当前尝试的已经填好的长度,当前尝试填的 ...

  7. HHKB Programming Contest 2020【ABCE】

    比赛链接:https://atcoder.jp/contests/hhkb2020/tasks A - Keyboard 代码 #include <bits/stdc++.h> using ...

  8. 2019牛客多校 Round7

    Solved:5 Rank:296 E Find the median (线段树) 题意:最开始一个空的数组 4e5次操作 每次把Li,Ri中的每个数插入进来 问当前的中位数 题解:把这n个区间离散化 ...

  9. hdu4770 Lights Against Dudely

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  10. LianLianKan HDU - 4272 状压dp

    题意:长度为n(n<=1000)的栈,栈顶元素可以与下面1~5个数中相同的元素消去,问最后能都完全消去. 题解: 比如这个序列12345678910112这个位置的最远可匹配位置能到11为什么呢 ...