📄 cloadercreator.cpp
字号:
// Author: Brandon LaCombe
// Date: February 3, 2006
// License: Public Domain
#include "CLoaderCreator.h"
#include <stddef.h>
#include "..\..\FileTools.h"
#include "..\..\remem.h"
#include "Loader.h"
#include "LoaderStructs.h"
// user defined types
#define JMP_OPCODE 0xE9
#define JMP_SIZE 5
#define POPAD_OPCODE 0x61
#define POPAD_SIZE 1
// code start
// Class constructor.
CLoaderCreator::CLoaderCreator()
{
m_pvLoaderHeader = ExportLoaderHeader(&m_dwLoaderHeaderSize);
m_pvTLSFixer = ExportTLSFixer(&m_dwTLSFixerSize);
m_pvNormalUnpacker = ExportNormalUnpacker(&m_dwNormalUnpackerSize);
m_pvNormalDefilter = ExportNormalDefilter(&m_dwNormalDefilterSize);
m_pvMaxUnpacker = ExportMaxUnpacker(&m_dwMaxUnpackerSize);
m_pvMaxDefilter = ExportMaxDefilter(&m_dwMaxDefilterSize);
m_pvHeaderUnpacker = ExportHeaderUnpacker(&m_dwHeaderUnpackerSize);
m_pvImportHandler = ExportImportHandler(&m_dwImportHandlerSize);
m_pvRelocationHandler = ExportRelocationHandler(&m_dwRelocationHandlerSize);
m_bOutput = FALSE;
}
// Calculates the size of the loader code minus the loader struct and decompressor.
DWORD CLoaderCreator::CalculateCodeSize()
{
DWORD dwCodeSize;
dwCodeSize = m_dwLoaderHeaderSize;
if(m_LoaderOptions.dwOrigTLSIndex)
dwCodeSize += (m_dwTLSFixerSize * 2);
if(m_LoaderOptions.bFilterCode)
{
if(m_LoaderOptions.bMax)
dwCodeSize += m_dwMaxDefilterSize;
else
dwCodeSize += m_dwNormalDefilterSize;
}
else
{
if(m_LoaderOptions.bMax)
dwCodeSize += m_dwMaxUnpackerSize;
else
dwCodeSize += m_dwNormalUnpackerSize;
}
if(m_LoaderOptions.dwHeaderRva)
dwCodeSize += m_dwHeaderUnpackerSize;
if(m_LoaderOptions.dwImportsRva)
dwCodeSize += m_dwImportHandlerSize;
if(m_LoaderOptions.dwRelocationsRva)
dwCodeSize += m_dwRelocationHandlerSize;
dwCodeSize += (POPAD_SIZE + JMP_SIZE);
return dwCodeSize;
}
// Calculates the entry point rva from a given loader rva.
DWORD CLoaderCreator::CalculateEntryPointRva(DWORD dwBaseRva)
{
return dwBaseRva + sizeof(LOADER_STRUCT);
}
// Writes the loader to the supplied memory.
VOID CLoaderCreator::Export(PVOID pvOutput, DWORD dwBaseRva)
{
DWORD dwCodeSize;
LOADER_STRUCT ls;
PBYTE pbOutputPtr;
if(m_bOutput)
{
pbOutputPtr = (PBYTE)pvOutput;
// output loader struct
dwCodeSize = CalculateCodeSize();
ls.dwNegatedLoaderRva = (DWORD)-(signed long)dwBaseRva;
ls.dwOepDelta = m_dwOepRva - (dwBaseRva + sizeof(LOADER_STRUCT) + 5);
ls.dwUnpackMemSize = m_LoaderOptions.dwUnpackMemSize;
ls.dwTotalMemSize = m_LoaderOptions.dwUnpackMemSize + m_LoaderOptions.dwWorkMemSize;
ls.pKernelIAT = m_LoaderOptions.dwKernelTableRva;
ls.pUnpack = dwBaseRva + sizeof(LOADER_STRUCT) + dwCodeSize;
ls.pSectionData = m_LoaderOptions.dwSectionDataRva;
ls.pHeader = m_LoaderOptions.dwHeaderRva;
ls.pImports = m_LoaderOptions.dwImportsRva + offsetof(IMAGE_IMPORT_DESCRIPTOR, Name);
ls.pRelocations = m_LoaderOptions.dwRelocationsRva;
ls.dwNegatedImageBase = (DWORD)-(signed long)m_dwImageBase;
ls.pTLSIndex = m_LoaderOptions.dwTLSIndexRva;
ls.dwOrigTLSIndex = m_LoaderOptions.dwOrigTLSIndex;
CopyMemory(pbOutputPtr, &ls, sizeof(LOADER_STRUCT));
pbOutputPtr += sizeof(LOADER_STRUCT);
// output loader header code
CopyMemory(pbOutputPtr, m_pvLoaderHeader, m_dwLoaderHeaderSize);
pbOutputPtr += m_dwLoaderHeaderSize;
// output tls fixer
if(m_LoaderOptions.dwOrigTLSIndex)
{
CopyMemory(pbOutputPtr, m_pvTLSFixer, m_dwTLSFixerSize);
pbOutputPtr += m_dwTLSFixerSize;
}
// output unpacker code
if(m_LoaderOptions.bFilterCode)
{
if(m_LoaderOptions.bMax)
{
CopyMemory(pbOutputPtr, m_pvMaxDefilter, m_dwMaxDefilterSize);
pbOutputPtr += m_dwMaxDefilterSize;
}
else
{
CopyMemory(pbOutputPtr, m_pvNormalDefilter, m_dwNormalDefilterSize);
pbOutputPtr += m_dwNormalDefilterSize;
}
}
else
{
if(m_LoaderOptions.bMax)
{
CopyMemory(pbOutputPtr, m_pvMaxUnpacker, m_dwMaxUnpackerSize);
pbOutputPtr += m_dwMaxUnpackerSize;
}
else
{
CopyMemory(pbOutputPtr, m_pvNormalUnpacker, m_dwNormalUnpackerSize);
pbOutputPtr += m_dwNormalUnpackerSize;
}
}
// output tls fixer
if(m_LoaderOptions.dwOrigTLSIndex)
{
CopyMemory(pbOutputPtr, m_pvTLSFixer, m_dwTLSFixerSize);
pbOutputPtr += m_dwTLSFixerSize;
}
// output header unpacker code
if(m_LoaderOptions.dwHeaderRva)
{
CopyMemory(pbOutputPtr, m_pvHeaderUnpacker, m_dwHeaderUnpackerSize);
pbOutputPtr += m_dwHeaderUnpackerSize;
}
// output import handler code
if(m_LoaderOptions.dwImportsRva)
{
CopyMemory(pbOutputPtr, m_pvImportHandler, m_dwImportHandlerSize);
pbOutputPtr += m_dwImportHandlerSize;
}
// output relocation handler code
if(m_LoaderOptions.dwRelocationsRva)
{
CopyMemory(pbOutputPtr, m_pvRelocationHandler, m_dwRelocationHandlerSize);
pbOutputPtr += m_dwRelocationHandlerSize;
}
// output popad and jmp loader_start code
*PBYTE(pbOutputPtr) = POPAD_OPCODE;
pbOutputPtr += sizeof(BYTE);
*PBYTE(pbOutputPtr) = JMP_OPCODE;
pbOutputPtr += sizeof(BYTE);
*PDWORD(pbOutputPtr) = (DWORD)-(signed long)dwCodeSize;
pbOutputPtr += sizeof(DWORD);
// output decompressor function
CopyMemory(pbOutputPtr, m_LoaderOptions.pvUnpacker, m_LoaderOptions.dwUnpackerSize);
pbOutputPtr += m_LoaderOptions.dwUnpackerSize;
}
}
// Returns the size of the whole loader.
DWORD CLoaderCreator::GetSize()
{
DWORD dwSize;
dwSize = 0;
if(m_bOutput)
{
dwSize += sizeof(LOADER_STRUCT);
dwSize += CalculateCodeSize();
dwSize += m_LoaderOptions.dwUnpackerSize;
}
return dwSize;
}
// Retrieves some information from the input file header and checks the loader options.
VOID CLoaderCreator::Rip(PVOID pvFile)
{
PIMAGE_NT_HEADERS pNt;
m_bOutput = FALSE;
pNt = PIMAGE_NT_HEADERS((PBYTE)pvFile + PIMAGE_DOS_HEADER(pvFile)->e_lfanew);
m_dwImageBase = pNt->OptionalHeader.ImageBase;
m_dwOepRva = pNt->OptionalHeader.AddressOfEntryPoint;
if(m_LoaderOptions.pvUnpacker &&
m_LoaderOptions.dwUnpackerSize &&
m_LoaderOptions.dwKernelTableRva &&
m_LoaderOptions.dwSectionDataRva)
{
m_bOutput = TRUE;
}
}
// Sets the loader options.
VOID CLoaderCreator::SetOptions(PLOADER_OPTIONS plo)
{
m_LoaderOptions = *plo;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -