PePatchByLoader
来源:互联网 发布:mac app store 速度慢 编辑:程序博客网 时间:2024/06/11 19:31
前言
当程序有壳时, 如果要打文件补丁, 就需要脱壳, 如果条件不允许, 可以采用打内存补丁的方式.
用CreateProcess启动目标进程好些.
如果不用在OEP处开始打补丁, 可以用非调试方式的CreateProcess启动进程. 等进程起来后, 手工选择时机, 对进程内存进行读写.
如果必须在OEP处打补丁, 要用调试方式的CreateProcess, 等到了OEP, 自动读写进程内存, 将补丁打上.
记录
手工选择时机打补丁
// PePatchByLoader.cpp : Defines the entry point for the console application.///*** 启动程序后, 等时机到了, 再修改指定内存内容, 可以用非调试方式的CreateProcess*/#include "stdafx.h"#include <windows.h>#include <stdlib.h>#include <stdio.h>#include <conio.h>#define OBJ_EXE_NAME "RegMech.exe"BOOL EnablePrivilege(BOOL bEnable);BOOL CmdProc_r(PROCESS_INFORMATION* pi);BOOL CmdProc_w(PROCESS_INFORMATION* pi);int main(int argc, char* argv[]){ BOOL bContinue = TRUE; int iChoice = 0; STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi)); EnablePrivilege(TRUE); do { si.cb = sizeof(si); if (!CreateProcess(OBJ_EXE_NAME, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { printf("error : CreateProcess [%s]\r\n", OBJ_EXE_NAME); break; } ResumeThread(pi.hThread); while (bContinue) { printf("PePatchByLoader 命令列表:\r\n"); printf("r : 读目标内存\r\n"); printf("w : 写目标内存\r\n"); printf("q : 退出\r\n"); fflush(stdin); iChoice = _getch(); switch (iChoice) { case 'r': SuspendThread(pi.hThread); CmdProc_r(&pi); ResumeThread(pi.hThread); break; case 'w': SuspendThread(pi.hThread); CmdProc_w(&pi); ResumeThread(pi.hThread); break; case 'q': bContinue = FALSE; break; default: break; } } if (pi.hProcess) { CloseHandle(pi.hProcess); pi.hProcess = NULL; } if (pi.hThread) { CloseHandle(pi.hThread); pi.hThread = NULL; } } while (0); printf("END\r\n"); system("pause"); return 0;}/** run resultPePatchByLoader 命令列表:r : 读目标内存w : 写目标内存q : 退出0F BF 95 0C FF FF FF 85 D2 0F 84 81 00 00 00PePatchByLoader 命令列表:r : 读目标内存w : 写目标内存q : 退出E9 82 00 00 00 90PePatchByLoader 命令列表:r : 读目标内存w : 写目标内存q : 退出END请按任意键继续. . .*/BOOL CmdProc_r(PROCESS_INFORMATION* pi){ /* 0088BCEC 0FBF95 0CFFFFFF movsx edx,word ptr ss:[ebp-0xF4] 0088BCF3 85D2 test edx,edx 0088BCF5 0F84 81000000 je RegMech.0088BD7C */ BOOL bRc = FALSE; LPCVOID lpBaseAddress = (LPCVOID)0x0088BCEC; char szBuf[0x100] = {'\0'}; SIZE_T nSize = 0; SIZE_T nIndex = 0; BYTE uc = '\0'; if ((NULL == pi) || (NULL == pi->hProcess)) { printf("invalid pi\r\n"); return bRc; } nSize = 0x0088BCF5 - 0x0088BCEC + 6;// 0088BCF5 - 0088BCEC + sizeof(0F84 81000000) bRc = ReadProcessMemory(pi->hProcess, lpBaseAddress, (LPVOID)szBuf, nSize, &nSize); if (bRc) { printf("\r\n"); for (nIndex = 0; nIndex < nSize; nIndex++) { uc = szBuf[nIndex]; printf("%2.2X ", uc); } printf("\r\n"); } else { printf("Error : ReadProcessMemory\r\n"); } return bRc;}BOOL CmdProc_w(PROCESS_INFORMATION* pi){ /* old code : 0088BCF5 0F84 81000000 je RegMech.0088BD7C new code : 0088BCF5 /E9 82000000 jmp RegMech.0088BD7C 0088BCFA |90 nop */ BOOL bRc = FALSE; BYTE uc = 0; LPVOID lpBaseAddress = (LPVOID)0x0088BCF5; char szBuf[0x6] = {(char)0xE9, (char)0x82, (char)0x00, (char)0x00, (char)0x00, (char)0x90}; SIZE_T nSize = sizeof(szBuf); SIZE_T nIndex = 0; DWORD dwOldProtect = 0; if ((NULL == pi) || (NULL == pi->hProcess)) { printf("invalid pi\r\n"); return bRc; } VirtualProtectEx(pi->hProcess, lpBaseAddress, nSize, PAGE_READWRITE, &dwOldProtect); bRc = WriteProcessMemory(pi->hProcess, lpBaseAddress, (LPVOID)szBuf, nSize, &nSize); VirtualProtectEx(pi->hProcess, lpBaseAddress, nSize, dwOldProtect, &dwOldProtect); if (bRc) { printf("\r\n"); for (nIndex = 0; nIndex < nSize; nIndex++) { uc = szBuf[nIndex]; printf("%2.2X ", uc); } printf("\r\n"); } else { printf("Error : WriteProcessMemory\r\n"); } return bRc;}BOOL EnablePrivilege(BOOL bEnable){ BOOL bRc = FALSE; HANDLE hToken = NULL; TOKEN_PRIVILEGES tp; ZeroMemory(&tp, sizeof(tp)); if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { tp.PrivilegeCount = 1; LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); bRc = (GetLastError() == ERROR_SUCCESS); CloseHandle(hToken); hToken = NULL; } return bRc;}
0 0
- PePatchByLoader
- Leetcode 368 - Largest Divisible Subset(dp)
- Spring源码如何导入到eclipse
- mysql-5.7.17-winx64的安装问题
- C#中语句的使用
- 响应式轮播插件(无焦点&可链式操作)
- PePatchByLoader
- HDU1969:Pie(二分 + 贪心)
- bringing up interface eth0: error no suitable device found
- 洛谷P1434 滑雪
- gulp源码解析(一)—— Stream详解
- Spring Data JPA例子[基于Spring Boot、Mysql]
- C++ 封装RapidJson把一个类Json序列化和反序列化
- java中有关 == 字符串的比较
- 利用phpmyadmin来做MySQL主从复制,so easy!