stub.cpp

来自「一些初级的网络编程」· C++ 代码 · 共 539 行 · 第 1/2 页

CPP
539
字号
// Stub.cpp : Defines the entry point for the DLL application.
//
#define  WIN32_LEAN_AND_MEAN

#include <windows.h>

#include "gev.h"
#include "depack.h"
#include "tea.h"

// linker directive for data section
#pragma data_seg(".a$A")
__declspec(allocate(".a$A")) extern GLOBAL_EXTERNAL_VARS gev = { 0 };
#pragma data_seg()

// linker directive to change entry point, merge data sections and change file allignment
#pragma comment(linker, "/entry:\"StubEntryPoint\"")
#pragma comment(linker, "/MERGE:.data=.a")

// thread local storage callback
extern "C" void NTAPI TlsCallback(PVOID DllHandle, DWORD Reason, PVOID Reserved);

// function pointer defs
typedef HGLOBAL (__stdcall *PFNGLOBALALLOC)(UINT, SIZE_T);
typedef HGLOBAL (__stdcall *PFNGLOBALFREE)(HGLOBAL);
typedef BOOL (__stdcall *PFNISDEBUGGERPRESENT)(void);
typedef VOID (__stdcall *PFNEXITPROCESS)(UINT);
typedef BOOL (__stdcall *PFNVIRTUALPROTECT)(LPVOID, SIZE_T, DWORD, PDWORD);


// globals
DWORD dwLoadAddress = 0;

// function pointers
PFNGLOBALALLOC pfnGlobalAlloc;
PFNGLOBALFREE pfnGlobalFree;
PFNISDEBUGGERPRESENT pfnIsDebugerPresent;
PFNEXITPROCESS pfnExitProcess;
PFNVIRTUALPROTECT pfnVirtualProtect;

//  thread local storage support
DWORD dwTlsSlotIndex = 0;
bool fSafeToCallback = false;
bool fDelayedTlsCallback = false;
PVOID tlsDllHandle = 0;
DWORD tlsReason = 0;
PVOID tlsReserved = 0;

// function defs
void main();	// real main (non naked function)
void GetLoadAddress();
void Jump();
void Decrypt();
void ResolveImports();
void CopyResources(PIMAGE_RESOURCE_DIRECTORY pSourceRoot, PIMAGE_RESOURCE_DIRECTORY pDestinationRoot);
void FinaliseTlsStuff();
void DecryptVars();
void CheckDebugger();
void SetupFuncs();

// crypted strings
char* StringDecrypt(unsigned char* source);
BYTE szKey[] = {0x84, 0x36, 0x2E, 0x23, 0x10, 0xB0, 0x1D, 0x36, 0x97, 0x77, 0x47, 0x45, 0x00};		// Needs to match that in packer (_DEBUG) code
BYTE szRsrc[] = {0x23, 0xD5, 0xC8, 0xF7, 0x9E, 0x00};
BYTE szKernel32[] = {0x37, 0x27, 0xBC, 0xC1, 0xA2, 0x86, 0x47, 0x58, 0x23, 0xC3, 0xD7, 0xE9, 0x00};
BYTE szGlobalAlloc[] = {0xC1, 0xCE, 0xEE, 0xCD, 0xB9, 0xB2, 0x0D, 0x87, 0x61, 0xC8, 0xD8, 0x00};
BYTE szGlobalFree[] = {0x8D, 0x07, 0xBC, 0xA0, 0x3C, 0xA9, 0x7A, 0xF9, 0x68, 0xC2, 0x00};
BYTE szIsDebuggerPresent[] = {0x7F, 0x56, 0xE0, 0xE4, 0xAF, 0xD0, 0x88, 0x2B, 0x03, 0xD1, 0xB8, 0x66, 0xD5, 0xBF, 0x45, 0xF5, 0x79, 0x00};
BYTE szExitProcess[] = {0x38, 0x40, 0xA2, 0x3D, 0xE3, 0x60, 0xFD, 0xC8, 0x68, 0xD4, 0xC8, 0x00};
BYTE szVirtualProtect[] = {0xB2, 0x88, 0x5A, 0x3D, 0x8F, 0x73, 0xB1, 0x5B, 0x7F, 0xC8, 0xCF, 0xE0, 0x9E, 0xFF, 0x00};

// our exe stub's entry point
void __declspec(naked) StubEntryPoint()
{
	main();
}

void main()
{
	SetupFuncs();
	CheckDebugger();
	DecryptVars();
	GetLoadAddress();
	Decrypt();
	ResolveImports();
	FinaliseTlsStuff();
	Jump();
}

void ResolveImports()
{
	IMAGE_IMPORT_DESCRIPTOR* pIID;
	IMAGE_THUNK_DATA* pThunk;
	IMAGE_IMPORT_BY_NAME* pImport;

	DWORD dwTemp;
	DWORD dwResult;
	DWORD* pAddress;
	HMODULE hMod;
	BOOL bDestroyName;
	DWORD dwOldProtect;

	PIMAGE_DOS_HEADER pDosHdr;
	PIMAGE_NT_HEADERS pNtHdr;
	PIMAGE_SECTION_HEADER pSecHdr;
	DWORD dwSecStart;
	DWORD dwKatSup;
	LONG lJmp;
	WORD wNumSections;
	WORD wSizeO;
	int i;

	pDosHdr = (PIMAGE_DOS_HEADER)dwLoadAddress;
	lJmp = pDosHdr->e_lfanew;
	dwKatSup = (DWORD)pDosHdr;
	dwKatSup += lJmp;

	pNtHdr = (PIMAGE_NT_HEADERS)dwKatSup;

	wNumSections = pNtHdr->FileHeader.NumberOfSections;
	wSizeO = pNtHdr->FileHeader.SizeOfOptionalHeader;

	dwSecStart = (DWORD)pNtHdr;
	dwSecStart += 24;
	dwSecStart += wSizeO;

	dwTemp = gev.dwIATAddress + dwLoadAddress;

	for(i = 0; i < wNumSections-1; i++)
	{
		pSecHdr = (PIMAGE_SECTION_HEADER)dwSecStart;

		if((dwTemp >= (pSecHdr->VirtualAddress + dwLoadAddress)) && (dwTemp < ((pSecHdr->VirtualAddress + dwLoadAddress) + pSecHdr->Misc.VirtualSize)))
		{
			pfnVirtualProtect((void*)(pSecHdr->VirtualAddress + dwLoadAddress), pSecHdr->Misc.VirtualSize, PAGE_READWRITE, &dwOldProtect);
			break;
		}

		dwSecStart += sizeof(IMAGE_SECTION_HEADER);
	}
	
	pIID = (IMAGE_IMPORT_DESCRIPTOR*)dwTemp;

	while(pIID)
	{
		if(pIID->OriginalFirstThunk)
		{
			dwTemp = pIID->OriginalFirstThunk + dwLoadAddress;
			pThunk = (IMAGE_THUNK_DATA*)dwTemp;
		}
		else if(pIID->FirstThunk)
		{
			dwTemp = pIID->FirstThunk + dwLoadAddress;
			pThunk = (IMAGE_THUNK_DATA*)dwTemp;
		}
		else
		{
			break;
		}

		dwTemp = (DWORD)pThunk->u1.Function + dwLoadAddress;
		pImport = (IMAGE_IMPORT_BY_NAME*)dwTemp;

		dwTemp = (DWORD)pIID->Name + dwLoadAddress;
		hMod = LoadLibrary((LPCSTR)dwTemp);

		if(hMod != INVALID_HANDLE_VALUE)
		{
			FillMemory((void*)dwTemp, strlen((LPCSTR)dwTemp), 0);
			//memset((void*)dwTemp, 0, strlen((LPCSTR)dwTemp));

			dwTemp = (DWORD)pIID->FirstThunk + dwLoadAddress;
			pAddress = (DWORD*)dwTemp;

			while(pThunk->u1.Function)
			{
				dwTemp = (DWORD)pThunk->u1.Function;

				if(dwTemp & IMAGE_ORDINAL_FLAG32)
				{
					dwTemp = (DWORD)pThunk->u1.Function & 0x0000ffff;
					bDestroyName = FALSE;
				}
				else
				{
					dwTemp = (DWORD)pImport->Name;
					bDestroyName = TRUE;
				}

				dwResult = (DWORD)GetProcAddress(hMod, (LPCSTR)dwTemp);

				if(bDestroyName)
				{
					FillMemory((void*)pImport->Name, strlen((LPCSTR)pImport->Name), 0);
					//memset((void*)pImport->Name, 0, strlen((LPCSTR)pImport->Name));
					
					FillMemory((void*)pThunk, sizeof(IMAGE_THUNK_DATA), 0);
					//memset((void*)pThunk, 0, sizeof(IMAGE_THUNK_DATA));
				}
				
				*pAddress = dwResult;
				pAddress++;
				pThunk++;

				dwTemp = (DWORD)pThunk->u1.Function + dwLoadAddress;
				pImport = (IMAGE_IMPORT_BY_NAME*)dwTemp;
			}
		}

		FillMemory((void*)pIID, sizeof(IMAGE_IMPORT_DESCRIPTOR), 0);
		//memset((void*)pIID, 0, sizeof(IMAGE_IMPORT_DESCRIPTOR));

		pIID++;
	}

	pfnVirtualProtect((void*)(pSecHdr->VirtualAddress + dwLoadAddress), pSecHdr->Misc.VirtualSize, dwOldProtect, &dwOldProtect);
}

inline void Decrypt()
{
	PIMAGE_DOS_HEADER pDosHdr;
	PIMAGE_NT_HEADERS pNtHdr;
	PIMAGE_SECTION_HEADER pSecHdr;
	DWORD dwSecStart;
	DWORD dwKatSup;
	LONG lJmp;
	WORD wNumSections;
	WORD wSizeO;
	int i;
	bool bResource;
	DWORD dwOldProtect;

	pDosHdr = (PIMAGE_DOS_HEADER)dwLoadAddress;
	lJmp = pDosHdr->e_lfanew;
	dwKatSup = (DWORD)pDosHdr;
	dwKatSup += lJmp;

	pNtHdr = (PIMAGE_NT_HEADERS)dwKatSup;

	wNumSections = pNtHdr->FileHeader.NumberOfSections;
	wSizeO = pNtHdr->FileHeader.SizeOfOptionalHeader;

	dwSecStart = (DWORD)pNtHdr;
	dwSecStart += 24;
	dwSecStart += wSizeO;

	char* rsrc = StringDecrypt(szRsrc);

	for(i = 0; i < wNumSections-1; i++)
	{
		// Reset resource flag
		bResource = false;

		pSecHdr = (PIMAGE_SECTION_HEADER)dwSecStart;

		// check if this is the resource section
		if(strcmp((char*)pSecHdr->Name, rsrc) == 0) bResource = true;

		// skip sections with raw size = 0
		if(pSecHdr->SizeOfRawData == 0)
		{
			dwSecStart += sizeof(IMAGE_SECTION_HEADER);
			continue;
		}

		//BYTE* lpbDecompBuffer = (BYTE*)pfnGlobalAlloc(GPTR, pSecHdr->Misc.VirtualSize);
		BYTE* lpbDecompBuffer = (BYTE*)pfnGlobalAlloc(GPTR, pSecHdr->SizeOfRawData);
		BYTE* lpbDestination = 0;
		BYTE* lpbResourceBuffer = 0;
		

⌨️ 快捷键说明

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