[C++] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdbool.h>
#include <dlfcn.h>
#include <string.h>
#include <stdint.h>
#include "damge.h"
char* temp_func;
typedef unsigned char BYTE;
typedef unsigned long DWORD;
typedef unsigned int uint32_t;
typedef signed short int16_t;
typedef signed short WORD;
typedef int(*STRCMP)(const char*, const char*);
typedef int64_t (*OrigFuncType)(
uint32_t *a1, int *a2, unsigned int a3, unsigned int a4,
unsigned int a5, unsigned int a6, double a7, unsigned int a8, int a9
);
OrigFuncType orig_func = nullptr;
char* trampoline = nullptr;
void BuildTrampoline(uintptr_t target_addr, size_t patch_len)
{
trampoline = (char *)mmap(nullptr, patch_len + 16, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE, -1, 0);
memcpy(trampoline, (void *)target_addr, patch_len);
uintptr_t jmp_back_addr = target_addr + patch_len;
unsigned char* p = (unsigned char*)(trampoline + patch_len);
// FF 25 00 00 00 00 [8字节绝对地址]
*p++ = 0xFF;
*p++ = 0x25;
*(uint32_t*)p = 0; // 32位偏移
p += 4;
*(uint64_t*)p = jmp_back_addr;
orig_func = (OrigFuncType)trampoline;
}
CHook::CHook(void)
{
memset(&m_Context, 0, sizeof(m_Context));
memset(m_OldCode, 0x90, 5);
m_dwRetAddr = 0;
m_dwHookAddr = 0;
}
CHook::~CHook(void)
{
}
bool change_addr_writable(long address, bool writable) {
long page_size = sysconf(_SC_PAGESIZE);
long page_start = (address)& (~(page_size - 1));
//printf("faild to init stubpage_start:%x\n", page_start);
//change memory attribute
if (writable == true) {
return mprotect((void*)page_start, page_size, PROT_READ | PROT_WRITE | PROT_EXEC) != -1;
}
else {
return mprotect((void*)page_start, page_size, PROT_READ | PROT_EXEC) != -1;
}
}
//替换目标函数的前len个字节,使之跳转到hook函数
void change_bytes(uintptr_t addr, const char code[], int len)
{
memcpy((void*)addr, code, len);
}
bool CHook::AddHookJMP(uintptr_t address, void *pfnHookProc)
{
if (change_addr_writable(address, true))
{
// 使用更可靠的跳转指令
BYTE jumpCode[14] = {0xFF, 0x25, 0x00, 0x00, 0x00, 0x00}; // jmp [rip+offset]
uint64_t addr64 = (uint64_t)pfnHookProc;
memcpy(&jumpCode[6], &addr64, 8);
change_bytes(address, (const char*)jumpCode, 14);
change_addr_writable(address, false);
return true;
}
return false;
}
CHook hook1;
// 菁梦 尝试写个伤害回调看看 2025年6月6日14:20:16 - -第一次
int64_t my_hook_func(uint32_t *a1, int *a2, unsigned int a3, unsigned int a4,
unsigned int a5, unsigned int a6, double a7, unsigned int a8, int a9)
{
printf(
"\033[1;31m[伤害回调数据] 参数:\n"
" a1 = %p\n"
" a2 = %p\n"
" a3 = %u\n"
" a4 = %u\n"
" a5 = %u\n"
" a6 = %u\n"
" a7 = %f\n"
" a8 = %u\n"
" a9 = %d\n\033[0m",
a1, a2, a3, a4, a5, a6, a7, a8, a9
);
int64_t ret = 0;
if (orig_func) {
printf("Before call orig_func: RIP=%p, RSP=%p\n", __builtin_return_address(0), __builtin_frame_address(0));
ret = orig_func(a1, a2, a3, a4, a5, a6, a7, a8, a9);
printf("After call orig_func: ret=%ld\n", ret);
}
return ret;
}
const char* asdas = "St5ctypeIcE";
int asas = 0;
int strcmp(const char *s1, const char *s2)
{
unsigned long myfunctionaddr = 0x48;
static void *handle = NULL;
static STRCMP old_strcmp = NULL;
if (!handle)
{
handle = dlopen("libc.so.6", RTLD_LAZY);
old_strcmp = (STRCMP)dlsym(handle, "strcmp");
}
if (old_strcmp(s1, asdas) == 0){
if (asas == 0){
// 计算patch长度,x64建议用14字节(避免截断指令)
size_t patch_len = 2;
BuildTrampoline(0x6E633A, patch_len);
// 对伤害函数跳转
hook1.AddHookJMP(0x6E633A, (void *)my_hook_func);
asas = 1;
}
}
return old_strcmp(s1, s2);
}
__attribute__((constructor))
void load()
{
temp_func = (char*)mmap((void *)0X3B0000, 4096, PROT_WRITE | PROT_EXEC | PROT_READ, MAP_ANON | MAP_PRIVATE, -1, 0);
}
#define RED "\033[31m"
#define GREEN "\033[32m"
#define YELLOW "\033[33m"
#define BLUE "\033[34m"
#define MAGENTA "\033[35m"
#define CYAN "\033[36m"
#define WHITE "\033[37m"
#define RESET "\033[0m"