Попытка заразить PE с помощью asm и C ++, но не знаю, что добавить в PE [закрыто]
Я пытаюсь создать приложение C++, которое заражает PE кодом сборки, изменяя точку входа PE в новый раздел, и там он должен запускать следующий код asm hello world. До сих пор я делал функцию, которая создает новый раздел в PE, и проблема в том, что я не знаю, что именно из сборки (я думаю, мне следует добавить что-то из .exe, созданного после компиляции), чтобы добавить в новый раздел. Я тестировал с CFF, и новый раздел создан corect, а точка входа изменена. Я должен упомянуть, что я использую nasm x64, и PE, который я пытаюсь заразить, тоже x64.
extern GetStdHandle
extern WriteConsoleA
extern ExitProcess
section .text
global main
main:
mov rcx, -11
call GetStdHandle
mov [stdOut], rax
mov rcx, [stdOut]
lea rdx, msg
mov r8, len
lea r9, buffer
call WriteConsoleA
mov rcx, 0
call ExitProcess
section .data
msg db 'Hello world!', 0xa
len equ $ - msg
section .bss
stdOut resq 2
buffer resq 2
и код C++, который я написал:
#include <stdio.h>
#include <windows.h>
#include <stdbool.h>
// returns the DOS Header
PIMAGE_DOS_HEADER GetDosHeader(LPBYTE file) {
return (PIMAGE_DOS_HEADER)file;
}
/*
* returns the PE header
*/
PIMAGE_NT_HEADERS GetPeHeader(LPBYTE file) {
PIMAGE_DOS_HEADER pidh = GetDosHeader(file);
return (PIMAGE_NT_HEADERS)((u_char*)pidh + pidh->e_lfanew);
}
/*
* returns the file header
*/
PIMAGE_FILE_HEADER GetFileHeader(LPBYTE file) {
PIMAGE_NT_HEADERS pinh = GetPeHeader(file);
return (PIMAGE_FILE_HEADER)&pinh->FileHeader;
}
/*
* returns the optional header
*/
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPBYTE file) {
PIMAGE_NT_HEADERS pinh = GetPeHeader(file);
return (PIMAGE_OPTIONAL_HEADER)&pinh->OptionalHeader;
}
/*
* returns the first section's header
* AKA .text or the code section
*/
PIMAGE_SECTION_HEADER GetFirstSectionHeader(LPBYTE file) {
PIMAGE_NT_HEADERS pinh = GetPeHeader(file);
return (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(pinh);
}
PIMAGE_SECTION_HEADER GetLastSectionHeader(LPBYTE file) {
return (PIMAGE_SECTION_HEADER)(GetFirstSectionHeader(file) + (GetPeHeader(file)->FileHeader.NumberOfSections - 1));
}
DWORD align(DWORD size, DWORD align, DWORD addr) {
if (!(size % align))
return addr + size;
return addr + (size / align + 1) * align;
}
bool AddSection(const char* filepath, const char* sectionName, DWORD sizeOfSection) {
HANDLE hFile = CreateFileA(filepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("[-] Cannot open %s\n", filepath);
return 0;
}
DWORD dwFileSize = GetFileSize(hFile, NULL);
if (!dwFileSize)
{
printf("[-] Could not get files size\n");
CloseHandle(hFile);
return 0;
}
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize, NULL);
DWORD dw = GetLastError();
if (!hMapping)
{
printf("[-] CreateFileMapping failed\n");
CloseHandle(hFile);
return 0;
}
LPBYTE pByte = (LPBYTE)MapViewOfFile(hMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, dwFileSize);
DWORD dw1 = GetLastError();
if (!pByte)
{
printf("[-] MapViewOfFile failed\n");
CloseHandle(hMapping);
CloseHandle(hFile);
return 0;
}
//check signature
//pDosHeader = (PIMAGE_DOS_HEADER)lpFile;
PIMAGE_DOS_HEADER dos = GetDosHeader(pByte);
if (dos->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("[-] DOS signature not found\n");
UnmapViewOfFile(pByte);
CloseHandle(hMapping);
CloseHandle(hFile);
return 0;
}
PIMAGE_NT_HEADERS nt = GetPeHeader(pByte);
PIMAGE_FILE_HEADER FH = (PIMAGE_FILE_HEADER)(pByte + dos->e_lfanew + sizeof(DWORD));
PIMAGE_OPTIONAL_HEADER OH = (PIMAGE_OPTIONAL_HEADER)(pByte + dos->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER));
PIMAGE_SECTION_HEADER SH = (PIMAGE_SECTION_HEADER)(pByte + dos->e_lfanew + sizeof(IMAGE_NT_HEADERS));
ZeroMemory(&SH[FH->NumberOfSections], sizeof(IMAGE_SECTION_HEADER));
CopyMemory(&SH[FH->NumberOfSections].Name, sectionName, 8);
//We use 8 bytes for section name,cause it is the maximum allowed section name size
//lets insert all the required information about our new PE section
SH[FH->NumberOfSections].Misc.VirtualSize = align(sizeOfSection, OH->SectionAlignment, 0);
SH[FH->NumberOfSections].VirtualAddress = align(SH[FH->NumberOfSections - 1].Misc.VirtualSize, OH->SectionAlignment, SH[FH->NumberOfSections - 1].VirtualAddress);
SH[FH->NumberOfSections].SizeOfRawData = align(sizeOfSection, OH->FileAlignment, 0);
SH[FH->NumberOfSections].PointerToRawData = align(SH[FH->NumberOfSections - 1].SizeOfRawData, OH->FileAlignment, SH[FH->NumberOfSections - 1].PointerToRawData);
SH[FH->NumberOfSections].Characteristics |= IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
SetFilePointer(hFile, SH[FH->NumberOfSections].PointerToRawData + SH[FH->NumberOfSections].SizeOfRawData, NULL, FILE_BEGIN);
//end the file right here,on the last section + it's own size
SetEndOfFile(hFile);
//now lets change the size of the image,to correspond to our modifications
//by adding a new section,the image size is bigger now
OH->SizeOfImage = SH[FH->NumberOfSections].VirtualAddress + SH[FH->NumberOfSections].Misc.VirtualSize;
//and we added a new section,so we change the NOS too
FH->NumberOfSections += 1;
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
//and finaly,we add all the modifications to the file
WriteFile(hFile, pByte, dwFileSize, &dw, NULL);
PIMAGE_SECTION_HEADER first = GetFirstSectionHeader(pByte);
PIMAGE_SECTION_HEADER last = GetLastSectionHeader(pByte);
SetFilePointer(hFile, last->PointerToRawData, NULL, FILE_BEGIN);
// in str I should add code to assembly/machine code for being added to the new section and then executed
const char* str = "";
DWORD dwOEP = nt->OptionalHeader.AddressOfEntryPoint + nt->OptionalHeader.ImageBase;
WriteFile(hFile, str, strlen(str), &dw, 0);
printf("EOP:- %d - %d\n", dwOEP, last->PointerToRawData);
nt->OptionalHeader.AddressOfEntryPoint = last->VirtualAddress; //- last->PointerToRawData;
CloseHandle(hFile);
return TRUE;
}
void main()
{
if (AddSection("D:\\sample.exe", ".TST", 400))
printf("Section added!\n");
else
printf("Error writting code!\n");
}
1 ответ
было бы проще, если бы это было так
HANDLE hFile = CreateFileA(...);
if(hFile!=INVALID_HANDLE_VALUE)
{
if(HANDLE hMap = CreateFileMapping(...))
{
if(VOID*data = MapViewOfFile(...))
{
///...
UnmapViewOfFile(data);
}
else /* can't map view */;
CloseHandle(hMap);
}
else /* can't create file mapping */;
CloseHandle(hFile);
}
else /* can't open file */;
новый раздел должен иметь адрес, округленный на
IMAGE_OPTIONAL_HEADER::SectionAlignment
и
entryPoint
знак равно
section_address
+
main_byte_offset
с начала раздела,
затем разрешая новые добавленные символы
GetStdHandle
WriteConsoleA
ExitProcess
они могут быть уже в
.idata
раздел в противном случае должен быть создан новый