C/C++ 写的CE,进程内存的读取与修改、特征码搜索、DLL注入、获取模块地址
2022-07-10
效果图:

编译环境:Unicode字符集
目录结构:
-----Getmod.h
-----yu.h
-----源.cpp
编译代码:
Getmod.h
#pragma once
// 尝试 将 delphi 翻译成 c++
#include<Windows.h>
#include<Tlhelp32.h>
class TToolhelp
{
public:
TToolhelp(DWORD dwFlags = 0, DWORD dwProcessID = 0);
~TToolhelp();
BOOL CreateSnapshot(DWORD dwFlags, DWORD dwProcessID = 0);
BOOL ProcessFirst(PPROCESSENTRY32 ppe);
BOOL ProcessNext(PPROCESSENTRY32 ppe);
BOOL ProcessFind(DWORD dwProcessId, PPROCESSENTRY32 ppe);
BOOL ModuleFirst(PMODULEENTRY32 pme);
BOOL ModuleNext(PMODULEENTRY32 pme);
BOOL ModuleFind_BaseAddr(void *pvBaseAddr, PMODULEENTRY32 pme);
BOOL ModuleFind_ModName(WCHAR * pszModName, PMODULEENTRY32 pme);
BOOL ThreadFirst(PTHREADENTRY32 pte);
BOOL ThreadNext(PTHREADENTRY32 pte);
BOOL HeapListFirst(PHEAPLIST32 phl);
BOOL HeapListNext(PHEAPLIST32 phl);
int HowManyHeaps();
BOOL HeapFirst(PHEAPENTRY32 phe, DWORD dwProcessID, DWORD dwHeapID);
BOOL HeapNext(PHEAPENTRY32 phe);
int HowManyBlocksInHeap(DWORD dwProcessID, DWORD dwHeapId);
BOOL IsAHeap(HANDLE hProcess, void * pvBlock, DWORD * pdwFlags);
BOOL EnableDebugPrivilege(BOOL fEnable = TRUE);
BOOL ReadProcessMemory(DWORD dwProcessID, void* pvBaseAddress, void* pvBuffer,
DWORD cbRead, DWORD *pdwNumberOfBytesRead = NULL);
private:
HANDLE m_hSnapshot;
};
//构造函数
TToolhelp::TToolhelp(DWORD dwFlags, DWORD dwProcessID)
{
m_hSnapshot = INVALID_HANDLE_VALUE;
CreateSnapshot(dwFlags, dwProcessID);
}
//析构函数
TToolhelp::~TToolhelp()
{
if (m_hSnapshot != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hSnapshot);
}
}
// 建立快照
BOOL TToolhelp::CreateSnapshot(DWORD dwFlags, DWORD dwProcessID)
{
if (m_hSnapshot != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hSnapshot);
}
if (dwFlags == 0)
m_hSnapshot = INVALID_HANDLE_VALUE;
else
m_hSnapshot = CreateToolhelp32Snapshot(dwFlags, dwProcessID);
return m_hSnapshot != INVALID_HANDLE_VALUE;
}
// 进程枚举
BOOL TToolhelp::ProcessFirst(PPROCESSENTRY32 ppe)
{
if (Process32First(m_hSnapshot, ppe) && ppe->th32ProcessID == 0)
{
return ProcessNext(ppe);
}
}
BOOL TToolhelp::ProcessNext(PPROCESSENTRY32 ppe)
{
if (Process32First(m_hSnapshot, ppe) && ppe->th32ProcessID == 0)
{
return ProcessNext(ppe);
}
}
BOOL TToolhelp::ProcessFind(DWORD dwProcessId, PPROCESSENTRY32 ppe)
{
BOOL R = ProcessFirst(ppe);
while (R)
{
if (ppe->th32ProcessID == dwProcessId)
break;
R = ProcessNext(ppe);
}
return R;
}
// 模块枚举
BOOL TToolhelp::ModuleFirst(PMODULEENTRY32 pme)
{
return Module32First(m_hSnapshot, pme);
}
BOOL TToolhelp::ModuleNext(PMODULEENTRY32 pme)
{
return Module32Next(m_hSnapshot, pme);
}
BOOL TToolhelp::ModuleFind_BaseAddr(void *pvBaseAddr, PMODULEENTRY32 pme)
{
BOOL R = ModuleFirst(pme);
while (R)
{
if (pme->modBaseAddr == pvBaseAddr)
break;
R = ModuleNext(pme);
}
return R;
}
BOOL TToolhelp::ModuleFind_ModName(WCHAR *pszModName, PMODULEENTRY32 pme)
{
BOOL R = ModuleFirst(pme);
while (R)
{
if (lstrcmpi(pme->szModule, pszModName) == 0 ||
lstrcmpi(pme->szExePath, pszModName) == 0) break;
R = ModuleNext(pme);
}
return R;
}
// 线程枚举
BOOL TToolhelp::ThreadFirst(PTHREADENTRY32 pte)
{
return Thread32First(m_hSnapshot, pte);
}
BOOL TToolhelp::ThreadNext(PTHREADENTRY32 pte)
{
return Thread32Next(m_hSnapshot, pte);
}
// 内存枚举
int TToolhelp::HowManyHeaps()
{
HEAPLIST32 hl;
BOOL fOK;
int R = 0;
hl.dwSize = sizeof(HEAPLIST32);
fOK = HeapListFirst(&hl);
while (fOK)
{
R++;
fOK = HeapListNext(&hl);
}
return R;
}
int TToolhelp::HowManyBlocksInHeap(DWORD dwProcessID, DWORD dwHeapId)
{
HEAPENTRY32 he;
BOOL fOK;
int R = 0;
he.dwSize = sizeof(he);
fOK = HeapFirst(&he, dwProcessID, dwHeapId);
while (fOK)
{
R++;
fOK = HeapNext(&he);
}
return R;
}
BOOL TToolhelp::HeapListFirst(PHEAPLIST32 phl)
{
return Heap32ListFirst(m_hSnapshot, phl);
}
BOOL TToolhelp::HeapListNext(PHEAPLIST32 phl)
{
return Heap32ListNext(m_hSnapshot, phl);
}
BOOL TToolhelp::HeapFirst(PHEAPENTRY32 phe, DWORD dwProcessID, DWORD dwHeapID)
{
return Heap32First(phe, dwProcessID, dwHeapID);
};
BOOL TToolhelp::HeapNext(PHEAPENTRY32 phe)
{
return Heap32Next(phe);
}
BOOL TToolhelp::IsAHeap(HANDLE hProcess, void *pvBlock, DWORD *pdwFlags)
{
HEAPLIST32 hl;
HEAPENTRY32 he;
MEMORY_BASIC_INFORMATION mbi;
BOOL fOkHL, fOkHE;
BOOL R = FALSE;
hl.dwSize = sizeof(HEAPLIST32);
he.dwSize = sizeof(HEAPENTRY32);
fOkHL = HeapListFirst(&hl);
while (fOkHL)
{
fOkHE = HeapFirst(&he, hl.th32ProcessID, hl.th32HeapID);
while (fOkHE)
{
VirtualQueryEx(hProcess, &he.dwAddress, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (DWORD(mbi.AllocationBase) <= DWORD(pvBlock) &&
DWORD(pvBlock) <= DWORD(mbi.AllocationBase) + mbi.RegionSize)
{
*pdwFlags = hl.dwFlags;
R = TRUE;
return R;
};
fOkHE = HeapNext(&he);
}
fOkHL = HeapListNext(&hl);
}
}
// 提升权限
BOOL TToolhelp::EnableDebugPrivilege(BOOL fEnable)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
BOOL R = FALSE;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
if (fEnable)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
R = GetLastError() == ERROR_SUCCESS;
CloseHandle(hToken);
}
return R;
}
// 内存读取
BOOL TToolhelp::ReadProcessMemory(DWORD dwProcessID, void * pvBaseAddress, void * pvBuffer,
DWORD cbRead, DWORD *pdwNumberOfBytesRead)
{
return Toolhelp32ReadProcessMemory(dwProcessID, pvBaseAddress, pvBuffer, cbRead, pdwNumberOfBytesRead);
}yu.h
#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <string.h>
#include <cstdlib>
#include <Tlhelp32.h>
#include <string>
#include "Getmod.h"
using namespace std;
//参数分别为:进程句柄、特征码、偏移、读取长度、开始扫描位地置、扫描结束位置
uintptr_t hanshu_dizhi; //记录特征码对应的地址
uintptr_t ScanAddress(HANDLE process, char *markCode, int nOffset, unsigned long dwReadLen = 4, uintptr_t StartAddr = 0x400000, uintptr_t EndAddr = 0x7FFFFFFF, int InstructionLen = 0)
{
//************处理特征码,转化成字节*****************
if (strlen(markCode) % 2 != 0) return 0;
//特征码长度
int len = strlen(markCode) / 2; //获取代码的字节数
//将特征码转换成byte型 保存在m_code 中
BYTE *m_code = new BYTE[len];
for (int i = 0; i < len; i++)
{
//定义可容纳单个字符的一种基本数据类型。
char c[] = { markCode[i * 2], markCode[i * 2 + 1], '\0' };
//将参数nptr字符串根据参数base来转换成长整型数
m_code[i] = (BYTE)::strtol(c, NULL, 16);
}
//每次读取游戏内存数目的大小
const DWORD pageSize = 4096;
// 查找特征码 /
//每页读取4096个字节
BYTE *page = new BYTE[pageSize];
uintptr_t tmpAddr = StartAddr;
//定义和特征码一样长度的标识
int compare_one = 0;
while (tmpAddr <= EndAddr)
{
::ReadProcessMemory(process, (LPCVOID)tmpAddr, page, pageSize, 0); //读取0x400000的内存数据,保存在page,长度为pageSize
//在该页中查找特征码
for (int i = 0; i < pageSize; i++)
{
if (m_code[0] == page[i])//有一个字节与特征码的第一个字节相同,则搜索
{
for (int j = 0; j<len - 1; j++)
{
if (m_code[j + 1] == page[i + j + 1])//比较每一个字节的大小,不相同则退出
{
compare_one++;
}
else
{
compare_one = 0;
break;
}//如果下个对比的字节不相等,则退出,减少资源被利用
}
if ((compare_one + 1) == len)
{
// 找到特征码处理
//赋值时要给初始值,避免冲突
uintptr_t dwAddr = tmpAddr + i + nOffset;
uintptr_t ullRet = 0;
::ReadProcessMemory(process, (void*)dwAddr, &ullRet, dwReadLen, 0);
//cout<<dwAddr<<endl;
//这里的dwAddr已经对应的是搜索到的地址
//地址输出的也是10进制 需要转化为16进制
hanshu_dizhi = dwAddr;//记录地址
if (InstructionLen)
{
ullRet += dwAddr + dwReadLen;
}
return ullRet;
}
}
}
tmpAddr = tmpAddr + pageSize - len;//下一页搜索要在前一页最后长度len 开始查找,避免两页交接中间有特征码搜索不出来
}
return 0;
}
//10到16 用法在下面
/*
int ret = 10;
string result = tentosixteen(ret);
cout << result << endl;
*/
int quzheng(unsigned int tendoc)
{
int qian = tendoc / 16;
return qian;
}
string huanzhi(int numtype)
{
string us = std::to_string(numtype);
if (us == "0")
{
string result = "0";
return result;
}
else if (us == "1")
{
string result = "1";
return result;
}
else if (us == "2")
{
string result = "2";
return result;
}
else if (us == "3")
{
string result = "3";
return result;
}
else if (us == "4")
{
string result = "4";
return result;
}
else if (us == "5")
{
string result = "5";
return result;
}
else if (us == "6")
{
string result = "6";
return result;
}
else if (us == "7")
{
string result = "7";
return result;
}
else if (us == "8")
{
string result = "8";
return result;
}
else if (us == "9")
{
string result = "9";
return result;
}
else if (us == "10")
{
string result = "A";
return result;
}
else if (us == "11")
{
string result = "B";
return result;
}
else if (us == "12")
{
string result = "C";
return result;
}
else if (us == "13")
{
string result = "D";
return result;
}
else if (us == "14")
{
string result = "E";
return result;
}
else if (us == "15")
{
string result = "F";
return result;
}
else if (us == "16")
{
string result = "10";
return result;
}
}
string daoxu(string sixteendoc)
{
int length = strlen(sixteendoc.c_str());
int i = 0;
string ret;
string result;
while (i < length || i == length)
{
ret = sixteendoc.substr(length - i, 1);
result = result + ret;
//cout << ret << endl;
i = i + 1;
}
return result;
}
string tentosixteen(unsigned int tendoc)
{
//int tendoc = 426;
int zhengshu = quzheng(tendoc);
string sixteendoc = "";
while (true)
{
if (zhengshu > 16)
{
int cha = tendoc - zhengshu * 16;
tendoc = zhengshu;
//cout << cha << endl;
string result = huanzhi(cha);
sixteendoc = sixteendoc + result;
zhengshu = quzheng(tendoc);
}
else if (zhengshu == 16)
{
int cha = tendoc - zhengshu * 16;
tendoc = zhengshu;
//cout << cha << endl;
string result = huanzhi(cha);
sixteendoc = sixteendoc + result;
zhengshu = quzheng(tendoc);
}
else
{
int cha = tendoc - zhengshu * 16;
tendoc = zhengshu;
//cout << cha << endl;
//cout << zhengshu << endl;//最后一个整数也是差值
string result1 = huanzhi(cha);
string result2 = huanzhi(zhengshu);
sixteendoc = sixteendoc + result1 + result2;
break;
}
}
string oversixdoc = daoxu(sixteendoc);//这个时候sixteendoc是反着的所以倒序倒为正了
//cout << "oversixdoc:" << oversixdoc << endl;
int length = strlen(oversixdoc.c_str());
string tianchong;
//cout <<"length:" << length << endl;
int i = 8 - length;
while (true)
{
if (i > 0)
{
tianchong = tianchong + "0";
}
else
{
break;
}
i = i - 1;
}
//cout << "tianchong" << tianchong << endl;
string result = tianchong + oversixdoc;
//string result = tianchong + oversixdoc;
return result;
}
//16到10 用法在下面
/*
string typesixteen = "ABCDEFAB";
unsigned int result = sixteentoten(typesixteen);
cout << "结果:" << result << endl;
*/
int beishu(int length)
{
int ji = 1;
int length1 = 7 - length;
int i = 0;
while (true)
{
if (i < length1)
{
ji = ji * 16;
}
else
{
break;
}
i = i + 1;
}
//cout << "ji : " << ji << endl;
return ji;
}
int callback(string ret, int i)
{
unsigned int callback = 1;
//cout << "i:" << i << "ret" << ret << endl;
//cout << "beishu : " << beilv << endl;
if (ret == "0")
{
int beilv = beishu(i);
callback = beilv * 0;
}
else if (ret == "1")
{
int beilv = beishu(i);
callback = beilv * 1;
}
else if (ret == "2")
{
int beilv = beishu(i);
callback = beilv * 2;
}
else if (ret == "3")
{
int beilv = beishu(i);
callback = beilv * 3;
}
else if (ret == "4")
{
int beilv = beishu(i);
callback = beilv * 4;
}
else if (ret == "5")
{
int beilv = beishu(i);
callback = beilv * 5;
}
else if (ret == "6")
{
int beilv = beishu(i);
callback = beilv * 6;
}
else if (ret == "7")
{
int beilv = beishu(i);
callback = beilv * 7;
}
else if (ret == "8")
{
int beilv = beishu(i);
callback = beilv * 8;
}
else if (ret == "9")
{
int beilv = beishu(i);
callback = beilv * 9;
}
else if (ret == "A" || ret == "a")
{
int beilv = beishu(i);
callback = beilv * 10;
}
else if (ret == "B" || ret == "b")
{
int beilv = beishu(i);
callback = beilv * 11;
}
else if (ret == "C" || ret == "c")
{
int beilv = beishu(i);
callback = beilv * 12;
}
else if (ret == "D" || ret == "d")
{
int beilv = beishu(i);
callback = beilv * 13;
}
else if (ret == "E" || ret == "e")
{
int beilv = beishu(i);
callback = beilv * 14;
}
else if (ret == "F" || ret == "f")
{
int beilv = beishu(i);
callback = beilv * 15;
}
return callback;
}
int sixteentoten(string ten)
{
int length = strlen(ten.c_str());
int i = 0;
int answer = 0;
int reback;
string ret;
while (true)
{
if (i < length)
{
ret = ten.substr(i, 1);//获取到了每一个位数上的具体值
reback = callback(ret, i);
answer = answer + reback;
}
else
{
break;
}
i = i + 1;
}
string result = "1";
return answer;
}
/*Char*转TCHAR*/
LPWSTR ConvertCharToLPWSTR(const char* szString)
{
int dwLen = strlen(szString) + 1;
int nwLen = MultiByteToWideChar(CP_ACP, 0, szString, dwLen, NULL, 0);//算出合适的长度
LPWSTR lpszPath = new WCHAR[dwLen];
MultiByteToWideChar(CP_ACP, 0, szString, dwLen, lpszPath, nwLen);
return lpszPath;
}
/*string转LPCWSTR*/
LPCWSTR stringToLPCWSTR(std::string orig)
{
size_t origsize = orig.length() + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
return wcstring;
}
//DLL注入
/// <summary>
/// 注入DLL文件
/// </summary>
/// <param name="DllFullPath">DLL文件的全路径</param>
/// <param name="dwRemoteProcessId">要注入的程序的PID</param>
/// <returns></returns>
BOOL InjectDLL(const wchar_t* DllFullPath, const DWORD dwRemoteProcessId)
{
// 计算路径的字节数
int pathSize = (wcslen(DllFullPath) + 1) * sizeof(wchar_t);
// 获取句柄后,可以完全控制进程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId);
if (hProcess == NULL) {
//cout << "获取句柄失败" << endl;
return FALSE;
}
// TerminateProcess(hProcess, 0);//关闭句柄对象
// 实现注入
// 1.首先要提升权限,打开进程的访问令牌
// 【参数1】当前程序
// 【参数2】权限,可添加的权限|可查询的权限
HANDLE hToken;
if (FALSE == OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY, &hToken)) {
// 权限修改失败
//cout << "权限修改失败" << endl;
return FALSE;
}
//2.查看与进程相关的特权信息
LUID luid;
if (FALSE == LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
// 特权信息查询失败
//cout << "特权信息查询失败" << endl;
return FALSE;
};
//3.调节进程的访问令牌的特权属性
// 这几行代码固定不变
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = luid;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // 打开特权
// 【参数1】访问令牌
// 【参数2】是否禁用特权
// 【参数3】新特权所占的字节数
// 【参数4】原来的特权是否需要保存
// 【参数5】原特权的长度
if (FALSE == AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
{
// 提升特权失败
//cout << "提升特权失败" << endl;
return FALSE;
};
//在远程进程中申请内存空间
// 【参数1】程序的句柄对象
// 【参数2】申请的内存地址,由系统分配,所以为NULL
// 【参数3】申请的内存长度
// 【参数4】调用物理存储器
// 【参数5】这块内存可读可写,可执行
// 【返回】申请到的地址
LPVOID lpAddr = VirtualAllocEx(hProcess, NULL, pathSize, MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (lpAddr == NULL) {
// 在远程进程中申请内存失败
//cout << "在远程进程中申请内存失败" << endl;
return FALSE;
}
// 把DLL路径写入到远程进程中
// 强行修改程序的内存
// 【参数1】程序的句柄
// 【参数2】申请到的内存首地址
// 【参数3】写入的内容
// 【参数4】要写入的字节数
// 【参数5】
if (FALSE == WriteProcessMemory(hProcess, lpAddr, DllFullPath,
pathSize, NULL)) {
// 在远程进程中写入数据失败
//cout << "在远程进程中写入数据失败" << endl;
return FALSE;
};
// 调用Kernel32.dll中的LoadLibraryW方法用以加载DLL文件
PTHREAD_START_ROUTINE pfnStartAssr =
(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"Kernel32.dll"),
"LoadLibraryW");
// 在远程进程中开辟线程
// 【参数1】远程线程的句柄
// 【参数2】线程属性。NULL表示使用默认属性
// 【参数3】堆栈大小。0代表默认
// 【参数4】加载DLL文件的对象
// 【参数5】加载文件的路径
// 【参数6】延迟时间。0代表立即启动
// 【参数7】线程ID。为NULL就行了
HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, pfnStartAssr, lpAddr, 0,
NULL);
if (hRemoteThread == NULL) {
// 创建远程线程失败
//cout << "创建远程线程失败" << endl;
// 释放内存
VirtualFreeEx(hProcess, lpAddr, 0, MEM_FREE);
return FALSE;
}
cout << "注入成功" << endl;
// 等待线程结束
WaitForSingleObject(hRemoteThread, -1);
// 关闭线程
CloseHandle(hRemoteThread);
// 释放内存
VirtualFreeEx(hProcess, lpAddr, 0, MEM_FREE);
}
//const wchar_t* 转 char*
char* WcharToChar(const wchar_t* wc)
{
char* m_char = NULL;
delete m_char;
m_char = NULL;
int len = WideCharToMultiByte(CP_ACP, 0, wc, wcslen(wc), NULL, 0, NULL, NULL);
m_char = new char[len + 1];
WideCharToMultiByte(CP_ACP, 0, wc, wcslen(wc), m_char, len, NULL, NULL);
m_char[len] = '\0';
return m_char;
}源.cpp
#include "yu.h"
void retisone()
{
cin.ignore();
cout << "请输入窗口标题:";
string title;
getline(cin, title);
cout << "请输入内存地址16位:";
string straddress;
cin >> straddress;
string name = "0x" + straddress;
DWORD address = std::strtoul(name.c_str(), NULL, 16);//转换为DWORD类型变量
HWND hWnd;
LPCWSTR newititle = ConvertCharToLPWSTR(title.c_str());
hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
DWORD PID;
GetWindowThreadProcessId(hWnd, &PID);//存入PID
HANDLE hprocess;
hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);//获取进程
DWORD value = 0;//用来存原值是多少
DWORD size = 0;
if (false == ReadProcessMemory(hprocess, (void*)address, &value, sizeof(DWORD), &size))
{
cout << "读取失败" << endl;
}
else
{
cout << "当前的值(10进制):" << value << endl;
}
}
void retistwo()
{
cin.ignore();
cout << "请输入窗口标题:";
string title;
getline(cin, title);
cout << "请输入内存地址16位:";
string straddress;
cin >> straddress;
cout << "请输入修改为多少值(10进制):";
string newthing;
cin >> newthing;
string name = "0x" + straddress;
DWORD address = std::strtoul(name.c_str(), NULL, 16);//转换为DWORD类型变量
HWND hWnd;
LPCWSTR newititle = ConvertCharToLPWSTR(title.c_str());
hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
DWORD PID;
GetWindowThreadProcessId(hWnd, &PID);//存入PID
HANDLE hprocess;
hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);//获取进程
DWORD value = 0;//用来存原值是多少
DWORD newvalue = std::strtoul(newthing.c_str(), NULL, 10);//转换为DWORD类型变量
DWORD size = 0;
if (false == WriteProcessMemory(hprocess, (void*)address, &newvalue, sizeof(DWORD), &size))
{
cout << "修改失败" << endl;
}
else
{
cout << "修改成功" << endl;
}
}
void retisthree()
{
cin.ignore();
cout << "请输入窗口标题:";
string title;
getline(cin, title);
cout << "请输入特征码(如果不行可以试试切换大小写):";
string special;
cin >> special;
char * specialcode = const_cast<char*>(special.c_str());
cout << "请输入偏移量,如果没有请输入0:";
int move;
cin >> move;
HWND hWnd;
LPCWSTR newititle = ConvertCharToLPWSTR(title.c_str());
hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
DWORD PID;
GetWindowThreadProcessId(hWnd, &PID);//存入PID
HANDLE hprocess;
hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);//获取进程
ScanAddress(hprocess, specialcode, 0);//"获取地址值为多少" 如果输出的地址不对,可以试试特征码的大写和小写的替换
//cout << hanshu_dizhi << endl;//输出地址(10进制)
unsigned int num = hanshu_dizhi;
num = num + move;//相对内存地址偏移量(10进制)
string oversixdoc = tentosixteen(num);//这里已经转换为了16进制的地址
cout << "地址为:" << oversixdoc << endl;//输出地址(10进制)
}
void retisfour()
{
cin.ignore();
cout << "请输入窗口标题:";
string title;
getline(cin, title);
cout << "请输入DLL路径:";
string path;
cin >> path;
HWND hWnd;
LPCWSTR newititle = ConvertCharToLPWSTR(title.c_str());
hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
DWORD PID;
GetWindowThreadProcessId(hWnd, &PID);//存入PID
LPCWSTR newipath = ConvertCharToLPWSTR(path.c_str());
InjectDLL(newipath, PID);//这个dll你所要注入的dll文件,这个"数字"是你想注入的进程的PID号
}
void retisfive()
{
cin.ignore();
cout << "请输入窗口标题:";
string title;
getline(cin, title);
HWND hWnd;
LPCWSTR newititle = ConvertCharToLPWSTR(title.c_str());
hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
DWORD PID;
GetWindowThreadProcessId(hWnd, &PID);//存入PID
setlocale(LC_ALL, "chs");
MODULEENTRY32 meme;
meme.dwSize = sizeof(MODULEENTRY32);
BOOL fmOk;
TToolhelp(NULL).EnableDebugPrivilege(TRUE);
TToolhelp thModules = TToolhelp(TH32CS_SNAPALL, PID);//进程号
fmOk = thModules.ModuleFirst(&meme);
// 模块
while (true)
{
if (fmOk == 1)
{
//cout << fmOk << endl;
//模块
wprintf(L"模块基址:十进制 %d ,十六进制 0x%x ,模块大小:%d,模块名称:%s\n", meme.modBaseAddr, meme.modBaseAddr, meme.modBaseSize, meme.szModule);
fmOk = thModules.ModuleNext(&meme);
}
else
{
cout << "over" << endl;
break;
}
}
TToolhelp(NULL).EnableDebugPrivilege(FALSE);
}
void retissix()
{
cin.ignore();
cout << "请输入窗口标题:";
string title;
getline(cin, title);
cout << "请输入模块名字:";
string dllname;
getline(cin, dllname);
HWND hWnd;
LPCWSTR newititle = ConvertCharToLPWSTR(title.c_str());
hWnd = FindWindow(NULL, newititle);//根据窗口标题获取窗口句柄
DWORD PID;
GetWindowThreadProcessId(hWnd, &PID);//存入PID
//cout << PID << endl;
setlocale(LC_ALL, "chs");
MODULEENTRY32 meme;
meme.dwSize = sizeof(MODULEENTRY32);
BOOL fmOk;
TToolhelp(NULL).EnableDebugPrivilege(TRUE);
TToolhelp thModules = TToolhelp(TH32CS_SNAPALL, PID);//进程号
fmOk = thModules.ModuleFirst(&meme);
while (true)
{
if (fmOk == 1)
{
//cout << fmOk << endl;
//模块
//wprintf(L"模块基址:十进制 %d ,十六进制 0x%x ,模块大小:%d,模块名称:%s\n", meme.modBaseAddr, meme.modBaseAddr, meme.modBaseSize, meme.szModule);
const wchar_t * havedll;
havedll = meme.szModule;
char * chhacedll = WcharToChar(havedll);
string strhavedll = chhacedll;
if (strhavedll == dllname)
{
unsigned char * sixaddr = meme.modBaseAddr;
void * addrofwant = meme.modBaseAddr;
int addr = (int)addrofwant;
string addrresult = tentosixteen(addr);
cout << "该模块地址(16进制):" << addrresult << endl;
break;
}
// 下一模块
fmOk = thModules.ModuleNext(&meme);
}
else
{
cout << "over" << endl;
break;
}
}
TToolhelp(NULL).EnableDebugPrivilege(FALSE);
}
void niceui()
{
cout << "---------Ece程序介绍---------" << endl;
cout << "----1.读取某进程某地址数据---" << endl;
cout << "----2.修改某进程某地址数据---" << endl;
cout << "----3.特征码搜索地址---------" << endl;
cout << "----4.DLL注入----------------" << endl;
cout << "----5.获取程序所有模块地址---" << endl;
cout << "----6.获取程序特定模块地址---" << endl;
cout << "----7.刷新屏幕内容-----------" << endl;
cout << "----8.加入QQ群:614815597-----\n\n" << endl;
}
int main()
{
niceui();
int ret;
while (true)
{
cout << "你的指令是:";
cin >> ret;
if (ret == 1)//根据窗口标题读取某进程的某个地址
{
retisone();
}
else if (ret == 2)//根据窗口标题修改某个进程的某个地址
{
retistwo();
}
else if (ret == 3)//特征码搜索
{
retisthree();
}
else if (ret == 4)//dll注入
{
retisfour();
}
else if (ret == 5)//获取程序所有模块地址
{
retisfive();
}
else if (ret == 6)//获取程序特定模块地址
{
retissix();
}
else if (ret == 7)//清屏
{
system("cls");
niceui();
}
else if (ret == 8)//加入Q群
{
cout << "请你手动加群啦哈哈哈。官方Q群:614815597" << endl;
}
else
{
cout << "这是一个无法辨析命令" << endl;
}
}
while (true);
}如果你实在看不懂,只想要源码和已经编译好的软件
源码链接: https://pan.baidu.com/s/14MgQYNLqoMb3jRkWzBw9Yg?pwd=npn5 提取码: npn5 复制这段内容后打开百度网盘手机App,操作更方便哦
发表评论: