注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

从C开始

 
 
 

日志

 
 

清除 PE 文件里的数字签名  

2011-10-06 17:43:46|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
在 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);
}
  评论这张
 
阅读(1437)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018