首页
社区
课程
招聘
[原创]PEArmor 0.46 静态脱壳机原理及源码
发表于: 2009-3-12 22:41 10273

[原创]PEArmor 0.46 静态脱壳机原理及源码

2009-3-12 22:41
10273

  首先感谢天草老师,这些天跟他学习到了不少东西。这个其实是他布置的作业,给大家分享下成果。
      PEArmor这个壳特点:1、aplib压缩 2、IAT加密 3、程序Call和Jmp跳入壳里然后解密执行真api(不知道密届术语)。壳分两层外壳,第一层解压出第二层外壳,然后跳入第二层外壳去执行(第二层开始处大量花),第二层解压出各个段,接着还原IAT,再根据加密表把程序代码里的 call和jmp指向外壳,跳向oep。
    首先我找第一层壳的入口,找需要解压二层外壳所需要的相关数据的偏移,解压二层外壳。

	//*************************************************************************
	//搜索特征码,在壳第一层找真正壳代码入口。
	//*************************************************************************
	BYTE szPCode1[] = "\x5D\x81\xED\x05\x00\x00\x00\x8D\x75\x3D\x56";
	shellstart = searchMem(pPEImage,szPCode1,sizeof(szPCode1));
	if (shellstart == NULL)
	{
		return FALSE;
	}

BYTE * FistPackBaseAddr = NULL;
	DWORD  dwFirstPackSize = 0;   
	HANDLE hFistPackTempMem = 0;
//*************************************************************************
//    解压第二层外壳
 //*************************************************************************
	   __try
	   {
		   FistPackBaseAddr = shellstart - 0xAF;
		   dwFirstPackSize  = GETDWORD(FistPackBaseAddr + 0x82);
		   hFistPackTempMem = VirtualAlloc(NULL,dwFirstPackSize, MEM_COMMIT, PAGE_READWRITE);
		   aP_depack_asm((PVOID)(GETDWORD(FistPackBaseAddr+0x7e)+FistPackBaseAddr),(PVOID)hFistPackTempMem);
	   }
	   __except(EXCEPTION_EXECUTE_HANDLER)
	   {
		   VirtualFree(hFistPackTempMem,dwFirstPackSize,MEM_RELEASE);
		   return FALSE;
	   }

//*************************************************************************
//搜索特征码,在壳第二层找真正壳代码入口(跳过无数花,准确定位,同时也确认是当前版本的壳)。
//*************************************************************************

	   BYTE szPCode2[] = "\xE8\x00\x00\x00\x00\x5A\x83\xEA\x05\x5D\xB9\x03\x00\x00\x00";
	   
	   shellstart2 = searchMem((BYTE *)hFistPackTempMem,szPCode2,sizeof(szPCode2));
	   
	   if (shellstart2 == NULL)
	   {
		   return FALSE;
	   }
BOOL CPEArmor046UnPack::unPackEachSection()
{

	   __try
	   {
		   DWORD dwOffset = 0x2ED;
		   while (GETDWORD(shellstart2 + dwOffset)!=0)
		   {
			   DWORD dwCurrentSectionSize = GETDWORD(shellstart2 + dwOffset);
			   HANDLE hEachSectionTempMem = VirtualAlloc(NULL,dwCurrentSectionSize, MEM_COMMIT, PAGE_READWRITE);
			   DWORD dwEachSectionPackDataAddr = GETDWORD(shellstart2 + dwOffset + 0x4) + (DWORD)pImage;
			   aP_depack_asm((PVOID)(dwEachSectionPackDataAddr),(PVOID)hEachSectionTempMem);
			   memcpy((PVOID)dwEachSectionPackDataAddr,(PVOID)hEachSectionTempMem,dwCurrentSectionSize);
			   VirtualFree(hEachSectionTempMem,dwCurrentSectionSize,MEM_RELEASE);
			   dwOffset += 0xC;
		   }
	   }
	   
	   __except(EXCEPTION_EXECUTE_HANDLER)
	   {
		   return FALSE;
	   }
	   return TRUE;
}
BOOL CPEArmor046UnPack::analyzeImportTable()
{

				
	__try{
		
		BOOL blApiStrShuffle  = GETDWORD(shellstart2 + 0x2B8) == 1?TRUE:FALSE;
		
		
		if (blApiStrShuffle)  //IAT加密方式1
		{
			DWORD dwOrgImportaddr  = GETDWORD(shellstart2 + 0x2c0) + (DWORD)shellstart2;
			while (TRUE)
			{
				if (GETDWORD((PDWORD)(dwOrgImportaddr))==0)
				{
					break;
				}
				STOrgImport stOrgImportDataTemp ;
				stOrgImportDataTemp.dwThunkTable = GETDWORD((PDWORD)(dwOrgImportaddr));
				stOrgImportDataTemp.strdllName.assign((char *)(dwOrgImportaddr+5));
				stOrgImportDataTemp.dwApiNumber = GETDWORD((PBYTE)(dwOrgImportaddr + 5 + GETBYTE((PBYTE)(dwOrgImportaddr + 4)) + 1));
				dwOrgImportaddr = dwOrgImportaddr + 5 + GETBYTE(dwOrgImportaddr + 4) +5;
				BOOL blIsApiOrd = GETBYTE(dwOrgImportaddr)==0?TRUE:FALSE;
				stOrgImportDataTemp.isOrd = blIsApiOrd;
				if (blIsApiOrd) //序号
				{
					for (int i = 0 ; i < stOrgImportDataTemp.dwApiNumber;i++)
					{
						DWORD dwApiOrg = GETDWORD(dwOrgImportaddr+1);
						stOrgImportDataTemp.vecApiOrd.push_back(dwApiOrg);
						dwOrgImportaddr = dwOrgImportaddr + 1 + sizeof(DWORD) + 1;
					}
				}
				else  //APi名
				{
					for (int i = 0 ; i < stOrgImportDataTemp.dwApiNumber;i++)
					{
						string strApiName;
						strApiName.assign((char *)(dwOrgImportaddr+1));
						stOrgImportDataTemp.vecApiName.push_back(strApiName);
						dwOrgImportaddr = dwOrgImportaddr + 1 + GETBYTE(dwOrgImportaddr)+1;
					}
				}
				
				vecImport.push_back(stOrgImportDataTemp);
				
			}
			
		}
		else  // IAT不自定义存储格式的 (IAT加密方式2)
		{
			DWORD dwDllBase = GETDWORD(shellstart2 + 0x2c0) + (DWORD)pImage;
			
			DWORD dwApiOrdOrName = NULL;
			DWORD dwIatAddr = NULL;
			while(TRUE)
			{
				
				DWORD dwDllNameAddr = GETDWORD((PBYTE)dwDllBase + 0xc);
				if (dwDllNameAddr != 0)
				{
					
					dwDllNameAddr = dwDllNameAddr + (DWORD)pImage; //dllname
					
					
					if (GETDWORD(dwDllBase) !=0)
					{
						dwApiOrdOrName = GETDWORD(dwDllBase) + (DWORD)pImage;
						dwIatAddr = GETDWORD(dwDllBase + 0x10)+(DWORD)pImage;
					}
					else
					{
						dwApiOrdOrName = GETDWORD(dwDllBase + 0x10) + (DWORD)pImage;
						dwIatAddr = GETDWORD(dwDllBase + 0x10)+(DWORD)pImage;
					}
					
					
					STOrgImport stOrgImportDataTemp;
					if (GETDWORD(dwApiOrdOrName) & 0x80000000)
					{
						stOrgImportDataTemp.isOrd = TRUE;
					}
					else
					{
						stOrgImportDataTemp.isOrd = FALSE;
					}
					stOrgImportDataTemp.dwThunkTable = dwIatAddr - (DWORD)pImage;
					stOrgImportDataTemp.strdllName.assign((char *)dwDllNameAddr);
					
					
					
					while(TRUE)
					{
						if (GETDWORD(dwApiOrdOrName) == 0)
						{
							dwDllBase = dwDllBase + 0x14;
							
							vecImport.push_back(stOrgImportDataTemp);
							break;
						}
						else
						{
							//处理
							
							if ( GETDWORD(dwApiOrdOrName) & 0x80000000 )
							{
								DWORD dwOrd = GETDWORD(dwApiOrdOrName) & 0x7fffffff;
								stOrgImportDataTemp.vecApiOrd.push_back(dwOrd);
							}
							else
							{
								DWORD dwApiNameAddr = (GETDWORD(dwApiOrdOrName) + 2 ) + (DWORD)pImage;
								string strApiName;
								strApiName.assign((char *)dwApiNameAddr);
								stOrgImportDataTemp.vecApiName.push_back(strApiName);
							}
							
							dwApiOrdOrName = dwApiOrdOrName + 0x4;
							
							dwIatAddr = dwIatAddr + 0x4;
						}
					}
					
					
				}
				else
				{
					break;
				}
			}
		}
		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			return FALSE;
		}
		return TRUE;
}

[注意]APP应用上架合规检测服务,协助应用顺利上架!

上传的附件:
收藏
免费 8
支持
分享
最新回复 (7)
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好文,学习,感谢分享
2009-3-13 12:39
0
雪    币: 304
活跃值: (82)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
3
终于看到c++版的脱壳机了
2009-3-14 10:58
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
那位大牛转换成delphi的就好了
2009-3-19 09:44
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
做个现成的注册机不是更好吗?
2009-3-21 21:56
0
雪    币: 1262
活跃值: (825)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
注册机,这个跟注册机有什么关系?请教下。
2009-3-21 22:38
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
太牛叉了,终于见到VC源代码注册机了,非常感谢LZ分享。

带[Overlay]加PEArmor 0.46壳的软件,脱壳时在分析IAT的时候失败了 ,怎么回事?
2009-5-12 03:33
0
雪    币: 116
活跃值: (56)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
c++........好文,学习,感谢LZ
2009-5-14 09:51
0
游客
登录 | 注册 方可回帖
返回
//