x86 hook跳转-内存地址转换-计算框架

 

Code :

 

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include "tlhelp32.h"

int hexstringtobyte(char *in, unsigned char *out);
int bytetohexstring(unsigned char *in, int len, char *out);

//存进程句柄
HANDLE hProcess;

//存自己分配的地址
LPVOID lp_address;

DWORD GetProcessIDByName(const char* pName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hSnapshot) {
        return NULL;
    }
    PROCESSENTRY32 pe = { sizeof(pe) };
    for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe)) {
        if (strcmp(pe.szExeFile, pName) == 0) {
            CloseHandle(hSnapshot);
            return pe.th32ProcessID;
        }
        //printf("%-6d %s\n", pe.th32ProcessID, pe.szExeFile);
    }
    CloseHandle(hSnapshot);
    return 0;
}


//十六进制逆序算法1
DWORD f(unsigned int n)
{
    unsigned int temp = 0;
    int i;
    for (i = 0; i < 4; i++)
    {
        temp = (temp << 8) | (0xff & (n >> (i * 8)));
    }
    return temp;
    //printf("%x\n", temp);
}

//十六进制逆序算法2
DWORD ff(unsigned int temp)
{
    long hex1 = (temp & 0xFF000000) >> 24;
    long hex2 = (temp & 0x000000FF) << 24;
    long hex3 = (temp & 0x00FF0000) >> 8;
    long hex4 = (temp & 0x0000FF00) << 8;
    long hexSum = hex1 + hex2 + hex3 + hex4;
    return hexSum;
}


//十六进制转字节数组
int hexstringtobyte(char *in, unsigned char *out) {
    int len = (int)strlen(in);
    char *str = (char *)malloc(len);
    memset(str, 0, len);
    memcpy(str, in, len);
    for (int i = 0; i < len; i += 2) {
        //小写转大写
        if (str[i] >= 'a' && str[i] <= 'f') str[i] = str[i] & ~0x20;
        if (str[i + 1] >= 'a' && str[i] <= 'f') str[i + 1] = str[i + 1] & ~0x20;
        //处理第前4位
        if (str[i] >= 'A' && str[i] <= 'F')
            out[i / 2] = (str[i] - 'A' + 10) << 4;
        else
            out[i / 2] = (str[i] & ~0x30) << 4;
        //处理后4位, 并组合起来
        if (str[i + 1] >= 'A' && str[i + 1] <= 'F')
            out[i / 2] |= (str[i + 1] - 'A' + 10);
        else
            out[i / 2] |= (str[i + 1] & ~0x30);
    }
    free(str);
    return 0;
}

int bytetohexstring(unsigned char *in, int len, char *out) {
    for (int i = 0; i < len; i++) {
        if ((in[i] >> 4) >= 10 && (in[i] >> 4) <= 15)
            out[2 * i] = (in[i] >> 4) + 'A' - 10;
        else
            out[2 * i] = (in[i] >> 4) | 0x30;

        if ((in[i] & 0x0f) >= 10 && (in[i] & 0x0f) <= 15)
            out[2 * i + 1] = (in[i] & 0x0f) + 'A' - 10;
        else
            out[2 * i + 1] = (in[i] & 0x0f) | 0x30;
    }
    return 0;
}



int main()
{
    int Pid = GetProcessIDByName("QQ.exe");
    hProcess = INVALID_HANDLE_VALUE;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);//游戏进程句柄


    printf("进程ID:%d \n\n", Pid);

    //分配的起始地址
    lp_address = VirtualAllocEx(hProcess, NULL, 128, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    printf("分配的地址为:0x%X\n\n", lp_address);

    //在分配的起始地址+10的位置写入字节
    //写入左边部分----------------------------------------------------注意下面写入2个字节
    BYTE shellCode_1[] = { 0x89,0x05 };
    WriteProcessMemory(hProcess, (LPVOID)((DWORD)(lp_address) + 0x10), shellCode_1, 2, NULL);

    //在分配的起始地址+30的位置存放我们的数据,也就是mov [分配地址 + 0x30],eax
    DWORD shellCode_2 = (DWORD)lp_address + 0x30;

    DWORD new_shellCode = ff(shellCode_2);

    //将new_shellCode转换成字符数组--假设0F3F0010--->转换成30003F0F--->转换成字符数组方便写入
    char s[8];
    sprintf(s,"%x", new_shellCode);
    unsigned char temp[4] = { 0 };
    //转换
    hexstringtobyte(s, temp);
    //打印应该写入的字节
    printf("写入的地址为:0x%X , 保存eax的地址为:mov [0x%X],eax , 写入的字节应该为:\n\n", (DWORD)lp_address + 0x10, (DWORD)lp_address + 0x30);
    for (int i = 0; i < 4; i++) {
        printf("%x ", temp[i]);
    }

    //写入字节
    WriteProcessMemory(hProcess, (LPVOID)((DWORD)(lp_address)+ 0x12), temp, 4, NULL);


    getchar();
    return 0;
}

 

x86 hook跳转-内存地址转换-计算框架_第1张图片

你可能感兴趣的:(x86 hook跳转-内存地址转换-计算框架)