⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 canreloc.cpp

📁 此为本书的配套光盘.本书不但由浅入深地讲解了软件保护技术
💻 CPP
字号:
/********************************************************************

	Copyright (c) Beijing Feitian Technologies
	http://www.FTSafe.com

	File :		CanReloc.cpp	

	Created:	2003/11/04

	Author:		yihai
	
	Purpose:	?

	Revision:	?

*********************************************************************/
#include <windows.h>

extern "C"
{
#define	__countof(a)	sizeof(a)/sizeof(a[0])
#define		DEFAULT_LINK_BASE	0x10000000

typedef HMODULE (WINAPI *TPFN_LoadLibrary)(IN  LPCSTR lpLibFileName );
typedef FARPROC (WINAPI *TPFN_GetProcAddress)( IN HMODULE hModule, IN LPCSTR lpProcName );
typedef BOOL	(WINAPI *TPFN_FreeLibrary)( IN OUT HMODULE hLibModule );
typedef int		(WINAPI *TPFN_MessageBox)( IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);
typedef void	(WINAPI *TPFN_OldDllEntry)(HANDLE  hDllHandle,DWORD   dwReason,LPVOID  lpreserved);

//使用1作为变量的初值以保证所有的变量在可执行文件中的顺序与源码中的顺序相一致
PDWORD	g_shl_p_ref_IAT_addr=(PDWORD)1;
PDWORD  pFirstAPI=(PDWORD)1;
DWORD   g_shl_peek_reloc_item_offset=1;

TPFN_LoadLibrary	g_pLoadLibrary=(TPFN_LoadLibrary)1;
TPFN_GetProcAddress g_pGetProcAddress=(TPFN_GetProcAddress)1;
TPFN_FreeLibrary	g_pFreeLibrary=(TPFN_FreeLibrary)1;
TPFN_MessageBox		g_pMessageBox=(TPFN_MessageBox)1;

DWORD	g_shl_old_entry=1;
PDWORD	g_shl_p_old_IAT_addr=(PDWORD)1;
DWORD	g_shl_old_IAT_size=1;
PDWORD	g_shl_p_new_IAT_addr=(PDWORD)1;

char	szMsgStartUp[64]="MessageStartUp";
char	szUser32[64]="USER32.DLL";
char	szMessageBox[64]="MessageBoxA";

//begin dumpreloc
DWORD g_shl_basereloc_item[] = {
	0x0000100B, 0x00001010, 0x00001017, 0x00001025, 0x0000102E
}; //end of g_shl_basereloc_item

//end dumpreloc

//声明一个结构体成员映射所有的全局变量
typedef struct tagMY_REF_DATA
{	
	PDWORD	g_shl_p_ref_IAT_addr;
	PDWORD  pFirstAPI;
	DWORD	g_shl_peek_reloc_item_offset;

	TPFN_LoadLibrary	g_pLoadLibrary;
	TPFN_GetProcAddress g_pGetProcAddress;
	TPFN_FreeLibrary	g_pFreeLibrary;
	TPFN_MessageBox		g_pMessageBox;	

	DWORD	g_shl_old_entry;
	PDWORD	g_shl_p_old_IAT_addr;
	DWORD	g_shl_old_IAT_size;
	PDWORD	g_shl_p_new_IAT_addr;

	char	szMsgStartUp[64];
	char	szUser32[64];
	char	szMessageBox[64];
	DWORD   g_shl_basereloc_item[5];
}MY_REF_DATA,*PMY_REF_DATA;

#pragma warning( disable : 4035)

DWORD PopRealAddr()
{
	__asm pop  eax
}

DWORD PrePopRealAddr()
{
	__asm call PopRealAddr
}

#pragma warning( default : 4035)

DWORD CalcDataSize();
DWORD CalcFuncSize();

//取得所有全局变量数据块的首地址
PMY_REF_DATA Seek_MyDataPos()
{	
	DWORD dwAddr = PrePopRealAddr();
	dwAddr -= 5;	//减掉call PopRealAddr指令本身的5个字节
	DWORD dwDataSize = CalcDataSize();
	DWORD dwFuncSize = CalcFuncSize();	
	dwAddr -= dwFuncSize;	
	PMY_REF_DATA pMyData = (PMY_REF_DATA)(dwAddr - dwDataSize);

	return pMyData;
}

//计算PopRealAddr函的代码长度
DWORD CalcFuncSize()
{
	DWORD dwFunSize = ((DWORD)PrePopRealAddr) - ((DWORD)PopRealAddr);
	return dwFunSize;
}

//计算所有的全局变量的数据长度
DWORD CalcDataSize()
{
	DWORD dwDataSize = sizeof(MY_REF_DATA);	
	return dwDataSize;
}

//取得运行时基地址
DWORD  CalcRunTimeImageBase(PMY_REF_DATA pData)
{
	PBYTE p = (PBYTE)(&pData->g_shl_peek_reloc_item_offset);	
	p += pData->g_shl_peek_reloc_item_offset;
	PDWORD pValue = (PDWORD)p;
	return *pValue;
}

//取得API的首地址
void Seek_FirstAPI(PMY_REF_DATA pData)
{
	DWORD dwRefIAT = (DWORD)pData->g_shl_p_ref_IAT_addr;	//取得壳中所使用的第一个API的首地址

	DWORD dwBase = CalcRunTimeImageBase(pData);
	
	dwRefIAT-=DEFAULT_LINK_BASE;	//由于使用了peek参数,所以要手工重定位dwRefIAT
	dwRefIAT+=dwBase;

	PDWORD pRefIAT = (PDWORD)dwRefIAT;
	pData->pFirstAPI = pRefIAT;
}

//定位API LoadLibrary
void Seek_LoadLibrary(PMY_REF_DATA pData)
{
	pData->g_pLoadLibrary = (TPFN_LoadLibrary)(pData->pFirstAPI[0]);
}

//定位API GetProcAddress
void Seek_GetProcAddress(PMY_REF_DATA pData)
{
	pData->g_pGetProcAddress = (TPFN_GetProcAddress)(pData->pFirstAPI[1]);
}

//定位API FreeLibrary
void Seek_FreeLibrary(PMY_REF_DATA pData)
{
	pData->g_pFreeLibrary = (TPFN_FreeLibrary)(pData->pFirstAPI[2]);
}

void RelocIt(PDWORD pReloc,DWORD dwBase)
{
	DWORD dwValue = *pReloc;
	PBYTE pData = (PBYTE)dwValue;
	pData += dwBase;
	PDWORD pdwData = (PDWORD)pData;
	*pdwData -= DEFAULT_LINK_BASE;
	*pdwData += dwBase;
}

void SelfReloc(PMY_REF_DATA pData)
{	
	DWORD dwBase = CalcRunTimeImageBase(pData);
	if(dwBase==DEFAULT_LINK_BASE)
		return;
	
	int nCount = __countof(pData->g_shl_basereloc_item);
	PDWORD pReloc = pData->g_shl_basereloc_item;
	for(int i=0;i<nCount;i++,pReloc++)
	{	
		RelocIt(pReloc,dwBase);		
	}
}

void shell_init(PMY_REF_DATA pData)						//恢复加壳前程序的引入函数表
{
	DWORD dwBase = CalcRunTimeImageBase(pData);
	if(dwBase != DEFAULT_LINK_BASE)
	{
		//以手方式重定位g_shl_old_entry g_shl_p_old_IAT_addr g_shl_p_new_IAT_addr
		PDWORD p = (PDWORD)(&pData->g_shl_old_entry);
		*p -= DEFAULT_LINK_BASE;
		*p += dwBase;

		p = (PDWORD)(&pData->g_shl_p_old_IAT_addr);		
		*p -= DEFAULT_LINK_BASE;
		*p += dwBase;

		p = (PDWORD)(&pData->g_shl_p_new_IAT_addr);
		*p -= DEFAULT_LINK_BASE;
		*p += dwBase;		
	}	
	memcpy(pData->g_shl_p_old_IAT_addr,pData->g_shl_p_new_IAT_addr,pData->g_shl_old_IAT_size);
}

BOOL WINAPI ShellDllStartupEntry(HANDLE  hDllHandle,
								 DWORD   dwReason,
						LPVOID  lpreserved
		)
{
	PMY_REF_DATA pData = Seek_MyDataPos();
	if(dwReason == DLL_PROCESS_ATTACH)
	{		
		Seek_FirstAPI(pData);
		
		Seek_LoadLibrary(pData);		
		Seek_GetProcAddress(pData);	
		Seek_FreeLibrary(pData);

		HMODULE  hMod = pData->g_pLoadLibrary(pData->szUser32);	
		TPFN_MessageBox pBox =(TPFN_MessageBox) pData->g_pGetProcAddress(hMod,pData->szMessageBox);		
		pBox(0,pData->szMsgStartUp,0,MB_OK);
		
		SelfReloc(pData);
		shell_init(pData);
	}		
	TPFN_OldDllEntry pfnOldDllEntry = (TPFN_OldDllEntry)pData->g_shl_old_entry;
	pfnOldDllEntry(hDllHandle,dwReason,lpreserved);
	return TRUE;
}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -