滴水 2015-03-18(任意代码空白区添加代码) 抄视频代码


#include <winnt.h>

#include "stdafx.h"
#include "Globle.h"
#include <windows.h>
#include <malloc.h>

#define FILEPATH_IN        "C:/ipmsg.exe"
#define FILEPATH_OUT       "C:/ipmsg_new.exe"


#define SHELLCODELENGTH 0X12
//XP //演示的地址
//#define MESSAGEBOXADDR  0X77E5425F
//Win7  //这个宏要看自己机器的地址
#define MESSAGEBOXADDR  0x75BAEA89

//全局变量声明
BYTE shellCode[] =
{
	0x6A,00,0x6A,00,0x6A,00,0x6A,00,
	0xE8,00,00,00,00,
	0XE9,00,00,00,00
};



//
//Construction/Destruction
//
DWORD ReadPEFile(IN LPSTR lpszFile,OUT LPVOID*  pFileBuffer)
{
	FILE *pFile = NULL;
	DWORD fileSize = 0;
	LPVOID pTempFileBuffer;
	//打开文件
	pFile = fopen(lpszFile, "rb");
	if(!pFile)
	{
	    printf(" 无法打开 EXE 文件!");
		return 0;
	}
	//读取文件大小
	fseek(pFile, 0 , SEEK_END);
	fileSize = ftell(pFile);
	fseek(pFile, 0 , SEEK_SET);
	//分配缓冲区
	pTempFileBuffer = malloc(fileSize);
    if(!pTempFileBuffer)
	{
		printf(" 分配空间失败! ");
		fclose(pFile);
		return 0;
	}
	//将文件数据读取到缓冲区
	size_t n = fread(pTempFileBuffer, fileSize, 1, pFile);
    if(!n)
	{
		printf(" 读取数据失败! \n ");
		free(pTempFileBuffer);
		return 0;
	}
	*pFileBuffer = pTempFileBuffer;
	pTempFileBuffer = NULL;
	fclose(pFile);
	return fileSize;

}

DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer,OUT LPVOID*  pImageBuffer)
{
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader =NULL;
	LPVOID pTempImageBuffer = NULL;

	if(pFileBuffer == NULL)
	{
		printf("缓冲区指针无效");
        return 0;
	}
    //判断是否是有效的MZ标志
	if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
	{
		printf("不是有效的MZ标志\n");
		return 0;
	}
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	//判断是否是有效的PE标志
	if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
	{
        printf("不是有效的PE标志\n");
		return 0;
	}
   pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
   pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
   //可选PE头
   pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
   //第一个节目录指针
   pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);

   //根据SizeofImage申请新的空间

   pTempImageBuffer = malloc(pOptionHeader->SizeOfImage);

   if(!pTempImageBuffer)
   {
	   printf(" 分配空间失败! ");
	   return 0;
   }
   //初始化新的缓冲区
   memset(pTempImageBuffer,0,pOptionHeader->SizeOfImage);
   //根据SizeOfHeaders 先copy头
   memcpy(pTempImageBuffer,pDosHeader,pOptionHeader->SizeOfHeaders);
   //根据节表 循环copy节
   PIMAGE_SECTION_HEADER ptempSectionHeader = pSectionHeader;
   for(int i=0; i<pPEHeader->NumberOfSections;i++,ptempSectionHeader++)
   {
	   memcpy((void*)((DWORD)pTempImageBuffer + ptempSectionHeader->VirtualAddress),(void*)((DWORD)pDosHeader + ptempSectionHeader->PointerToRawData),ptempSectionHeader->SizeOfRawData);
   }
   *pImageBuffer = pTempImageBuffer;
   pTempImageBuffer = NULL;

   return pOptionHeader->SizeOfImage;
}

DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewFileBuffer)
{
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader =NULL;
	LPVOID pTempNewbuffer = NULL;
    DWORD sizeOfFile = 0;
	DWORD numberOfSection = 0;

	if(pImageBuffer == NULL)
	{
		printf("ImageBuffer缓冲区指针无效");
		return 0;
	} 
	//判断是否是有效的MZ标志
	if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
	{
		printf("ImageBuffer中的数据没有有效的MZ标志\n");
		return 0;
	}
	pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
	//判断是否是有效的PE标志
	if (*((PDWORD)((DWORD)pImageBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
	{
		printf("ImageBuffer中的数据没有有效的PE标志\n");
		return 0;
	}
 	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
	pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4);
	//可选PE头
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
	//第一个节目录指针
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
    //计算文件需要的空间:最后一个节的文件偏移+节对齐后的长度
    numberOfSection = pPEHeader->NumberOfSections;
	pSectionHeader = pSectionHeader+(numberOfSection-1);

	sizeOfFile = pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData;
	
	//根据SizeOfImage申请新的空间
	pTempNewbuffer = malloc(sizeOfFile);
	if (!pTempNewbuffer)
	{
		printf("分配新空间失败!");
		return 0;
	}
	//初始化新的缓冲区
	memset(pTempNewbuffer, 0, sizeOfFile);
	//根据SizeOfHearders 先Copy头
	memcpy(pTempNewbuffer, pDosHeader, pOptionHeader->SizeOfHeaders);
	//根据节表 循环copy节
	PIMAGE_SECTION_HEADER pTempSectionHeader =  (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
	for (int i=0; i<pPEHeader->NumberOfSections;i++, pTempSectionHeader++)
	{	//PointerToRawData节区在文件中的偏移,VirtualAddress节区在内存中的偏移地址,SizeOfRawData节在文件中对齐后的尺寸
		memcpy((void*)((DWORD)pTempNewbuffer + pTempSectionHeader->PointerToRawData), (void*)((DWORD)pImageBuffer + pTempSectionHeader->VirtualAddress), pTempSectionHeader->SizeOfRawData);
	}
	//返回数据
	*pNewFileBuffer = pTempNewbuffer; //暂存的数据传给参数后释放
	pTempNewbuffer = NULL;
	return sizeOfFile;  // 返回计算得到的分配内存的大小
}

//****************************************************************************
//MemeryTOFile:将内存中的数据复制到文件
//参数说明:
//pMemBuffer 内存中的数据的指针
//size 要复制的大小
//lpszFile 要存储的文件路径
//返回值说明:
//读取失败返回0 否则返回复制大小
//****************************************************************************
BOOL MemeryTOFile(IN LPVOID pMemBuffer,IN size_t size,OUT LPSTR lpszFile)
{   
	FILE *fp = NULL;
	fp = fopen(lpszFile, "wb");
	if(fp == NULL)
	{
		return FALSE;
	}
	fwrite(pMemBuffer, size, 1, fp);
	fclose(fp);
	fp = NULL;
	return TRUE;
}
//****************************************************************************
//RvaToFileOffset:将内存变异转换文件偏移
//参数说明:
//pFileBuffer FileBuffer指针
//dwRva RVA的值
//返回值说明
//返回转换后的FOA的值 如果失败返回0
//****************************************************************************
DWORD RavToFileOffset(IN LPVOID pFileBuffer,IN DWORD dwRva)
{
	return 0;
}
//测试函数:打印NT头
VOID TestPrintNTHeaders()
{
}
//测试函数 文件-->FileBuffer-->ImageBuffer-NewBuffer-->存盘
VOID TestPELoader()
{
}
//测试函数:向代码段空闲区添加代码
VOID TestAddCodeInCodeSec()
{
	LPVOID pFileBuffer = NULL;
    LPVOID pImageBuffer = NULL;
	LPVOID pNewBuffer = NULL;
	PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	PBYTE codeBegin = NULL;
	BOOL isOK = FALSE;
	DWORD size = 0;
   
	//File-->FileBuffer
	ReadPEFile(FILEPATH_IN,&pFileBuffer);
	if(!pFileBuffer)
	{
		printf("文件-->缓冲区失败");
		return;
	}
	//FileBuffer-->ImageBuffer
	CopyFileBufferToImageBuffer(pFileBuffer,&pImageBuffer);
	if(!pImageBuffer)
	{
	    printf("FileBuffer-->ImageBuffer");
		free(pFileBuffer);
		return;
	
	}
	//判断代码段空闲区是否足够存储ShellCode代码
	pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(((DWORD)pImageBuffer + pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER);
	pSectionHeader = (PIMAGE_SECTION_HEADER)(((DWORD)pImageBuffer + pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_NT_OPTIONAL32_HEADER);

	if(((pSectionHeader->SizeOfRawData) - (pSectionHeader->Misc.VirtualSize)) < SHELLCODELENGTH)
	{
		printf("代码区空间不够");
		free(pFileBuffer);
		free(pImageBuffer);
	}
	//将代码复制到空闲区
	codeBegin = (PBYTE)((DWORD)pImageBuffer + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize);
	memcpy(codeBegin,shellCode,SHELLCODELENGTH);
	//修正E8
	DWORD  callAddr = (MESSAGEBOXADDR - (pOptionHeader->ImageBase+((DWORD)(codeBegin+0xD) - (DWORD)pImageBuffer)));
    *(PDWORD)(codeBegin+9) = callAddr;
    //修改E9
    DWORD jmpAddr = ((pOptionHeader->ImageBase + pOptionHeader->AddressOfEntryPoint) - (pOptionHeader->ImageBase + ((DWORD)codeBegin+SHELLCODELENGTH- (DWORD)pImageBuffer)));
    *(PDWORD)(codeBegin + 0xE) = jmpAddr; 
	//修改OEP
    pOptionHeader->AddressOfEntryPoint = (DWORD)codeBegin - (DWORD)pImageBuffer;
  
    //ImageBuffer-NewBuffer
    size = CopyImageBufferToNewBuffer(pImageBuffer,&pNewBuffer);
    if(size==0 || !pNewBuffer)
    {
        printf("ImageBuffer-->NewBuffer失败");
 	    free(pFileBuffer); 
	    free(pImageBuffer);
	    return;
   }
   //NewBuffer-->文件
   isOK = MemeryTOFile(pNewBuffer,size,FILEPATH_OUT);
   if(isOK)
   {
       printf("存盘成功");
	   free(pFileBuffer);
       free(pImageBuffer);
       free(pNewBuffer);
       return;
  }

}

//测试函数 向数据段空白闲添加代码
VOID TestAddCodeInExpSec()
{
}
//测试函数:打印目录项
VOID TestPrintDricetory()
{
}
//测试函数:打印输出表
VOID TestPrintExport()
{
}
//测试函数:通过函数名获得地址 成功返回函数RVA 失败返回0
DWORD TestGetFunctionAddrByName(PSTR pszFunctionName)
{
	return 0;
}
#if !defined(AFX_GLOBLE_H__6E197AFF_5DAE_4435_99CC_3760AFDFB99E__INCLUDED_)
#define AFX_GLOBLE_H__6E197AFF_5DAE_4435_99CC_3760AFDFB99E__INCLUDED_


#include <windows.h>

//全局变量声明
extern BYTE shellcode[];
//函数声明
//****************************************************************************
//ReadPEFile:将文件读取到缓冲区
//参数说明:
//lpszFile 文件路径
//pFileBuffer 缓冲区指针
//返回值说明
//读取失败返回0 否则返回实际读取的大小
//****************************************************************************
DWORD ReadPEFile(IN LPSTR lpszFile,OUT LPVOID*  pFileBuffer);
//****************************************************************************
//CopyFileBufferToImageBuffer:将文件从FileBuffer复制到ImageBuffer
//参数说明:
//pFileBuffer  FileBuffer指针
//pImageBuffer ImageBuffer指针
//返回值说明:
//读取失败返回0 否则返回复制的大小
//****************************************************************************
DWORD CopyFileBufferToImageBuffer(IN LPVOID  pFileBuffer,OUT LPVOID*  pImageBuffer);
//CopyImageBuffertoNewBuffer:将ImageBuffer中的数据复制到新的缓冲区
//参数说明:
//PImageBuffer ImageBuffer指针
//pNewBuffer NewBuffer指针
//返回值说明:
//读取失败返回0 否则返回复制的大小
//****************************************************************************
DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer,OUT LPVOID* pNewBuffer);
//****************************************************************************
//MemeryTOFile:将内存中的数据复制到文件
//参数说明:
//pMemBuffer 内存中的数据的指针
//size 要复制的大小
//lpszFile 要存储的文件路径
//返回值说明:
//读取失败返回0 否则返回复制大小
//****************************************************************************
BOOL MemeryTOFile(IN LPVOID pMemBuffer,IN size_t size,OUT LPSTR lpszFile);
//****************************************************************************
//RvaToFileOffset:将内存变异转换文件偏移
//参数说明:
//pFileBuffer FileBuffer指针
//dwRva RVA的值
//返回值说明
//返回转换后的FOA的值 如果失败返回0
//****************************************************************************
DWORD RavToFileOffset(IN LPVOID pFileBuffer,IN DWORD dwRva);
//测试函数:打印NT头
VOID TestPrintNTHeaders();
//测试函数 文件-->FileBuffer-->ImageBuffer-NewBuffer-->存盘
VOID TestPELoader();
//测试函数:向代码段空闲区添加代码
VOID TestAddCodeInCodeSec();
//测试函数 向数据段空白闲添加代码
VOID TestAddCodeInExpSec();
//测试函数:打印目录项
VOID TestPrintDricetory();
//测试函数:打印输出表
VOID TestPrintExport();
//测试函数:通过函数名获得地址 成功返回函数RVA 失败返回0
DWORD TestGetFunctionAddrByName(PSTR pszFunctionName);

#endif //
// PETool.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Globle.h"
int main(int argc, char* argv[])
{
	

	//
    
	//

	TestAddCodeInCodeSec();
	printf("Hello World!\n");
	return 0;
}

抱歉,OpenCVSharp并不直接支持"滴水算法"(也称为域生长),这是一个基于图像处理和像素连接的经典计算机视觉技术,通常用于分割图像。OpenCVSharp是C#编写的OpenCV接口库,它主要用于与原生OpenCV库交互,而不是直接提供完整的算法实现。 然而,你可以使用OpenCVSharp来实现滴水算法的一些基本步骤,如阈值化、腐蚀膨胀、域生长等。下面是一个简单的示例,展示了如何使用OpenCVSharp进行二值图像的域生长: ```csharp using Emgu.CV; using Emgu.CV.Structure; // 假设img是已经处理过的灰度图像 Mat src = new Mat("image.jpg", ImreadModes.GrayScale); // 转换成8位单通道图像 Mat gray = src.Clone(); gray.CvtColor(Color.Bgr2Gray, ColorConversionCodes.Bgr2Gray); // 应用阈值以创建二值图像 double thresholdValue = 128; // 根据图像调整这个值 Mat binaryImage = new Mat(); threshold(gray, binaryImage, thresholdValue, 255, ThresholdType.Binary); // 初始化种子点(通常是前景像素) Point seedPoint = new Point(10, 10); bool[] visited = new bool[src.Rows * src.Cols]; // 域生长函数(这里简化,仅展示基本思路) void RegionGrowth(Point seed, Mat& image) { // 从种子开始 visited[seed.Y * src.Cols + seed.X] = true; // 检查相邻像素 for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++) { if (y == 0 && x == 0) continue; // 忽略自身 Point pixel = new Point(seed.X + x, seed.Y + y); if (pixel.X >= 0 && pixel.X < src.Cols && pixel.Y >= 0 && pixel.Y < src.Rows && image.At<byte>(pixel) != 0 && !visited[pixel.Y * src.Cols + pixel.X]) { visited[pixel.Y * src.Cols + pixel.X] = true; // 对这些像素应用相同的操作(比如染色) } } } // 运行域生长 RegionGrowth(seedPoint, binaryImage); // 显示结果 binaryImage.Show(); ``` 请注意,这只是一个基础示例,实际应用中可能需要更复杂的条件判断和优化。你可以在网上找到更详细的滴水算法教程来进一步学习。如果你想要使用OpenCVSharp的高级功能,建议查阅官方文档或社资源。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值