Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Created June 9, 2026 07:19
Show Gist options
  • Select an option

  • Save sunmeat/1ec0eebce70e6cace445610ac2fb0b7e to your computer and use it in GitHub Desktop.

Select an option

Save sunmeat/1ec0eebce70e6cace445610ac2fb0b7e to your computer and use it in GitHub Desktop.
пример находит строку текста в памяти другого процесса, и меняет её на другую строку такой же длины (проверять в notepad++)
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <vector>
#include <string>
#include <shellapi.h>
bool IsRunAsAdmin() {
bool isAdmin = false;
HANDLE token = NULL;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
TOKEN_ELEVATION elevation;
DWORD size = sizeof(elevation);
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size)) {
isAdmin = elevation.TokenIsElevated != 0;
}
CloseHandle(token);
}
return isAdmin;
}
void ElevatePrivileges() {
wchar_t szPath[MAX_PATH];
if (GetModuleFileNameW(NULL, szPath, MAX_PATH)) {
SHELLEXECUTEINFOW sei = { sizeof(sei) };
sei.cbSize = sizeof(sei);
sei.lpVerb = L"runas";
sei.lpFile = szPath;
sei.hwnd = NULL;
sei.nShow = SW_NORMAL;
if (ShellExecuteExW(&sei)) {
ExitProcess(0);
}
}
}
DWORD GetProcessIdByName(const wchar_t* processName) {
DWORD pid = 0;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32W processEntry;
processEntry.dwSize = sizeof(processEntry);
if (Process32FirstW(snapshot, &processEntry)) {
do {
if (wcscmp(processEntry.szExeFile, processName) == 0) {
pid = processEntry.th32ProcessID;
break;
}
} while (Process32NextW(snapshot, &processEntry));
}
CloseHandle(snapshot);
}
return pid;
}
int main() {
if (!IsRunAsAdmin()) {
ElevatePrivileges();
return 0;
}
// Нацеливаемся на классический Win32 Notepad++
const wchar_t* targetProcess = L"notepad++.exe";
std::string targetStr, newStr;
std::cout << "Enter string to find (e.g. hello): ";
std::cin >> targetStr;
std::cout << "Enter new string (must be same length, e.g. world): ";
std::cin >> newStr;
if (targetStr.length() != newStr.length()) {
std::cout << "Strings must be of equal length for this simple example!" << std::endl;
system("pause");
return 1;
}
DWORD pid = GetProcessIdByName(targetProcess);
if (pid == 0) {
std::cout << "Process notepad++.exe not found. Please open Notepad++ first." << std::endl;
system("pause");
return 1;
}
HANDLE processHandle = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!processHandle) {
std::cout << "Failed to open process. Error code: " << GetLastError() << std::endl;
system("pause");
return 1;
}
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
char* address = static_cast<char*>(sysInfo.lpMinimumApplicationAddress);
char* maxAddress = static_cast<char*>(sysInfo.lpMaximumApplicationAddress);
size_t replacementsCount = 0;
while (address < maxAddress) {
MEMORY_BASIC_INFORMATION mbi;
if (VirtualQueryEx(processHandle, address, &mbi, sizeof(mbi)) == sizeof(mbi)) {
if (mbi.State == MEM_COMMIT && (mbi.Protect & PAGE_READWRITE) && !(mbi.Protect & PAGE_GUARD)) {
std::vector<char> buffer(mbi.RegionSize);
SIZE_T bytesRead;
if (ReadProcessMemory(processHandle, mbi.BaseAddress, buffer.data(), mbi.RegionSize, &bytesRead)) {
for (size_t i = 0; i <= bytesRead - targetStr.length(); ++i) {
if (memcmp(&buffer[i], targetStr.c_str(), targetStr.length()) == 0) {
char* matchAddress = static_cast<char*>(mbi.BaseAddress) + i;
SIZE_T bytesWritten;
if (WriteProcessMemory(processHandle, matchAddress, newStr.c_str(), newStr.length(), &bytesWritten)) {
replacementsCount++;
}
}
}
}
}
address += mbi.RegionSize;
}
else {
address += sysInfo.dwPageSize;
}
}
std::cout << "Scan finished. Total replacements made: " << replacementsCount << std::endl;
CloseHandle(processHandle);
system("pause");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment