上一个内容:45.使用hook点链表实现指定跳转
以 45.使用hook点链表实现指定跳转 它的代码为基础进行修改
此代码已实现无敌与秒杀功能
HOOKPOINT.h文件里的修改
#pragma once
typedef struct CPUINFO {
unsigned eflags;
unsigned edi;
unsigned esi;
unsigned ebp;
unsigned esp;
unsigned ebx;
unsigned edx;
unsigned ecx;
unsigned eax;
unsigned eip;
}*PCPUINFO;
typedef bool (*HOOKBACK)(PCPUINFO);
typedef unsigned char uchar;
typedef class HOOKPOINT
{
private:
// Address表示在哪进入外挂代码,也就是在什么地方做hook
LPVOID Address;
HOOKPOINT* NextPoint;
HOOKPOINT* BackPoint;
public:
// 外挂代码的地址
HOOKBACK DestCall;
// 修复区代码
char* CodeFix;
LPVOID AddressRet;
public:
HOOKPOINT();
~HOOKPOINT();
HOOKPOINT(LPVOID, LPVOID, HOOKBACK, uchar lenth, HOOKPOINT*, HOOKPOINT* _NextPoint = NULL);
HOOKPOINT* AddPonit(LPVOID, LPVOID, HOOKBACK, uchar lenth);
HOOKPOINT* FindPoint(LPVOID);
}*PHOOKPOINT;
HOOKPOINT.cpp文件里的修改
unsigned GetJMPCode(unsigned distance, unsigned eip);
HOOKPOINT::~HOOKPOINT()
{
delete CodeFix;
}
HOOKPOINT::HOOKPOINT(LPVOID _adr, LPVOID _adrRet, HOOKBACK _hbk, uchar lenth, HOOKPOINT* _BackP, HOOKPOINT* _NextPoint):
Address(_adr), AddressRet(_adrRet), DestCall(_hbk), BackPoint{ _BackP }, NextPoint{ _NextPoint }
{
CodeFix = new char[lenth + 0x5];
memcpy(CodeFix, _adr, lenth);
/**
下面是之前分析剑侠情缘用来无敌的代码
mov [esi + 10], edi
mov eax, [esi+10]
jmp Address+lenth // 这个是执行完剑侠情缘原有代码让它再跳回去
CodeFix长度是 lenth+0x5,lenth是要进行hook位置的指令长度,0x5是执行完指令之后让他跳回去
*/
DWORD dOld;
CodeFix[lenth] = 0xE9;
unsigned* adr = (unsigned*)(CodeFix + lenth + 1);
adr[0] = GetJMPCode((unsigned)_adr + lenth, (unsigned)&CodeFix[lenth]);
VirtualProtect(CodeFix, lenth+0x5, PAGE_EXECUTE_READWRITE, &dOld);
}
HOOKPOINT* HOOKPOINT::AddPonit(LPVOID _adr,LPVOID _adrRet, HOOKBACK _hbk, uchar lenth)
{
NextPoint = new HOOKPOINT(_adr, _adrRet, _hbk, lenth, this);
return NextPoint;
}
htdHook.cpp文件里的修改
void _stdcall DisHook(PCPUINFO e) {
/**
call指令执行时会让eip指向下一条指令的位置,
这里减去0x5是让他回到call的位置,也就是得到从哪来的
*/
unsigned _eip = e->eip - 0x5;
PHOOKPOINT point = htdHookPtr->Points.FindPoint((LPVOID)_eip);
if (point) {
if(point->DestCall(e)){
// 继续执行原有代码
e->eip = (unsigned)point->CodeFix;
}else{
// 调转到指定位置执行
e->eip = (unsigned)point->AddressRet;
}
}
}
void htdHook::SetHook(LPVOID Address, HOOKBACK hokBack, uchar len, LPVOID AddressRet)
{
DWORD dOld;
DWORD dNew;
PPointLast = PPointLast->AddPonit(Address, AddressRet, hokBack, len);
VirtualProtect(Address, 0x5, PAGE_EXECUTE_READWRITE, &dOld);
char* code = (char*)Address;
code[0] = 0xE8;
unsigned* Adr = (unsigned*)(code + 1);
Adr[0] = GetJMPCode((unsigned)data_code, (unsigned)Address);
VirtualProtect(Address, 0x5, dOld, &dNew);
}
htdHook.h文件里的修改
void SetHook(LPVOID Address, HOOKBACK ookBack, uchar len, LPVOID AddressRet);
CWndMain.cpp文件中的修改
bool Wudi(PCPUINFO e) {
if (e->esi==0x4cef08)
{
e->edi = 0;
}
else {
e->edi = *((int*)(e->esi + 0x10));// 秒杀(除了我们的角色都得死)
}
return true;
}
bool NewWudi(PCPUINFO e) {
//AfxMessageBox(L"测试执行完这个辅助代码跳转");
return true;
}
void CWndMain::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
hook.SetHook((LPVOID)0x41FDB2, Wudi, 6, 0);
hook.SetHook((LPVOID)0x41FD40, NewWudi, 8, (LPVOID)0x41FE40);
}