#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加载
最新推荐文章于 2024-05-22 09:37:58 发布