首页
社区
课程
招聘
[原创]清除 PE 文件里的数字签名
发表于: 2011-9-3 21:42 16462

[原创]清除 PE 文件里的数字签名

2011-9-3 21:42
16462
在 PE 可选头的数据目录里,DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] 保存着数字签名的位置和大小。要清除数字签名,只要根据这些信息删除掉数字签名,再把字段清零就可以了。
关键代码如下:

先把文件映射到内存:
__forceinline LPVOID MapPeFile(LPCWSTR pwzFile, PLARGE_INTEGER lpFileSize)
{
	if (StrSafeLen(pwzFile) <= 0) // 如果传入的文件路径为空
		return NULL;

	HANDLE hFile = CreateFileW(pwzFile,
						GENERIC_READ,
						FILE_SHARE_READ,
						NULL,
						OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL,
						NULL);

	if (INVALID_HANDLE_VALUE == hFile)
		return NULL;

	GetFileSizeEx(hFile, lpFileSize);
	HANDLE hMapFile = CreateFileMappingW(hFile,
							NULL,
							PAGE_READONLY,
							0,
							0,
							NULL);

	CloseHandle(hFile);

	if (NULL == hMapFile)
		return NULL;

	LPVOID pRet = MapViewOfFile(hMapFile,
						FILE_MAP_READ,
						0,
						0,
						0);

	CloseHandle(hMapFile);

	return pRet;
}


判断 PE 文件是否有效
// 判断 PE 文件格式是否是无效的
__forceinline BOOL IsInvalidPe(LPVOID pBase)
{
	if (NULL == pBase)
		return TRUE;

	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBase;
	if (IMAGE_DOS_SIGNATURE != pDosHeader->e_magic)
		return TRUE;

	PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pBase + pDosHeader->e_lfanew);
	if (IMAGE_NT_SIGNATURE != pNtHeaders->Signature)
		return TRUE;

	return FALSE;
}


再获取数字签名的位置和大小:
__forceinline BOOL GetPeSignOffsetAndSize(LPVOID pBase, LPDWORD lpOffset, LPDWORD lpSize)
{
	if (NULL == pBase || NULL == lpOffset || NULL == lpSize)
		return FALSE;

	*lpOffset = *lpSize = 0;

	if (IsInvalidPe(pBase))
		return FALSE;

	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBase;
	PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pBase + pDosHeader->e_lfanew);
	*lpOffset = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
	*lpSize = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;

	if (0 == *lpOffset || 0 == *lpSize)
		return FALSE;

	return TRUE;
}


清除数字签名:
__forceinline BOOL RemovePeSign(LPVOID pBase, PLARGE_INTEGER lpFileSize, LPCWSTR pwzNewFile)
{
	BOOL bRet = FALSE;

	if (NULL == pBase || NULL == lpFileSize)
		return FALSE;

	if (IsInvalidPe(pBase))
		return FALSE;

	DWORD dwOffset;
	DWORD dwSize;

	GetPeSignOffsetAndSize(pBase, &dwOffset, &dwSize);

	if (0 == dwOffset || 0 == dwSize)
		return FALSE;

	LPVOID pNewBase = VirtualAlloc(NULL, lpFileSize->LowPart, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == pNewBase)
		return FALSE;

	DWORD dwRealFileSize = lpFileSize->LowPart - dwSize;
	memcpy(pNewBase, pBase, dwRealFileSize);
	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pNewBase;
	PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pNewBase + pDosHeader->e_lfanew);
	pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = 0;
	pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = 0;
	pNtHeaders->OptionalHeader.CheckSum = 0;
	// 重新计算校检和
	DWORD dwHeaderSum, dwCheckSum;
	CheckSumMappedFile(pNewBase, dwRealFileSize, &dwHeaderSum, &dwCheckSum);
	pNtHeaders->OptionalHeader.CheckSum = dwCheckSum;

	HANDLE hFile = CreateFile(pwzNewFile,
						GENERIC_WRITE,
						FILE_SHARE_READ,
						NULL,
						CREATE_ALWAYS,
						FILE_ATTRIBUTE_NORMAL,
						NULL);

	if (INVALID_HANDLE_VALUE == hFile)
		goto _exit;

	DWORD dwBytes;
	bRet = WriteFile(hFile, pNewBase, dwRealFileSize, &dwBytes, NULL);
	CloseHandle(hFile);
_exit:
	VirtualFree(pNewBase, 0, MEM_RELEASE);

	return bRet;
}


最后的清理工作:
__forceinline void UnmapPeFile(LPVOID pBase)
{
	if (NULL != pBase)
		UnmapViewOfFile(pBase);
}


一个简单的图形界面:

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 6
支持
分享
最新回复 (9)
雪    币: 2307
活跃值: (983)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
沙发支持
2011-9-3 21:45
0
雪    币: 237
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我一直用 stub_pe,也很便捷,就是删除末尾添加节,再编辑pe头里面的证书偏移为0
一直懒得自己写程序
2011-9-3 22:09
0
雪    币: 1751
活跃值: (1611)
能力值: ( LV12,RANK:222 )
在线值:
发帖
回帖
粉丝
4
以前用的CELESIGN,不错,这个更小巧了。
2011-9-3 22:59
0
雪    币: 153
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
对 SpeedCommander 这一招不管用...
http://www.speedproject.de/download.html
2011-9-4 00:40
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
6
数字签名已经清除了,是因为没有认证的数字签名,被提示的。
2011-9-4 01:58
0
雪    币: 249
活跃值: (71)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7
部分程序清除之后直接失效
2011-10-5 09:31
0
雪    币: 109
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
嗯。没有全部成功
2011-10-5 09:39
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
9
数字签名效验技术
2011-10-5 14:22
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
10
顶啊!!!!!!!!!!!!!!!!!
2011-10-5 14:23
0
游客
登录 | 注册 方可回帖
返回
//