#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
#include <winnt.h>
// DllMain帪偺傾僞僢僠丄僨僞僢僠敾掕
#define DLL_ATTACH 0
#define DLL_DETACH 1
#define SIZE_OF_NT_SIGNATURE (sizeof(DWORD))
#define SIZE_OF_PARAMETER_BLOCK 4096
#define IMAGE_PARAMETER_MAGIC 0xCDC31337
#define RVATOVA(base, offset) ( /
(LPVOID)((DWORD)(base) + (DWORD)(offset)))
// NT僔僌僱僠儍
#define NTSIGNATURE(ptr) ( /
(LPVOID)((PBYTE)(ptr) + /
((PIMAGE_DOS_HEADER)(ptr))->e_lfanew))
// PE僿僢僟僆僼僙僢僩
#define PEFHDROFFSET(ptr) ( /
(LPVOID)((PBYTE)(ptr) + /
((PIMAGE_DOS_HEADER)(ptr))->e_lfanew + /
SIZE_OF_NT_SIGNATURE))
// 僆僾僔儑儞僿僢僟僆僼僙僢僩
#define OPTHDROFFSET(ptr) ( /
(LPVOID)((PBYTE)(ptr) + /
((PIMAGE_DOS_HEADER)(ptr))->e_lfanew + /
SIZE_OF_NT_SIGNATURE + /
sizeof(IMAGE_FILE_HEADER)))
// 僙僋僔儑儞僿僢僟僆僼僙僢僩
#define SECHDROFFSET(ptr) ( /
(LPVOID)((PBYTE)(ptr) + /
((PIMAGE_DOS_HEADER)(ptr))->e_lfanew + /
SIZE_OF_NT_SIGNATURE + /
sizeof(IMAGE_FILE_HEADER) + /
sizeof(IMAGE_OPTIONAL_HEADER)))
// 峔憿懱偺嫬奅傪1僶僀僩愝掕
#pragma pack(push, 1)
typedef struct{
DWORD dwPageRVA;
DWORD dwBlockSize;
} IMAGE_FIXUP_BLOCK, *PIMAGE_FIXUP_BLOCK;
typedef struct{
WORD offset:12;
WORD type:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
// DLL僀儊乕僕僨乕僞偺峔憿懱
typedef struct __imageparameters{
PVOID pImageBase;
TCHAR svName[MAX_PATH];
DWORD dwFlags;
int nLockCount;
struct __imageparameters *next;
} IMAGE_PARAMETERS, *PIMAGE_PARAMETERS;
#pragma pack(pop)
// DllMain偺億僀儞僞娭悢
typedef BOOL (WINAPI *DLLMAIN_T)(HMODULE, DWORD, LPVOID);
// DLL僨乕僞儀乕僗偺僩僢僾
PIMAGE_PARAMETERS g_pImageParamHead;
// 僋儕僥傿僇儖僙僋僔儑儞曄悢
CRITICAL_SECTION g_DLLCrit;
// -------------------------------------------------------------
// 弶婜壔張棟
// -------------------------------------------------------------
void InitializeDLLLoad(void)
{
InitializeCriticalSection(&g_DLLCrit);
g_pImageParamHead = NULL;
}
// -------------------------------------------------------------
// 廔椆張棟
// -------------------------------------------------------------
void KillDLLLoad(void)
{
PIMAGE_PARAMETERS cur = g_pImageParamHead;
while(cur != NULL){
PIMAGE_PARAMETERS next = cur->next;
delete [] cur;
cur = next;
}
DeleteCriticalSection(&g_DLLCrit);
}
// -------------------------------------------------------------
// 僨乕僞儀乕僗偵怴偟偄DLL傪捛壛
// 堷悢丂丗DLL僴儞僪儖丄DLL柤乮幆暿巕乯
// 栠傝抣丗error -1, success(find 0, make 1)
// -------------------------------------------------------------
int AddDLLReference(PVOID pImageBase,
PTCHAR szName,
DWORD dwFlags)
{
// szName偑側偗傟偽僄儔乕
if(szName == NULL)
return -1;
EnterCriticalSection(&g_DLLCrit);
PIMAGE_PARAMETERS cur = g_pImageParamHead;
// DLL傪専嶕
while(cur != NULL){
if(cur->pImageBase != pImageBase)
cur = cur->next;
else{
cur->nLockCount++;
LeaveCriticalSection(&g_DLLCrit);
return 0;
}
}
// 怴偟偄DLL偺惗惉
if((cur = (PIMAGE_PARAMETERS)new IMAGE_PARAMETERS[1]) == NULL){
LeaveCriticalSection(&g_DLLCrit);
return -1;
}
cur->pImageBase = pImageBase;
cur->nLockCount = 1;
cur->dwFlags = dwFlags;
cur->next = g_pImageParamHead;
lstrcpyn(cur->svName, szName, MAX_PATH);
g_pImageParamHead = cur;
LeaveCriticalSection(&g_DLLCrit);
return 1;
}
// -------------------------------------------------------------
// 僨乕僞儀乕僗偐傜DLL傪嶍彍
// 堷悢丂丗DLL僴儞僪儖丄DLL柤乮幆暿巕乯
// 栠傝抣丗error -1, success(keep 0, delete 1)
// -------------------------------------------------------------
int RemoveDLLReference(PVOID pImageBase,
PTCHAR svName,
PDWORD pdwFlags)
{
EnterCriticalSection(&g_DLLCrit);
PIMAGE_PARAMETERS prev, cur = g_pImageParamHead;
// DLL傪専嶕
while(cur != NULL){
if(cur->pImageBase == pImageBase)
break;
prev = cur;
cur = cur->next;
}
// 敪尒偱偒側偐偭偨傜僄儔乕
if(cur == NULL){
LeaveCriticalSection(&g_DLLCrit);
return -1;
}
cur->nLockCount--;
*pdwFlags = cur->dwFlags;
lstrcpyn(svName, cur->svName, MAX_PATH);
// 僇僂儞僞偑傑偩0偠傖側偄側傜廔椆
if(cur->nLockCount != 0){
LeaveCriticalSection(&g_DLLCrit);
return 0;
}
// 楢寢傪峏怴
if(prev == NULL)
g_pImageParamHead = g_pImageParamHead->next;
else
prev->next = cur->next;
delete [] cur;
LeaveCriticalSection(&g_DLLCrit);
return 1;
}
// -------------------------------------------------------------
// 僷儔儊乕僞僥乕僽儖偐傜DLL傪専嶕偟偰偦偺僴儞僪儖傪曉偡
// 堷悢丂丗DLL僼傽僀儖柤
// 栠傝抣丗尒偮偐傟偽偦偺DLL偺僴儞僪儖丄尒偮偐傜側偗傟偽NULL
// -------------------------------------------------------------
HMODULE GetDLLHandle(PTCHAR svName)
{
if(svName == NULL)
return NULL;
EnterCriticalSection(&g_DLLCrit);
// 僷儔乕儊乕僞僥乕僽儖偺僩僢僾傪庢摼
PIMAGE_PARAMETERS cur = g_pImageParamHead;
// DLL傪専嶕
while(cur != NULL){
if(lstrcmpi(cur->svName, svName) != 0)
cur = cur->next;
else{
// 尒偮偐偭偨傜僴儞僪儖傪曉偡
LeaveCriticalSection(&g_DLLCrit);
return (HMODULE)cur->pImageBase;
}
}
// 尒偮偐傜側偗傟偽廔椆
LeaveCriticalSection(&g_DLLCrit);
return NULL;
}
// -------------------------------------------------------------
// 僷儔儊乕僞僥乕僽儖偐傜DLL傪専嶕偟偰偦偺僼傽僀儖柤傪曉偡
// 堷悢丂丗DLL僴儞僪儖丄奿擺愭億僀儞僞丄奿擺椞堟偺僒僀僘
// 栠傝抣丗尒偮偐傟偽僼傽僀儖柤偺僒僀僘丄尒偮偐傜側偗傟偽0
// -------------------------------------------------------------
DWORD GetDLLFileName(HMODULE hModule,
LPTSTR lpFileName,
DWORD dwSize)
{
if(hModule == NULL || lpFileName == NULL || dwSize == 0)
return 0;
// 傑偢偼捠忢偺GetModuleFileName偱挷傋傞
DWORD dwRet = GetModuleFileName(hModule, lpFileName, dwSize);
if(dwRet != 0)
return dwRet;
EnterCriticalSection(&g_DLLCrit);
PIMAGE_PARAMETERS cur = g_pImageParamHead;
// DLL傪専嶕
while(cur != NULL){
if(cur->pImageBase != hModule)
cur=cur->next;
else{
// 尒偮偐偭偨傜暥帤楍偲僒僀僘傪曉偡
LeaveCriticalSection(&g_DLLCrit);
lstrcpyn(lpFileName, cur->svName, dwSize);
return lstrlen(lpFileName);
}
}
LeaveCriticalSection(&g_DLLCrit);
return 0;
}
// -------------------------------------------------------------
// DLL撪偵偁傞僄僋僗億乕僩娭悢傪専嶕偡傞
// 堷悢丂丗DLL僴儞僪儖丄娭悢柤
// 栠傝抣丗惉岟側傜娭悢傾僪儗僗丄幐攕側傜NULL
// -------------------------------------------------------------
FARPROC GetDLLProcAddress(HMODULE hModule,
LPCSTR lpProcName)
{
// hModule偑NULL側傜偽僄儔乕
if(hModule == NULL)
return NULL;
// 僨傿儗僋僩儕僇僂儞僩庢摼
PIMAGE_OPTIONAL_HEADER poh =
(PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(hModule);
int nDirCount = poh->NumberOfRvaAndSizes;
if(nDirCount < 16)
return FALSE;
// 僄僋僗億乕僩僨傿儗僋僩儕僥乕僽儖庢摼
DWORD dwIDEE = IMAGE_DIRECTORY_ENTRY_EXPORT;
if(poh->DataDirectory[dwIDEE].Size == 0)
return NULL;
DWORD dwAddr = poh->DataDirectory[dwIDEE].VirtualAddress;
PIMAGE_EXPORT_DIRECTORY ped =
(PIMAGE_EXPORT_DIRECTORY)RVATOVA(hModule, dwAddr);
// 彉悢庢摼
int nOrdinal = (LOWORD(lpProcName)) - ped->Base;
if(HIWORD(lpProcName) != 0){
int count = ped->NumberOfNames;
// 柤慜偲彉悢傪庢摼
DWORD *pdwNamePtr = (PDWORD)
RVATOVA(hModule, ped->AddressOfNames);
WORD *pwOrdinalPtr = (PWORD)
RVATOVA(hModule, ped->AddressOfNameOrdinals);
// 娭悢専嶕
int i;
for(i=0; i < count; i++, pdwNamePtr++, pwOrdinalPtr++){
PTCHAR svName = (PTCHAR)RVATOVA(hModule, *pdwNamePtr);
if(lstrcmp(svName, lpProcName) == 0){
nOrdinal = *pwOrdinalPtr;
break;
}
}
// 尒偮偐傜側偗傟偽NULL傪曉媝
if(i == count)
return NULL;
}
// 敪尒偟偨娭悢傪曉偡
PDWORD pAddrTable = (PDWORD)
RVATOVA(hModule, ped->AddressOfFunctions);
return (FARPROC)RVATOVA(hModule, pAddrTable[nOrdinal]);
}
// -------------------------------------------------------------
// DLL偺DLLMain娭悢傪憱傜偣傞娭悢
// 堷悢丂丗DLL僴儞僪儖丄DLL僒僀僘丄Attach or Detach偺僼儔僌
// 栠傝抣丗error -1, success(keep 0, delete 1)
// -------------------------------------------------------------
static BOOL RunDLLMain(PVOID pImageBase,
DWORD dwImageSize,
BOOL bDetach)
{
// 僼儔僌偺専嵏
PIMAGE_FILE_HEADER pfh = (PIMAGE_FILE_HEADER)
PEFHDROFFSET(pImageBase);
if((pfh->Characteristics & IMAGE_FILE_DLL) == 0)
return TRUE;
// DLLMain娭悢偺傾僪儗僗庢摼
PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER)
OPTHDROFFSET(pImageBase);
DLLMAIN_T pMain = (DLLMAIN_T)
RVATOVA(pImageBase, poh->AddressOfEntryPoint);
// 僨僞僢僠帪or傾僞僢僠帪
if(bDetach)
return pMain((HMODULE)pImageBase, DLL_PROCESS_DETACH, NULL);
else
return pMain((HMODULE)pImageBase, DLL_PROCESS_ATTACH, NULL);
}
// -------------------------------------------------------------
// 僀儞億乕僩娭悢偺傾僪儗僗夝寛娭悢
// 堷悢丂丗DLL僼傽僀儖僀儊乕僕丄DLL僼傽僀儖僀儊乕僕偺僒僀僘
// 栠傝抣丗惉岟TRUE丄幐攕FALSE
// -------------------------------------------------------------
BOOL PrepareDLLImage(PVOID pMemoryImage,
DWORD dwImageSize)
{
PIMAGE_OPTIONAL_HEADER poh =
(PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(pMemoryImage);
int nDirCount = poh->NumberOfRvaAndSizes;
if(nDirCount < 16)
return FALSE;
PIMAGE_SECTION_HEADER psh =
(PIMAGE_SECTION_HEADER)SECHDROFFSET(pMemoryImage);
DWORD dwIDEI = IMAGE_DIRECTORY_ENTRY_IMPORT;
if(poh->DataDirectory[dwIDEI].Size != 0){
PIMAGE_IMPORT_DESCRIPTOR pid =
(PIMAGE_IMPORT_DESCRIPTOR)RVATOVA(pMemoryImage,
poh->DataDirectory[dwIDEI].VirtualAddress);
for(; pid->OriginalFirstThunk != 0; pid++){
PTCHAR svDllName = (PTCHAR)
RVATOVA(pMemoryImage, pid->Name);
HMODULE hDll = GetModuleHandle(svDllName);
if(hDll == NULL){
if((hDll = LoadLibrary(svDllName)) == NULL)
return FALSE;
}
if(pid->TimeDateStamp != 0)
continue;
pid->ForwarderChain = (DWORD)hDll;
pid->TimeDateStamp = IMAGE_PARAMETER_MAGIC;
typedef struct{
union{
DWORD Function;
DWORD Ordinal;
DWORD AddressOfData;
} u1;
} MY_IMAGE_THUNK_DATA, *PMY_IMAGE_THUNK_DATA;
PMY_IMAGE_THUNK_DATA ptd_in = (PMY_IMAGE_THUNK_DATA)
RVATOVA(pMemoryImage, pid->OriginalFirstThunk);
PMY_IMAGE_THUNK_DATA ptd_out = (PMY_IMAGE_THUNK_DATA)
RVATOVA(pMemoryImage, pid->FirstThunk);
for(; ptd_in->u1.Function != NULL; ptd_in++, ptd_out++){
FARPROC func;
if(ptd_in->u1.Ordinal & 0x80000000){
func = GetProcAddress(hDll,
MAKEINTRESOURCE(ptd_in->u1.Ordinal));
}else{
PIMAGE_IMPORT_BY_NAME pibn =
(PIMAGE_IMPORT_BY_NAME)RVATOVA(
pMemoryImage, ptd_in->u1.AddressOfData);
func = GetProcAddress(hDll, (PTCHAR)pibn->Name);
}
if(func == NULL)
return FALSE;
ptd_out->u1.Function = (DWORD)func;
}
}
}
DWORD dwIDEB = IMAGE_DIRECTORY_ENTRY_BASERELOC;
DWORD delta = (DWORD)pMemoryImage - (DWORD)poh->ImageBase;
if((delta == 0) || (poh->DataDirectory[dwIDEB].Size == 0))
return TRUE;
PIMAGE_FIXUP_BLOCK pfb = (PIMAGE_FIXUP_BLOCK)RVATOVA(
pMemoryImage, poh->DataDirectory[dwIDEB].VirtualAddress);
while(pfb->dwPageRVA != 0){
int count = (pfb->dwBlockSize - sizeof(
IMAGE_FIXUP_BLOCK)) / sizeof(IMAGE_FIXUP_ENTRY);
PIMAGE_FIXUP_ENTRY pfe = (PIMAGE_FIXUP_ENTRY)
((PTCHAR)pfb + sizeof(IMAGE_FIXUP_BLOCK));
for(int i=0; i < count; i++, pfe++){
PVOID fixaddr = RVATOVA(
pMemoryImage, pfb->dwPageRVA + pfe->offset);
switch(pfe->type)
{
case IMAGE_REL_BASED_ABSOLUTE:
break;
case IMAGE_REL_BASED_HIGH:
*((WORD *)fixaddr) += HIWORD(delta);
break;
case IMAGE_REL_BASED_LOW:
*((WORD *)fixaddr) += LOWORD(delta);
break;
case IMAGE_REL_BASED_HIGHLOW:
*((DWORD *)fixaddr) += delta;
break;
case IMAGE_REL_BASED_HIGHADJ:
*((WORD *)fixaddr) = HIWORD(
((*((WORD *)fixaddr)) << 16) |
(*(WORD *)(pfe+1))+ delta + 0x00008000);
pfe++;
break;
default:
return FALSE;
}
}
pfb = (PIMAGE_FIXUP_BLOCK)((PTCHAR)pfb + pfb->dwBlockSize);
}
return TRUE;
}
// -------------------------------------------------------------
// DLL僀儊乕僕傪僾儘僥僋僩偡傞
// 堷悢丂丗DLL僼傽僀儖僀儊乕僕
// 栠傝抣丗惉岟TRUE丄幐攕FALSE
// -------------------------------------------------------------
BOOL ProtectDLLImage(PVOID pMemoryImage)
{
// 僙僋僔儑儞悢庢摼
PIMAGE_FILE_HEADER pfh =
(PIMAGE_FILE_HEADER)PEFHDROFFSET(pMemoryImage);
int nSectionCount = pfh->NumberOfSections;
// 僙僋僔儑儞僿僢僟庢摼
PIMAGE_SECTION_HEADER psh =
(PIMAGE_SECTION_HEADER)SECHDROFFSET(pMemoryImage);
for(int i=0; i < nSectionCount; i++, psh++){
// 僙僋僔儑儞傾僪儗僗偲僒僀僘偺庢摼
PVOID secMemAddr = (PTCHAR)
RVATOVA(pMemoryImage, psh->VirtualAddress);
DWORD chr = psh->Characteristics;
// 僾儘僥僋僩僼儔僌偺愝掕
BOOL bWrite = (chr & IMAGE_SCN_MEM_WRITE) ? TRUE : FALSE;
BOOL bRead = (chr & IMAGE_SCN_MEM_READ) ? TRUE : FALSE;
BOOL bExec = (chr & IMAGE_SCN_MEM_EXECUTE) ? TRUE : FALSE;
BOOL bShared = (chr & IMAGE_SCN_MEM_SHARED) ? TRUE : FALSE;
DWORD newProtect = 0;
// 僼儔僌惍棟
if(bWrite && bRead && bExec && bShared)
newProtect = PAGE_EXECUTE_READWRITE;
else if(bWrite && bRead && bExec)
newProtect = PAGE_EXECUTE_WRITECOPY;
else if(bRead && bExec)
newProtect = PAGE_EXECUTE_READ;
else if(bExec)
newProtect = PAGE_EXECUTE;
else if(bWrite && bRead && bShared)
newProtect = PAGE_READWRITE;
else if(bWrite && bRead)
newProtect = PAGE_WRITECOPY;
else if(bRead)
newProtect = PAGE_READONLY;
if(chr & IMAGE_SCN_MEM_NOT_CACHED)
newProtect |= PAGE_NOCACHE;
if(newProtect == 0)
return FALSE;
DWORD oldProtect;
// 僾儘僥僋僩幚峴
VirtualProtect(secMemAddr,
psh->SizeOfRawData, newProtect, &oldProtect);
}
return TRUE;
}
// -------------------------------------------------------------
// DLL僀儊乕僕傪僐僺乕偡傞娭悢
// 堷悢丂丗DLL僼傽僀儖僀儊乕僕丄僐僺乕愭億僀儞僞
// 栠傝抣丗惉岟TRUE丄幐攕FALSE
// -------------------------------------------------------------
BOOL MapDLLFromImage(PVOID pDLLFileImage,
PVOID pMemoryImage)
{
// PE僿僢僟偲僙僋僔儑儞僿僢僟傪僐僺乕
PIMAGE_OPTIONAL_HEADER poh =
(PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(pDLLFileImage);
memcpy(pMemoryImage, pDLLFileImage, poh->SizeOfHeaders);
// 僙僋僔儑儞悢傪庢摼
PIMAGE_FILE_HEADER pfh = (PIMAGE_FILE_HEADER)
PEFHDROFFSET(pDLLFileImage);
int nSectionCount = pfh->NumberOfSections;
// 僙僋僔儑儞僿僢僟億僀儞僞庢摼
PIMAGE_SECTION_HEADER psh =
(PIMAGE_SECTION_HEADER)SECHDROFFSET(pDLLFileImage);
// 偡傋偰偺僙僋僔儑儞偺僐僺乕
for(int i=0; i < nSectionCount; i++, psh++){
PTCHAR secMemAddr = (PTCHAR)
((PTCHAR)pMemoryImage + psh->VirtualAddress);
PTCHAR secFileAddr = (PTCHAR)
((PTCHAR)pDLLFileImage + psh->PointerToRawData);
int secLen = psh->SizeOfRawData;
memcpy(secMemAddr, secFileAddr, secLen);
}
return TRUE;
}
// -------------------------------------------------------------
// DLL僀儊乕僕偐傜DLL傪儘乕僪偡傞娭悢
// 堷悢丂丗DLL僼傽僀儖僀儊乕僕丄儅僢僺儞僌柤乮幆暿巕乯丄僼儔僌
// 栠傝抣丗惉岟DLL僴儞僪儖丄幐攕NULL
// -------------------------------------------------------------
HMODULE LoadDLLFromImage(LPVOID pDLLFileImage,
PTCHAR szMappingName,
DWORD dwFlags)
{
// 儅僢僺儞僌柤偑側偗傟偽僄儔乕
if(szMappingName == NULL)
return NULL;
// 儅僢僺儞僌柤偺僒僀僘傪敾掕
if(lstrlen(szMappingName) >= MAX_PATH)
return NULL;
// PE僨乕僞偺敾掕
PIMAGE_DOS_HEADER doshead = (PIMAGE_DOS_HEADER)pDLLFileImage;
if(doshead->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
if(*(DWORD *)NTSIGNATURE(pDLLFileImage) != IMAGE_NT_SIGNATURE)
return NULL;
PIMAGE_OPTIONAL_HEADER poh =
(PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(pDLLFileImage);
if(poh->Magic != 0x010B)
return NULL;
// 僙僋僔儑儞悢庢摼
PIMAGE_FILE_HEADER pfh =
(PIMAGE_FILE_HEADER)PEFHDROFFSET(pDLLFileImage);
int nSectionCount = pfh->NumberOfSections;
DWORD pPreferredImageBase = poh->ImageBase;
DWORD dwImageSize = poh->SizeOfImage;
PVOID pImageBase;
HANDLE hmapping = NULL;
// DLL僴儞僪儖偑尒偮偐傜側偗傟偽怴偟偔惗惉
if((pImageBase = GetDLLHandle(szMappingName)) == NULL){
BOOL bCreated = FALSE;
// 偡偱偵儅僢僺儞僌偝傟偰偄傞偐偳偆偐
hmapping = OpenFileMapping(
FILE_MAP_WRITE, TRUE, szMappingName);
// 偝傟偰偄側偄側傜惗惉
if(hmapping == NULL){
hmapping = CreateFileMapping(
INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
dwImageSize + SIZE_OF_PARAMETER_BLOCK, szMappingName);
if(hmapping == NULL)
return NULL;
bCreated = TRUE;
}
// 儅僢僺儞僌偝傟偰偄傞僨乕僞偺愭摢傪pImageBase傊
pImageBase = MapViewOfFileEx(
hmapping, FILE_MAP_WRITE, 0, 0, 0, (LPVOID)pPreferredImageBase);
if(pImageBase == NULL){
pImageBase = MapViewOfFileEx(
hmapping, FILE_MAP_WRITE, 0, 0, 0, NULL);
}
CloseHandle(hmapping);
if(pImageBase == NULL)
return NULL;
// 怴偟偔惗惉偝傟偨偐丄儀乕僗傾僪儗僗偑曄傢偭偰偄偨傜
if(bCreated || (pImageBase != (LPVOID)pPreferredImageBase)){
// DLL僀儊乕僕傪儅僢僺儞僌
if( ! MapDLLFromImage(pDLLFileImage, pImageBase)){
UnmapViewOfFile(pImageBase);
return NULL;
}
}
// LOAD_LIBRARY_AS_DATAFILE偑棫偭偰側偄側傜偽
if( ! (dwFlags & LOAD_LIBRARY_AS_DATAFILE)){
//
if( ! PrepareDLLImage(pImageBase, dwImageSize)){
UnmapViewOfFile(pImageBase);
return NULL;
}
// 僼儔僌偵DONT_RESOLVE_DLL_REFERENCES偑棫偭偰側偗傟偽
if( ! (dwFlags & DONT_RESOLVE_DLL_REFERENCES)){
// DLLMain傪幚峴乮傾僞僢僠乯
if( ! RunDLLMain(pImageBase, dwImageSize, DLL_ATTACH)){
UnmapViewOfFile(pImageBase);
return NULL;
}
}
// 僾儘僥僋僩傪幚峴
if( ! ProtectDLLImage(pImageBase)){
UnmapViewOfFile(pImageBase);
return NULL;
}
}
}
// DLL僨乕僞儀乕僗傊捛壛
if(AddDLLReference(pImageBase, szMappingName, dwFlags) == -1){
if(hmapping != NULL)
UnmapViewOfFile(pImageBase);
return NULL;
}
return (HMODULE)pImageBase;
}
// -------------------------------------------------------------
// DLL傪儘乕僪偡傞娭悢
// 堷悢丂丗DLL僼傽僀儖柤丄梊栺岅乮NULL屌掕乯丄僼儔僌
// 栠傝抣丗惉岟DLL僴儞僪儖丄幐攕NULL
// -------------------------------------------------------------
HMODULE LoadDLLEx(LPCTSTR lpLibFileName,
HANDLE hReserved,
DWORD dwFlags)
{
// 戙懼僼傽僀儖専嶕曽朄巜掕
// 乮LOAD_WITH_ALTERED_SEARCH_PATH乯偼僒億乕僩偟側偄
if(dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH)
return NULL;
// DLL僷僗庢摼
TCHAR szPath[MAX_PATH + 1], *szFilePart;
int nLen = SearchPath(NULL, lpLibFileName,
".dll", MAX_PATH, szPath, &szFilePart);
if(nLen == 0)
return NULL;
// 僼傽僀儖儅僢僺儞僌
HANDLE hFile = CreateFile(
szPath, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
if(hFile == INVALID_HANDLE_VALUE)
return NULL;
HANDLE hMapping = CreateFileMapping(
hFile, NULL, PAGE_READONLY, 0, 0, NULL);
CloseHandle(hFile);
LPVOID pBaseAddr = MapViewOfFile(
hMapping, FILE_MAP_READ, 0, 0, 0);
if(pBaseAddr == NULL){
CloseHandle(hMapping);
return NULL;
}
// DLL僀儊乕僕偺撉傒崬傒
HMODULE hRet = LoadDLLFromImage(pBaseAddr,
szFilePart, dwFlags & ~LOAD_WITH_ALTERED_SEARCH_PATH);
// 僼傽僀儖儅僢僺儞僌夝彍
UnmapViewOfFile(pBaseAddr);
CloseHandle(hMapping);
return hRet;
}
// -------------------------------------------------------------
// DLL傪儘乕僪偡傞娭悢乮LoadDLLEx傊偺嫶搉偟乯
// 堷悢丂丗DLL僼傽僀儖柤
// 栠傝抣丗惉岟DLL僴儞僪儖丄幐攕NULL
// -------------------------------------------------------------
HMODULE LoadDLL(LPCTSTR lpLibFileName)
{
return LoadDLLEx(lpLibFileName, NULL, 0);
}
// -------------------------------------------------------------
// DLL傪奐曻偡傞娭悢
// 堷悢丂丗DLL僴儞僪儖
// 栠傝抣丗惉岟TRUE丄幐攕FALSE
// -------------------------------------------------------------
BOOL FreeDLL(HMODULE hLibModule)
{
// hLibModule偑NULL側傜栤戣奜
if(hLibModule == NULL)
return FALSE;
// PE僨乕僞偺幆暿
PIMAGE_DOS_HEADER doshead = (PIMAGE_DOS_HEADER)hLibModule;
if(doshead->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
if(*(PDWORD)NTSIGNATURE(hLibModule) != IMAGE_NT_SIGNATURE)
return FALSE;
PIMAGE_OPTIONAL_HEADER poh =
(PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(hLibModule);
if(poh->Magic != 0x010B)
return FALSE;
DWORD dwFlags;
TCHAR szName[MAX_PATH];
// DLL僨乕僞儀乕僗偐傜偼偢偡
int dllaction = RemoveDLLReference(hLibModule, szName, &dwFlags);
if(dllaction == -1)
return FALSE;
// DLL偺僨僞僢僠
if( ! (dwFlags & (LOAD_LIBRARY_AS_DATAFILE |
DONT_RESOLVE_DLL_REFERENCES)))
{ // 僇僂儞僞偑0乮dllaction=1乯側傜偽DLL傪僨僞僢僠偟偰廔椆
if(dllaction){
RunDLLMain(hLibModule, poh->SizeOfImage, DLL_DETACH);
return UnmapViewOfFile(hLibModule);
}
}
return TRUE;
}
typedef int (*PADDFUNC)(int, int);
typedef int (*PSUBFUNC)(int, int);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
InitializeDLLLoad();
HMODULE hHandle = LoadDLL(_T("test_dll"));
PADDFUNC pAdd = (PADDFUNC)GetDLLProcAddress(hHandle, _T("add_num"));
int a = (*pAdd)(3, 5); // 3 + 5 = 8
PSUBFUNC pSub = (PSUBFUNC)GetDLLProcAddress(
GetDLLHandle(_T("test_dll.dll")), _T("sub_num"));
int b = (*pSub)(8, 5); // 8 - 5 = 3
TCHAR szFileName[MAX_PATH];
GetDLLFileName(hHandle, szFileName, sizeof(szFileName));
TCHAR szBuffer[1024];
wsprintf(szBuffer, _T(
"FileName = %s/r/na = %d, b = %d/r/n"), szFileName, a, b);
MessageBox(GetActiveWindow(), szBuffer, _T("Message"), MB_OK);
FreeDLL(hHandle);
KillDLLLoad();
return 0;
}
dll加载
最新推荐文章于 2025-01-08 12:57:31 发布
186

被折叠的 条评论
为什么被折叠?



