WriteProcessMemory по возвращаемым адресам - PullRequest
1 голос
/ 26 октября 2019

Таким образом, моя программа в основном ищет «указанные строки» в другой памяти процесса, а затем выводит адрес памяти, который содержит эти строки, но я хочу иметь возможность затем выполнить запись WriteProcessmemory, чтобы заменить все эти адреса. Мне просто нужно иметь всю процедуру записи для всех возвращаемых адресов, программа уже готова, мне просто нужно это, может быть, она могла бы работать, сохраняя адреса в векторе, или я не знаю.

#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <algorithm>
#include <iterator>
const char someDatanew[] = "\0";
template <class InIter1, class InIter2, class OutIter>
void find_all(unsigned char* base, InIter1 buf_start, InIter1 buf_end, InIter2 pat_start, InIter2 pat_end, OutIter res) {
    for (InIter1 pos = buf_start;
        buf_end != (pos = std::search(pos, buf_end, pat_start, pat_end));
        ++pos)
    {
        *res++ = base + (pos - buf_start);
    }
}

template <class outIter>
void find_locs(HANDLE process, std::string const &pattern, outIter output) {

    unsigned char* p = NULL;
    MEMORY_BASIC_INFORMATION info;

    for (p = NULL;
        VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize)
    {
        std::vector<char> buffer;
        std::vector<char>::iterator pos;

        if (info.State == MEM_COMMIT &&
            (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE))
        {
            SIZE_T bytes_read;
            buffer.resize(info.RegionSize);
            ReadProcessMemory(process, p, &buffer[0], info.RegionSize, &bytes_read);
            buffer.resize(bytes_read);
            find_all(p, buffer.begin(), buffer.end(), pattern.begin(), pattern.end(), output);
            //if (WriteProcessMemory(process, (LPVOID)here all returned addresses, someDatanew, sizeof(someDatanew), 0))
            ////    std::cout << "done";
            //}
        }
    }
}
void EnableDebugPriv() {
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tkp;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL);

    CloseHandle(hToken);
}

bool getMaximumPrivileges(HANDLE h_Process) {

    HANDLE h_Token;
    DWORD dw_TokenLength;

    if (OpenProcessToken(h_Process, TOKEN_READ | TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &h_Token)) {
        // Read the old token privileges
        TOKEN_PRIVILEGES* privilages = new TOKEN_PRIVILEGES[100];
        if (GetTokenInformation(h_Token, TokenPrivileges, privilages, sizeof(TOKEN_PRIVILEGES) * 100, &dw_TokenLength)) {
            // Enable all privileges
            for (int i = 0; i < privilages->PrivilegeCount; i++) {
                privilages->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED;
            }

            // Adjust the privilges
            if (AdjustTokenPrivileges(h_Token, false, privilages, sizeof(TOKEN_PRIVILEGES) * 100, NULL, NULL)) {
                delete[] privilages;
                return true;
            }
        }
        delete[] privilages;

    }
    return false;
} //get all tokens

int main() {
    EnableDebugPriv();
    getMaximumPrivileges(GetCurrentProcess());


    DWORD pid;
    std::cout << "Enter PID: ";
    std::cin >> pid;

    std::cin.get();

    std::string pattern;

    std::cout << "pattern to find: ";
    std::getline(std::cin, pattern);

    HANDLE process = OpenProcess(
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION | PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION,
        false,
        pid);

    find_locs(process, pattern,
        std::ostream_iterator<void*>(std::cout, "\n")); //outputs addresses that contains the strings

    system("pause");

    return 0;
}

Я ожидаю просто заменить все возвращенные адреса на someDatanew

1 Ответ

0 голосов
/ 12 ноября 2019

Вместо вывода результатов функции find_locs () на консоль вы должны записывать каждый строковый адрес в массив. Затем, после того, как это будет выполнено, прокрутите их и вызовите WriteProcessMemory , перезаписав их чем угодно, просто убедитесь, что у вас правильный размер / нулевое завершение.

Или вы можете отсканировать память дляодин шаблон, перезаписать результат, выполнить повторный поиск следующего, перезаписать, пока PatternScan () не вернет результат. Но это менее эффективно.

Для скорейшего разрешения вашего вопроса я отредактировал find_all (), добавив в него вызов WriteProcessMemory, который является самым быстрым способом выполнения того, что вы хотите. Я изменил несколько других вещей, поэтому обязательно скопируйте и вставьте весь этот исходный код, переписав ваш.

Я удалил материал повышения уровня токена SeDebug, в этом нет необходимости. Вам нужно только запустить вашу программу как администратор, чтобы использовать эти API.

Протестировано работает, просто убедитесь, что длина перезаписываемой строки по крайней мере равна длине someDataNew

#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <algorithm>
#include <iterator>

const char * someDatanew = "Foobar\0";

HANDLE process = 0;

template <class InIter1, class InIter2, class OutIter>

void find_all(unsigned char* base, InIter1 buf_start, InIter1 buf_end, InIter2 pat_start, InIter2 pat_end, OutIter res) {
    for (InIter1 pos = buf_start;
        buf_end != (pos = std::search(pos, buf_end, pat_start, pat_end));
        ++pos)
    {
        *res++ = base + (pos - buf_start);

        if (WriteProcessMemory(process, (LPVOID)(base + (pos - buf_start)), (LPCVOID)someDatanew, strlen(someDatanew), 0))
        std::cout << "done";

    }
}

template <class outIter>
void find_locs(HANDLE process, std::string const &pattern, outIter output) {

    unsigned char* p = NULL;
    MEMORY_BASIC_INFORMATION info;

    for (p = NULL;
        VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize)
    {
        std::vector<char> buffer;
        std::vector<char>::iterator pos;

        if (info.State == MEM_COMMIT &&
            (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE))
        {
            SIZE_T bytes_read;
            buffer.resize(info.RegionSize);
            ReadProcessMemory(process, p, &buffer[0], info.RegionSize, &bytes_read);
            buffer.resize(bytes_read);
            find_all(p, buffer.begin(), buffer.end(), pattern.begin(), pattern.end(), output);

        }
    }
}

int main()
{
    DWORD pid;
    std::cout << "Enter PID: ";
    std::cin >> pid;

    std::cin.get();

    std::string pattern;

    std::cout << "pattern to find: ";
    std::getline(std::cin, pattern);

    process = OpenProcess(
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION | PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION,
        false,
        pid);

    find_locs(process, pattern,
        std::ostream_iterator<void*>(std::cout, "\n")); //outputs addresses that contains the strings

    system("pause");

    return 0;
}
...