core-packer/DllEntryPoint32.cpp
#include <Windows.h>
#define _UNPACKERSECTION
#ifdef _BUILD32
#include "symbols.h"
#include "dll32.h"
#include "reloc.h"
//#include "macro.h"
#include "decrypt.h"
#pragma section(".pedll32", read, write, execute)
struct _vtbl
{
VirtualProtect_ptr mem_protect;
VirtualAlloc_ptr mem_alloc;
CreateFileA_ptr file_open;
SetFilePointer_ptr file_seek;
};
//__declspec(allocate(".pedll32"))
//CONFIGURATION dll32_configuration = {
// 0xBABECAFEBAD00021,
// 0xBABECAFEBAD00020,
// 0xBABECAFEBAD00010,
// 0xBABECAFEBAD00011,
// 0xBABECAFEBAD00100,
// FALSE,
// NULL
//};
__declspec(allocate(".pedll32"))
ULONG64 dwRelocSize = 0xBABECAFEBAD00021;
__declspec(allocate(".pedll32"))
ULONG64 lpRelocAddress = 0xBABECAFEBAD00020;
__declspec(allocate(".pedll32"))
ULONG64 _rc4key0 = 0xBABECAFEBAD00010;
__declspec(allocate(".pedll32"))
ULONG64 _rc4key1 = 0xBABECAFEBAD00011;
__declspec(allocate(".pedll32"))
ULONG64 _baseAddress = 0xBABECAFEBAD00100;
// Fixed symbols from loader
//__declspec(allocate(".pedll32"))
//LoadLibraryA_ptr _dll32_LoadLibraryA = (LoadLibraryA_ptr) 0xBABECAFEBAD00004;
//__declspec(allocate(".pedll32"))
//GetProcAddress_ptr _dll32_GetProcAddress = (GetProcAddress_ptr) 0xBABECAFEBAD00003;
__declspec(allocate(".pedll32"))
VirtualProtect_ptr _VirtualProtect;
__declspec(allocate(".pedll32"))
VirtualAlloc_ptr _VirtualAlloc;
__declspec(allocate(".pedll32"))
HMODULE g_hKernel32;
extern "C" {
__declspec(allocate(".pedll32"))
BYTE g_decrypted = FALSE;
__declspec(allocate(".pedll32"))
LPVOID g_lpTextBaseAddr = (LPVOID) 0L;
}
__declspec(allocate(".pedll32"))
CRITICAL_SECTION _critical_section;
#pragma code_seg(".pedll32")
void __memcpy(LPVOID dst, LPVOID src, int size)
{
int dw = size / 4;
if (dw > 0)
{
size -= dw * 4;
DWORD *dDST = (DWORD *) dst;
DWORD *dSRC = (DWORD *) src;
while(dw-- > 0)
*dDST++ = *dSRC++;
}
char *cDST = (char *)dst;
char *cSRC = (char *) src;
while(size-- > 0)
{
*cDST++ = *cSRC++;
}
}
#pragma code_seg(".pedll32")
int __memcmp(char *dst, char *src, int size)
{
if ((size % 4) == 0)
{ // optimized version ..
size /= 4;
DWORD *dDST = (DWORD *) dst;
DWORD *dSRC = (DWORD *) src;
while(size-- > 0)
{
if (*dDST != *dSRC)
goto error;
dDST++; dSRC++;
}
goto done;
}
else if ((size % 2) == 0)
{ // optimized version ..
size /= 4;
WORD *wDST = (WORD *) dst;
WORD *wSRC = (WORD *) src;
while(size-- > 0)
{
if (*wDST != *wSRC)
goto error;
wDST++;
wSRC++;
}
goto done;
}
else
{
while(size-- > 0)
{
if (*dst != *src)
goto error;
dst++;
src++;
}
}
goto done;
error:
return -1;
done:
return 0;
}
#pragma code_seg(".pedll32")
char *__strcpy(char *destination, const char *source)
{
char *d = destination;
while(*source != 0x00)
{
*destination++ = *source++;
}
*destination = 0x00;
return d;
}
#pragma code_seg(".pedll32")
char *__strcat(char *destination, const char *source)
{
char *d = destination;
for(;*destination != 0x00; destination++);
{
__asm {
nop
}
}
__strcpy(destination, source);
return d;
}
#pragma code_seg(".pedll32")
__declspec(naked)
HMODULE WINAPI _dll32_LoadLibraryA(LPCTSTR lpFileName)
{
__asm
{
nop
nop
nop
mov eax, dword ptr [g_hKernel32]
add eax, 11223340h
jmp dword ptr ds:[eax]
nop
nop
nop
nop
nop
}
}
#pragma code_seg(".pedll32")
__declspec(naked)
LPVOID WINAPI _dll32_GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
__asm {
nop
nop
nop
mov eax, dword ptr [g_hKernel32]
add eax, 11223341h
jmp dword ptr [eax]
nop
nop
nop
nop
nop
}
}
#pragma code_seg(".pedll32")
__declspec(naked)
DWORD WINAPI _SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
{
__asm {
nop
nop
nop
mov eax, dword ptr [g_hKernel32]
add eax, 11223342h
jmp dword ptr [eax]
nop
nop
nop
nop
nop
}
}
#pragma code_seg(".pedll32")
__declspec(naked)
BOOL WINAPI _CloseHandle(HANDLE hObject)
{
__asm {
nop
nop
nop
mov eax, dword ptr [g_hKernel32]
add eax, 11223343h
jmp dword ptr [eax]
nop
nop
nop
nop
nop
}
}
#pragma code_seg(".pedll32")
__declspec(naked)
BOOL WINAPI _ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
{
__asm {
nop
nop
nop
mov eax, dword ptr [g_hKernel32]
add eax, 11223344h
jmp dword ptr [eax]
nop
nop
nop
nop
nop
}
}
#pragma code_seg(".pedll32")
__declspec(naked)
DWORD WINAPI _GetModuleFileNameA(HMODULE hModule, LPTSTR lpFileName, DWORD nSize)
{
__asm {
nop
nop
nop
mov eax, dword ptr [g_hKernel32]
add eax, 11223345h
jmp dword ptr [eax]
nop
nop
nop
nop
nop
}
}
#pragma code_seg(".pedll32")
__declspec(naked)
HANDLE WINAPI _CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttribytes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
_asm {
nop
nop
nop
mov eax, dword ptr [g_hKernel32]
add eax, 11223346h
jmp dword ptr [eax]
nop
nop
nop
nop
nop
}
}
#pragma code_seg(".pedll32")
__declspec(naked)
BOOL WINAPI _EntryPoint(LPVOID lpBase, HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
__asm {
push ebp
mov ebp, esp
push dword ptr [ebp+14h]
push dword ptr [ebp+10h]
push dword ptr [ebp+0ch]
mov eax, dword ptr [ebp+08h]
add eax, 10101010h
call eax
mov esp, ebp
pop ebp
ret 0x10
}
}
#pragma code_seg(".pedll32")
__declspec(naked)
static LPVOID WINAPI _CALC_OFFSET(LPVOID base, DWORD disp)
{
__asm {
lea eax, dword ptr [esp+4]
mov eax, dword ptr [eax]
mov dword ptr [esp+4], eax
mov eax, dword ptr [esp+8]
add eax, dword ptr [esp+4]
ret 8
}
}
#define CALC_OFFSET(TYPE, base, disp) (TYPE) _CALC_OFFSET((LPVOID) base, disp)
#pragma code_seg(".pedll32")
static void __forceinline __fastcall swap(PBYTE a, PBYTE b)
{
BYTE c;
c = *a;
*a = *b;
*b = c;
}
#pragma code_seg(".pedll32")
static void __forceinline init_sbox(LPBYTE RC4_SBOX)
{
__declspec(allocate(".pedll32"))
static BYTE sbox[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
__memcpy(RC4_SBOX, sbox, 256);
}
#pragma code_seg(".pedll32")
static void __forceinline rc4_sbox_key(LPBYTE RC4_SBOX, PBYTE key, int length)
{
for(int i = 0, j=0; i < 256; i++)
{
j = (j + RC4_SBOX[i] + key[i % length]) % 256;
swap(&RC4_SBOX[i], &RC4_SBOX[j]);
}
}
#pragma code_seg(".pedll32")
static void __forceinline cypher_msg(LPBYTE RC4_SBOX, PBYTE msg, int length)
{
int i=0, j=0;
while(length > 0)
{
i = (i+1) % 256;
j = (j+RC4_SBOX[i]) % 256;
swap(&RC4_SBOX[i], &RC4_SBOX[j]);
*msg++ ^= RC4_SBOX[(RC4_SBOX[i] + RC4_SBOX[j]) % 256];
length--;
}
}
#pragma code_seg(".pedll32")
static BOOL reloc_is_text(PIMAGE_NT_HEADERS32 pImageNtHeader, PIMAGE_SECTION_HEADER pSectionText, DWORD offset)
{
//DWORD ImageBase = (DWORD) _baseAddress;
offset -= (DWORD) _baseAddress;
return (pSectionText->VirtualAddress <= offset && offset < (pSectionText->VirtualAddress + pSectionText->Misc.VirtualSize)) ? TRUE : FALSE;
}
#pragma code_seg(".pedll32")
#pragma code_seg(".pedll32")
static void reloctext(LPVOID pModule, PIMAGE_NT_HEADERS32 pImageNtHeader, PIMAGE_SECTION_HEADER pSectionPointer, LPVOID lpRelocAddress, DWORD dwRelocSize, LPVOID lpTextAddr)
{
DWORD ImageBase = (DWORD) _baseAddress;
base_relocation_block_t *relocation_page = (base_relocation_block_t *) lpRelocAddress;
if (dwRelocSize == 0 || relocation_page == NULL)
return; // no reloc table here!
// for each page!
while(relocation_page->BlockSize > 0)
{
if (relocation_page->PageRVA >= pSectionPointer->VirtualAddress && relocation_page->PageRVA < (pSectionPointer->VirtualAddress + pSectionPointer->Misc.VirtualSize))
{ // ok.. we can process this page!
typedef short relocation_entry;
int BlockSize = relocation_page->BlockSize - 8;
relocation_entry *entries = CALC_OFFSET(relocation_entry *, relocation_page, 8);
while(BlockSize > 0)
{
short type = ((*entries & 0xf000) >> 12);
long offset = (*entries & 0x0fff);
//ULONG *ptr = CALC_OFFSET(PULONG, pModule, offset + relocation_page->PageRVA);
ULONG *ptr = CALC_OFFSET(PULONG, lpTextAddr, offset + relocation_page->PageRVA - 0x1000); // base address of .text
ULONG value = *ptr;
ULONG dwNewValue = 0;
if (reloc_is_text(pImageNtHeader, pSectionPointer, (DWORD) value) == FALSE)
{
switch(type)
{
case IMAGE_REL_BASED_HIGHLOW:
value += (ImageBase - (DWORD) pModule);
*ptr = value;
break;
case IMAGE_REL_BASED_DIR64:
dwNewValue = value - ImageBase + (ULONG) pModule;
*ptr = dwNewValue;
break;
default:
break;
}
}
else
{ // applying different patch!
if (type == IMAGE_REL_BASED_HIGHLOW)
{
value = value - ImageBase - 0x1000;
value = value + (DWORD) lpTextAddr;
*ptr = value;
}
}
entries++;
BlockSize -= 2;
}
}
// move cursor on next page
relocation_page = CALC_OFFSET(base_relocation_block_t *, relocation_page, relocation_page->BlockSize);
}
}
#pragma code_seg(".pedll32")
static void Reloc_Process(LPVOID pModule, PIMAGE_NT_HEADERS32 pImageNtHeader, PIMAGE_SECTION_HEADER pSectionPointer, LPVOID lpRelocAddress, DWORD dwRelocSize, PIMAGE_SECTION_HEADER pTextPointer, LPVOID lpTextAddr)
{
DWORD ImageBase = (DWORD) _baseAddress;
if (dwRelocSize == 0 || lpRelocAddress == NULL)
return; // no reloc table here!
base_relocation_block_t *relocation_page = (base_relocation_block_t *) lpRelocAddress;
if (relocation_page == NULL)
return; // no relocation page available!
// for each page!
while(relocation_page->BlockSize > 0)
{
if (relocation_page->PageRVA < pSectionPointer->VirtualAddress || relocation_page->PageRVA > (pSectionPointer->VirtualAddress + pSectionPointer->Misc.VirtualSize))
{ // skip current page!
relocation_page = CALC_OFFSET(base_relocation_block_t *, relocation_page, relocation_page->BlockSize);
}
else
{ // ok.. we can process this page!
typedef short relocation_entry;
int BlockSize = relocation_page->BlockSize - 8;
relocation_entry *entries = CALC_OFFSET(relocation_entry *, relocation_page, 8);
while(BlockSize > 0)
{
short type = ((*entries & 0xf000) >> 12);
long offset = (*entries & 0x0fff);
ULONG *ptr = CALC_OFFSET(PULONG, pModule, offset + relocation_page->PageRVA);
ULONG value = *ptr;
ULONG dwNewValue = 0;
if (reloc_is_text(pImageNtHeader, pTextPointer, (DWORD) value) == FALSE)
{
switch(type)
{
case IMAGE_REL_BASED_HIGHLOW:
value = value - ImageBase;
value = value + (DWORD) pModule;
*ptr = value;
break;
case IMAGE_REL_BASED_DIR64:
dwNewValue = value - ImageBase + (ULONG) pModule;
*ptr = dwNewValue;
break;
default:
break;
}
}
else
{ // applying different patch!
if (type == IMAGE_REL_BASED_HIGHLOW)
{
value = value - ImageBase - 0x1000;
value = value + (DWORD) lpTextAddr;
*ptr = value;
}
}
/*switch(type)
{
case IMAGE_REL_BASED_HIGHLOW:
value = value - pImageNtHeader->OptionalHeader.ImageBase;
value = value + (DWORD) pModule;
*ptr = value;
break;
case IMAGE_REL_BASED_DIR64:
dwNewValue = value - pImageNtHeader->OptionalHeader.ImageBase + (ULONG) pModule;
*ptr = dwNewValue;
break;
}*/
entries++;
BlockSize -= 2;
}
relocation_page = CALC_OFFSET(base_relocation_block_t *, relocation_page, relocation_page->BlockSize);
}
}
}
#pragma code_seg(".pedll32")
static LPVOID rva2addr(PIMAGE_DOS_HEADER pImageDosHeader, DWORD ImageBase, LPVOID lpAddress)
{
ULONG dwImageDosHeader = (ULONG) pImageDosHeader; // new base address!
ULONG dwAddress = (ULONG) lpAddress; // rva
if (dwAddress > ImageBase)
dwAddress -= ImageBase;
dwAddress += dwImageDosHeader;
return (LPVOID) dwAddress;
}
#pragma code_seg(".pedll32")
BOOL WINAPI decrypt(struct _vtbl *vtbl, HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER) hinstDLL;
PIMAGE_NT_HEADERS32 pImageNtHeaders32 = CALC_OFFSET(PIMAGE_NT_HEADERS32, pImageDosHeader, pImageDosHeader->e_lfanew);
if (pImageNtHeaders32->Signature != IMAGE_NT_SIGNATURE)
{ // I'm invalid file?
return FALSE;
}
short NumberOfSections = pImageNtHeaders32->FileHeader.NumberOfSections-1; // I'm on tail!!! please don't patch myself!
for(PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pImageNtHeaders32); NumberOfSections > 0; NumberOfSections--, pSection++)
{
if ((pSection->Characteristics & IMAGE_SCN_MEM_SHARED) == IMAGE_SCN_MEM_SHARED) // shared memory!
continue;
DWORD dwOldPermissions = NULL, dwDummy = 0;
LPVOID lpAddress = rva2addr(pImageDosHeader, pImageNtHeaders32->OptionalHeader.ImageBase, (LPVOID) pSection->VirtualAddress);
vtbl->mem_protect(lpAddress, pSection->Misc.VirtualSize, PAGE_READWRITE, &dwOldPermissions);
BYTE sbox[256];
ULONG64 rc4key[2] = { _rc4key0, _rc4key1 };
init_sbox(sbox);
rc4_sbox_key(sbox, (PBYTE) &rc4key, 16);
__declspec(allocate(".pedll32"))
static char szText[] = { '.', 't', 'e', 'x', 't', 0x00 };
__declspec(allocate(".pedll32"))
static char szData[] = { '.', 'd', 'a', 't', 'a', 0x00 };
if (__memcmp((char *) pSection->Name, szText, 5) == 0)
{
g_lpTextBaseAddr = vtbl->mem_alloc(0x0, pSection->Misc.VirtualSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
__memcpy((char *) g_lpTextBaseAddr, (char *) lpAddress, pSection->SizeOfRawData); // transfer data into new section "block"
cypher_msg(sbox, (PBYTE) g_lpTextBaseAddr, pSection->SizeOfRawData); // decrypt done!
}
else if (__memcmp((char *) pSection->Name, szData, 5) == 0)
{
cypher_msg(sbox, (PBYTE) lpAddress, pSection->SizeOfRawData); // decrypt done!
}
// apply reloc in current section!
ULONG ptrReloc = CALC_OFFSET(ULONG, pImageDosHeader, (ULONG) lpRelocAddress);
if (g_decrypted == 0) // relocation must be done only 1st time!
{ // it's first time?
if (pSection == IMAGE_FIRST_SECTION(pImageNtHeaders32))
{
reloctext((LPVOID) pImageDosHeader, pImageNtHeaders32, pSection, (LPVOID) ptrReloc, dwRelocSize, g_lpTextBaseAddr);
}
else
Reloc_Process((LPVOID) pImageDosHeader, pImageNtHeaders32, pSection, (LPVOID) ptrReloc, dwRelocSize, IMAGE_FIRST_SECTION(pImageNtHeaders32), g_lpTextBaseAddr);
}
vtbl->mem_protect(lpAddress, pSection->Misc.VirtualSize, dwOldPermissions, &dwDummy);
}
return TRUE;
}
__declspec(allocate(".pedll32"))
char szInitialize[] = { 'I', 'n', 'i', 't', 'i', 'a', 'l', 'i', 'z', 'e', 0x00 };
__declspec(allocate(".pedll32"))
char szCritical[] = { 'C', 'r', 'i', 't', 'i', 'c', 'a', 'l', 0x00 };
__declspec(allocate(".pedll32"))
char szSection[] = { 'S', 'e', 'c', 't', 'i', 'o', 'n', 0x00 };
__declspec(allocate(".pedll32"))
char szLeave[] = { 'L', 'e', 'a', 'v', 'e', 0x00 };
__declspec(allocate(".pedll32"))
char szDelete[] = {'D', 'e', 'l', 'e', 't', 'e', 0x00 };
__declspec(allocate(".pedll32"))
char szEnter[] = { 'E', 'n', 't', 'e', 'r', 0x00 };
#pragma code_seg(".pedll32")
static void _InitializeCriticalSection(HMODULE h, LPCRITICAL_SECTION lpCriticalSection)
{
char szApi[40];
__strcpy(szApi, szInitialize);
__strcat(szApi, szCritical);
__strcat(szApi, szSection);
//char szApi[] = { 'I', 'n', 'i', 't', 'i', 'a', 'l', 'i', 'z', 'e', 'C', 'r', 'i', 't', 'i', 'c', 'a', 'l', 'S', 'e', 'c', 't', 'i', 'o', 'n', 0x00 };
InitializeCriticalSection_ptr f = (InitializeCriticalSection_ptr) _dll32_GetProcAddress(h, szApi);
f(lpCriticalSection);
}
#pragma code_seg(".pedll32")
static void _LeaveCriticalSection(HMODULE h, LPCRITICAL_SECTION lpCriticalSection)
{
char szApi[23];
__strcpy(szApi, szLeave);
__strcat(szApi, szCritical);
__strcat(szApi, szSection);
InitializeCriticalSection_ptr f = (InitializeCriticalSection_ptr) _dll32_GetProcAddress(h, szApi);
f(lpCriticalSection);
}
#pragma code_seg(".pedll32")
static void _DeleteCriticalSection(HMODULE h, LPCRITICAL_SECTION lpCriticalSection)
{
char szApi[24];
__strcpy(szApi, szDelete);
__strcat(szApi, szCritical);
__strcat(szApi, szSection);
InitializeCriticalSection_ptr f = (InitializeCriticalSection_ptr) _dll32_GetProcAddress(h, szApi);
f(lpCriticalSection);
}
#pragma code_seg(".pedll32")
static void _EnterCriticalSection(HMODULE h, LPCRITICAL_SECTION lpCriticalSection)
{
char szApi[23];
__strcpy(szApi, szEnter);
__strcat(szApi, szCritical);
__strcat(szApi, szSection);
InitializeCriticalSection_ptr f = (InitializeCriticalSection_ptr) _dll32_GetProcAddress(h, szApi);
f(lpCriticalSection);
}
__declspec(allocate(".pedll32"))
char szKernel32[] = { 'K', 'E', 'R', 'N', 'E', 'L', '3', '2', 0x00 };
#pragma code_seg(".pedll32")
static HMODULE WINAPI get_Kernel32(void)
{
return _dll32_LoadLibraryA(szKernel32);
}
__declspec(allocate(".pedll32"))
char szDisableThreadLibraryCalls[] = { 'D', 'i', 's', 'a', 'b', 'l', 'e', 'T', 'h', 'r', 'e', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'C', 'a', 'l', 'l', 's', 00 };
#pragma code_seg(".pedll32")
static BOOL WINAPI _DisableThreadLibraryCalls(HMODULE hKernel32, HMODULE hModule)
{
typedef BOOL (WINAPI *DisableThreadLibraryCalls_ptr)(HMODULE hModule);
DisableThreadLibraryCalls_ptr f = (DisableThreadLibraryCalls_ptr) _dll32_GetProcAddress(hKernel32, szDisableThreadLibraryCalls);
return f(hModule);
}
__declspec(allocate(".pedll32"))
char szGetModuleFileNameA[] = { 'G', 'e', 't', 'M', 'o', 'd', 'u', 'l', 'e', 'F', 'i', 'l', 'e', 'N', 'a', 'm', 'e', 'A', 0x00 };
#pragma code_seg(".pedll32")
BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
// find patterns!
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER) hinstDLL;
PIMAGE_NT_HEADERS pNtHeader = CALC_OFFSET(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew);
_baseAddress = pNtHeader->OptionalHeader.ImageBase;
if (fdwReason == DLL_PROCESS_ATTACH)
{
if (g_hKernel32 == NULL)
{
g_hKernel32 = hinstDLL;
HMODULE h = get_Kernel32();
_InitializeCriticalSection(h, &_critical_section);
_DisableThreadLibraryCalls(h, hinstDLL);
//decrypt(hinstDLL, fdwReason, lpvReserved);
return TRUE;
}
}
if (fdwReason == DLL_PROCESS_DETACH)
{
HMODULE h = get_Kernel32();
_DeleteCriticalSection(h, &_critical_section);
}
if (g_decrypted == TRUE)
return _EntryPoint(g_lpTextBaseAddr, hinstDLL, fdwReason, lpvReserved);
else
return TRUE;
}
__declspec(allocate(".pedll32"))
char szVirtualProtect[] = { 'V', 'i', 'r', 't', 'u', 'a', 'l', 'P', 'r', 'o', 't', 'e', 'c', 't', 0x00 };
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked)
LPVOID WINAPI DELAYDECRYPT(DWORD dwX)
{
struct _vtbl vtable;
LPVOID dwResult;
// prolog
__asm
{
push ebp
mov ebp, esp
sub esp, 40h
}
vtable.mem_protect = _VirtualProtect;
vtable.mem_alloc = _VirtualAlloc;
vtable.file_open = _CreateFileA;
vtable.file_seek = _SetFilePointer;
//{ , _VirtualAlloc, _CreateFileA, _SetFilePointer };
_EnterCriticalSection(get_Kernel32(), &_critical_section);
if (g_decrypted == FALSE)
{
char szVirtualAlloc[0x14];
__strcpy(szVirtualAlloc, szVirtualProtect);
HMODULE h = get_Kernel32();
_VirtualProtect = (VirtualProtect_ptr) _dll32_GetProcAddress(h, szVirtualProtect);
szVirtualAlloc[7] = 'A';
szVirtualAlloc[8] = 'l';
szVirtualAlloc[9] = 'l';
szVirtualAlloc[0x0a] = 'o';
szVirtualAlloc[0x0b] = 'c';
szVirtualAlloc[0x0c] = 0x00;
_VirtualAlloc = (VirtualAlloc_ptr) _dll32_GetProcAddress(h, szVirtualAlloc);
vtable.mem_protect = _VirtualProtect;
vtable.mem_alloc = _VirtualAlloc;
g_decrypted = decrypt(&vtable, g_hKernel32, DLL_PROCESS_ATTACH, NULL);
_EntryPoint(g_lpTextBaseAddr, g_hKernel32, DLL_PROCESS_ATTACH, NULL);
}
else if (g_decrypted == 2)
{
decrypt(&vtable, g_hKernel32, DLL_PROCESS_ATTACH, NULL);
}
_LeaveCriticalSection(get_Kernel32(), &_critical_section);
dwResult = CALC_OFFSET(LPVOID, g_lpTextBaseAddr, dwX);
// epilogue
// restore stack, remove from stack our ret. address and jmp into original function
__asm
{
mov eax, dwResult
mov esp, ebp
pop ebp
pop ecx
pop ecx
jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint0(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint1(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint2(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint3(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint4(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint5(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint6(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint7(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint8(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPoint9(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPointA(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPointB(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPointC(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPointD(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPointE(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
__declspec(naked) VOID WINAPI _FakeEntryPointF(VOID)
{
__asm
{
push 0x10001000
call DELAYDECRYPT
//jmp eax
}
}
#pragma code_seg(".pedll32")
extern "C"
void WINAPI DELAYENCRYPT()
{
struct _vtbl vtable = { _VirtualProtect, _VirtualAlloc, _CreateFileA, _SetFilePointer };
g_decrypted = 2;
decrypt(&vtable, g_hKernel32, DLL_PROCESS_ATTACH, NULL);
}
#endif