⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dllload.cpp

📁 mpq文件的格式就是一种压缩格式
💻 CPP
📖 第 1 页 / 共 3 页
字号:

		LeaveCriticalSection(&g_DLLCrit);
		return 1;
	}
	
	LeaveCriticalSection(&g_DLLCrit);
	return 0;
}

static int MapDLLFromImage(void *pDLLFileImage, void *pMemoryImage)
{
	// Get Number of Sections
	IMAGE_FILE_HEADER     * pe = GetFileHeader((HMODULE)pDLLFileImage);
	IMAGE_OPTIONAL_HEADER * oh = GetOptionalHeader((HMODULE)pDLLFileImage);
	IMAGE_SECTION_HEADER  * sh = GetSectionHeader((HMODULE)pDLLFileImage);
	DWORD hdrlen = oh->SizeOfHeaders;
	int nSectionCount = pe->NumberOfSections;

	// Copy PE Header + Section Headers
	memcpy(pMemoryImage, pDLLFileImage, hdrlen);
	
	// Copy Sections one by one
	for(int i = 0; i < nSectionCount; i++, sh++)
    {
		char * secMemAddr  = (char *)pMemoryImage + sh->VirtualAddress;
        char * secFileAddr = (char *)pDLLFileImage + sh->PointerToRawData;

		// Copy Section data
		memcpy(secMemAddr, secFileAddr, sh->SizeOfRawData);
	}
	return ERROR_SUCCESS;
}

int PrepareDLLImage(void *pMemoryImage, DWORD /* dwImageSize */, BOOL /* bResolve */, BOOL bRebind)
{
	// Get headers
	IMAGE_OPTIONAL_HEADER * oh = GetOptionalHeader((HMODULE)pMemoryImage);
//  IMAGE_SECTION_HEADER  * sh = GetSectionHeader((HMODULE)pMemoryImage);
	int nDirCount = oh->NumberOfRvaAndSizes;

	// Get number of image directories in list
	if(nDirCount < 16)
        return ERROR_CAN_NOT_COMPLETE;
	
	// - Process import table -----------------------------------------------
	if(oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size !=0 )
    {
		IMAGE_IMPORT_DESCRIPTOR * id = (IMAGE_IMPORT_DESCRIPTOR *)MovePtr((HMODULE)pMemoryImage,oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
		
		// For all imported DLLs
		while(id->OriginalFirstThunk != 0)
        {
			char * svDllName = (char *)MovePtr((HMODULE)pMemoryImage, id->Name);
			
			// Map library into address space (could also use LoadDLL())
			HMODULE hDll = GetModuleHandle(svDllName);
			if(hDll == NULL)
                hDll = LoadLibrary(svDllName);
	
			if(hDll == NULL)
                return ERROR_CAN_NOT_COMPLETE;

			// Bind if not bound already
			if(id->TimeDateStamp==0 || bRebind)
            {
				// Store DLL infoz
				id->ForwarderChain = (DWORD)hDll;
				id->TimeDateStamp = 0xCDC31337; // This is bullshit cuz I don't want to call libc.
				
				// Fill in Import Address Table
				IMAGE_THUNK_DATA * td_in  = (IMAGE_THUNK_DATA *)MovePtr((HMODULE)pMemoryImage, (DWORD)id->OriginalFirstThunk);
                IMAGE_THUNK_DATA * td_out = (IMAGE_THUNK_DATA *)MovePtr((HMODULE)pMemoryImage, (DWORD)id->FirstThunk);
				
				while(td_in->u1.Function != NULL)
                {
                    IMAGE_IMPORT_BY_NAME * ibn;
                    FARPROC func;
					
					// Determine if ordinal or name pointer
					if(td_in->u1.Ordinal & 0x80000000)
						// Ordinal
						func = GetProcAddress(hDll, MAKEINTRESOURCE(td_in->u1.Ordinal));
					else
                    {
						// Function name
						ibn  = (IMAGE_IMPORT_BY_NAME *)MovePtr((HMODULE)pMemoryImage, (DWORD)td_in->u1.AddressOfData);
						func = GetProcAddress(hDll, (char *)ibn->Name);
					}

					if(func == NULL)
                        return ERROR_CAN_NOT_COMPLETE;
					
					// Write address to appropriate location
					td_out->u1.Ordinal = (DWORD)func;
					
					td_in++;
					td_out++;
				}
			}
			id++;
		}
	}

	// - Process relocation tables if necessary ----------------------------------
	// Calculate fixup delta
	DWORD delta = (DWORD)pMemoryImage - (DWORD)oh->ImageBase;

	if((delta != 0) && oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)
    {
		IMAGE_FIXUP_BLOCK * fb = (IMAGE_FIXUP_BLOCK *)MovePtr((HMODULE)pMemoryImage,oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
		
		// For each fixup block
		while(fb->dwPageRVA != 0)
        {
			IMAGE_FIXUP_ENTRY * fe = (IMAGE_FIXUP_ENTRY *)((char *)fb + sizeof(IMAGE_FIXUP_BLOCK));
			int count = (fb->dwBlockSize - sizeof(IMAGE_FIXUP_BLOCK)) / sizeof(IMAGE_FIXUP_ENTRY);

			// For each fixup entry
			for(int i=0; i < count; i++, fe++)
            {
				VOID * fixaddr = MovePtr((HMODULE)pMemoryImage, fb->dwPageRVA + fe->offset);
                WORD * pwFixAddr = (WORD *)fixaddr;
				int adjust;

                switch(fe->type)
                {
				    case IMAGE_REL_BASED_ABSOLUTE:
					    break;

                    case IMAGE_REL_BASED_HIGH:
					    *pwFixAddr = (WORD)(*pwFixAddr + HIWORD(delta));
					    break;

                    case IMAGE_REL_BASED_LOW:
					    *pwFixAddr = (WORD)(*pwFixAddr + LOWORD(delta));
					    break;

                    case IMAGE_REL_BASED_HIGHLOW:
					    *((DWORD *)fixaddr) += delta;
					    break;
				    
                    case IMAGE_REL_BASED_HIGHADJ: // This one's really fucked up.
					    adjust=((*((WORD *)fixaddr)) << 16) | (*(WORD *)(fe+1));
					    adjust += delta;
					    adjust += 0x00008000;
					    *((WORD *)fixaddr) = HIWORD(adjust);
					    fe++;
					    break;

                    default:
					    return ERROR_CAN_NOT_COMPLETE;
				}
			}
			fb = (IMAGE_FIXUP_BLOCK *)((char *)fb + fb->dwBlockSize);
		}
	}
	return 0;
}

HMODULE LoadDLLFromImage(void * pDLLFileImage, char * mapName, DWORD dwFlags)
{
    IMAGE_OPTIONAL_HEADER * oh;
	HANDLE hMapping   = NULL;
	void * pImageBase = NULL;
    int    nSectionCount;                  // Number of sections
    int    error = ERROR_CAN_NOT_COMPLETE;

    __try
    {
        // Check DOS Header
        if(((IMAGE_DOS_HEADER *)pDLLFileImage)->e_magic != IMAGE_DOS_SIGNATURE)
            return NULL;

	    // Check NT magic word. If not found => Bad file format
	    if(*GetNTSignature((HMODULE)pDLLFileImage) != IMAGE_NT_SIGNATURE)
            return NULL;

	    // Get section count
	    nSectionCount = GetFileHeader((HMODULE)pDLLFileImage)->NumberOfSections;
	    
	    // Ensure we are an executable image, not a rom image
	    oh = GetOptionalHeader((HMODULE)pDLLFileImage);
	    if(oh->Magic != 0x010B)
            return NULL;

	    // Get preferred image base and image length
	    void *pPreferredImageBase = (void *)oh->ImageBase;
	    DWORD dwImageSize = oh->SizeOfImage;

	    // Get base address of virtual image
	    if((pImageBase = GetDLLHandle(mapName)) == NULL)
        {
		    BOOL bCreated = FALSE;
//		    BOOL bRebased = FALSE;

            // If not mapped into this process, then we should map it now
		    if(g_bIsWinNT)
            {
			    // === Windows NT DLL Loading (supports shared sections) ===
			    if(mapName != NULL)
    			    hMapping = OpenFileMapping(FILE_MAP_WRITE, TRUE, mapName);

                if(hMapping == NULL)
                {
				    hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, dwImageSize+SIZE_OF_PARAMETER_BLOCK, mapName);
				    if(hMapping == NULL)
                        return NULL;
				    bCreated = TRUE;
			    }

			    // Try to load file mapping view at preferred image base (not gonna happen in Win9x..sigh)
			    if((pImageBase = MapViewOfFileEx(hMapping, FILE_MAP_WRITE, 0, 0, 0, pPreferredImageBase)) == NULL)
				    pImageBase = MapViewOfFileEx(hMapping, FILE_MAP_WRITE, 0, 0, 0, NULL);

                CloseHandle(hMapping);					
			    if(pImageBase == NULL)
                    return NULL;
		    }
            else
            {
			    // === Windows 9x DLL Loading (does not support shared sections) ===
			    pImageBase = VirtualAlloc(pPreferredImageBase, dwImageSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
			    if(pImageBase == NULL)
                {
				    pImageBase = VirtualAlloc(NULL,dwImageSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
				    if(pImageBase == NULL)
                        return NULL;
			    }
			    bCreated = TRUE;	
		    }
		    
		    // Now map DLL from file image into appropriate memory image (if just created)
		    // Also remap if DLL is being rebased as well (gotta fix relocations)
		    if(bCreated || (pImageBase != pPreferredImageBase))
            {
			    if((error = MapDLLFromImage(pDLLFileImage,pImageBase)) != 0)
                    return NULL;
		    }
		    
		    // Prepare DLL image (handle relocations/import/export/etc)
		    if(!(dwFlags & LOAD_LIBRARY_AS_DATAFILE))
            {
			    if(PrepareDLLImage(pImageBase, dwImageSize, (dwFlags & DONT_RESOLVE_DLL_REFERENCES) ? FALSE : TRUE, (dwFlags & REBIND_IMAGE_IMPORTS) ? TRUE:FALSE))
				    return NULL;
            }
			    
		    // Resolve DLL references
		    if(!(dwFlags & DONT_RESOLVE_DLL_REFERENCES))
            {
			    if(!RunDLLMain(pImageBase,dwImageSize,DLL_ATTACH))
				    return NULL;
		    }
			    
		    // Apply appropriate protections
            if((error = ProtectDLLImage(pImageBase, (dwFlags & RWX_PERMISSIONS) ? TRUE : FALSE)) != 0)
  	            return NULL;
	    }

	    // Add to DLL table/increase reference count
	    if(AddDLLReference(pImageBase, mapName, dwFlags) == -1)
            return NULL;

        // All done OK, reset error
        error = 0;
    }
    __finally
    {
        // If any error, cleanup and return NULL
        if(error != 0 || pImageBase == NULL)
        {
            if(g_bIsWinNT)
                UnmapViewOfFile(pImageBase);
	        else
                VirtualFree(pImageBase,0,MEM_RELEASE);
            pImageBase = NULL;
        }
    }
	return (HMODULE)pImageBase;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// GetDLLHandle()                                                                                          //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////


// Like GetModuleHandle(), returns null if the module is not loaded, returns a base address otherwise
HMODULE GetDLLHandle(char *svName)
{
	if(svName == NULL)
        return NULL;

	EnterCriticalSection(&g_DLLCrit);

	// Find DLL in list
	IMAGE_PARAMETERS *cur;
	for(cur = g_pImageParamHead;cur!=NULL;cur=cur->next) {
		if(lstrcmpi(cur->svName,svName)==0) break;
	}
	
	if(cur!=NULL) {
		LeaveCriticalSection(&g_DLLCrit);
		return (HMODULE) cur->pImageBase;
	} 

	LeaveCriticalSection(&g_DLLCrit);
	return NULL;	
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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