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请求,就渲 ...
随机推荐
- Solon rpc 1.3.1 发布,推出Cloud接口与配置规范
Solon 是一个微型的Java RPC开发框架.项目从2018年启动以来,参考过大量前人作品:历时两年,3500多次的commit:内核保持0.1m的身材,超高的跑分,良好的使用体验.支持:Rpc. ...
- pycharm设置头文件模板(for mac)
我们要达到的效果是每次新建一个.py文件都会有头文件,关于头文件的作用之前已做解释
- 基于GTID恢复误篡改数据
问题描述:创建测试库和测试表,先update数据,在delete数据,在update数据,通过gtid查找两次update的值. 参考文档:https://baijiahao.baidu.com/s? ...
- 统一资源定位符 (URL)
统一资源标识符(uniform/universal resource identifier,URI)用于表示Internet中的资源(通常是文档).URI 主要用于两种目的,其一是命名资源,尽管此时把 ...
- 文本处理三剑客简介(grep、awk、sed)
本章内容: 命令 描述 awk 支持所有的正则表达式 sed 默认不支持扩展表达式,加-r 选项开启 ERE,如果不加-r 使用花括号要加转义符\{\} grep 默认不支持扩展表达式,加-E 选项开 ...
- 9. Linux用户身份和能力
root 拥有最高的系统所有权,能够管理系统的各项功能,如添加/删除用户.启动/关闭服务进程.开启/禁用硬件设备等.以root 管理员的身份工作时不会受到系统的限制 在Linux 系统中,UID 有唯 ...
- VIT Vision Transformer | 先从PyTorch代码了解
文章原创自:微信公众号「机器学习炼丹术」 作者:炼丹兄 联系方式:微信cyx645016617 代码来自github [前言]:看代码的时候,也许会不理解VIT中各种组件的含义,但是这个文章的目的是了 ...
- mysql高级day2
Mysql高级-day02 1. Mysql的体系结构概览 整个MySQL Server由以下组成 Connection Pool : 连接池组件 Management Services & ...
- XV6学习(10)锁
在包括XV6的绝大部分操作系统都是多个任务交错执行的.交错的一个原因是多核硬件:多核计算机的多个CPU核心独立执行计算,如XV6的RISC-V处理器.多个CPU核心共享物理内存,XV6利用这种共享来维 ...
- impala支持的数据库里的double(float)类型,通过迁移inceptor后,类型的值都变成了null
impala支持的数据库里的double(float)类型,通过迁移inceptor后,double类型的值都变成了null. 通过查阅日志发现默认将double转换成Decimal(38,10)然而 ...