Code :
#define _CRT_SECURE_NO_WARNINGS #include <Windows.h> #include <stdio.h> #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; }