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;
}
c++ x86_x64挂钩函数 传递寄存器表的更多相关文章
- python 函数传递参数的多种方法
python中函数根据是否有返回值可以分为四种:无参数无返回值,无参数有返回值,有参数无返回值,有参数有返回值. Python中函数传递参数的形式主要有以下五种,分别为位置传递,关键字传递,默认值传递 ...
- sql:除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询
执行sql语句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date ...
- C++向main函数传递参数的方法(实例已上传至github)
通常情况下,我们定义的main函数都只有空形参列表: int main(){...} 然而,有时我们确实需要给mian传递实参,一种常见的情况是用户设置一组选项来确定函数所要执行的操作.例如,假定ma ...
- scrapy回调函数传递参数
scrapy.Request 的callback传参的两种方式 1.使用 lambda方式传递参数 def parse(self, response): for sel in response.xpa ...
- linux中probe函数传递参数的寻找(下)
点击打开链接 linux中probe函数传递参数的寻找(下) 通过追寻driver的脚步,我们有了努力的方向:只有找到spi_bus_type的填充device即可,下面该从device去打通,当两个 ...
- SQL Server -- 回忆笔记(二):增删改查,修改表结构,约束,关键字使用,函数,多表联合查询
SQL Server知识点回忆篇(二):增删改查,修改表结构,约束,关键字使用,函数,多表联合查询 1. insert 如果sql server设置的排序规则不是简体中文,必须在简体中文字符串前加N, ...
- Delphi过程函数传递参数的几种方式
Delphi过程函数传递参数的几种方式 在Delphi过程.函数中传递参数几个修饰符为Const.Var.Out. 另一种不加修饰符的为默认按值传递参数. 一.默认方式以值方式传递参数 proced ...
- CreateThread给线程函数传递的参数
HANDLE WINAPI CreateThread ( __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指向SECURITY_ATTR ...
- flask 在视图函数中验证表单
在视图函数中验证表单 因为现在的basic_form视图同时接受两种类型的请求:GET请求和POST请求.所以我们要根据请求方法的不同执行不同的代码.具体来说,首先是实例化表单,如果是GET请求,就渲 ...
随机推荐
- LIS的优化
二分优化 在求一个最长不上升自序列中,显然其结尾元素越小,越有利于接其他元素,对答案的贡献也就可能会更高 那么我们可以用low[i]去存长度为i的LIS结尾元素的最小值 因此我们只要维护low数组 对 ...
- 数位dp 笔记
目录 数位dp 笔记 解决的问题 & 主体思想 入门 -- windy数 绕一个弯 -- 萌数 the end? -- 恨7不成妻 小心细节 [SDOI2016]储能表 复杂度起飞 [AHOI ...
- java关键字static使用总结
java关键字static使用总结 1.static修饰的方法被称之为静态方法也叫做类方法,加static的方法,可以通过类名直接访问,不加static的方法只能通过对象名访问. 静态方法可以直接通过 ...
- Language Guide (proto3) | proto3 语言指南(十三)JSON映射
JSON Mapping - JSON映射 Proto3支持JSON中的规范编码,使得在系统之间共享数据更加容易.下表按类型对编码进行了描述. 如果JSON编码的数据中缺少一个值或者它的值为null, ...
- svn安装步骤
我使用的是myeclipse 8.5 svn是site-1.8.22.zip 步骤 1.在myeclipse安装路径下dropins文件夹中创建svn文件夹 2.解压site-1.8.22.zip复 ...
- 织梦dedecms用户注册时笔名去掉的方法
修改目的:用户注册时不用输入笔名,实现系统自动同步用户名和用户笔名. 负责织梦dedecms用户注册的php文件是member/reg_new.php ,不难发现,用户注册时的用户名$userid,和 ...
- ThreadLocal全面解析,一篇带你入门
===================== 大厂面试题: 1.Java中的引用类型有哪几种? 2.每种引用类型的特点是什么? 3.每种引用类型的应用场景是什么? 4.ThreadLocal你了解吗 5 ...
- 设计模式(四)——Java抽象工厂模式
抽象工厂模式 1 基本介绍 1) 抽象工厂模式:定义了一个 interface 用于创建相关或有依赖关系的对象簇,而无需指明具体的类 2) 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合. 3) ...
- HDU - 3613 Best Reward(manacher或拓展kmp)
传送门:HDU - 3613 题意:给出26个字母的价值,然后给你一个字符串,把它分成两个字符串,字符串是回文串才算价值,求价值最大是多少. 题解:这个题可以用马拉车,也可以用拓展kmp. ①Mana ...
- 8.PowerShell DSC之Push
前言 LCM的默认mode就是push,所以对于push模式,我们直接就三步走 以下是示例: 1.编写配置 Authoring Configuration WebsiteTest { # Import ...