zoukankan      html  css  js  c++  java
  • DLL内存加载

    动态加载dll
    功能:
         把一个处于内存里的dll直接加载并且使用。
    用途:
         免杀(静态文件查杀),外挂(防止游戏自己hook了loadlibrary等函数),以及其他。
    原理: 
        假设目前处于内存里的dll是A,然后开辟一个新的内存空间B,根据A的文件头等相关信息,把B看做是加载内存。
    然后把数据拷贝到B里,并且对齐相关节,然后修正iat等相关。然后在手动调用一次dllmain函数,这样dll就被从内存A
    加载到内存B里了。之后再调用函数的时候,直接根据函数名,在INT或者其他位置找到函数地址,这个过程就是模拟了
    GetProcAddress函数的功能。

    整理了一个内存加载dll相关的类以及测试项目代码:(http://download.csdn.net/detail/u013761036/9686863)
    下面是相关测试代码:

    #include "stdafx.h"
    #include <string>
    #include <windows.h>
    #include <shlwapi.h>
    #include "MemLoadDll.h"
    #pragma comment(lib, "shlwapi.lib")
    using namespace std;
    #pragma warning(disable : 4996)
    
    
    unsigned char bMemory[1024*1024*5] = {0};
    
    
    DWORD dwLoadDll2Memory(string strDllPath){
    	FILE *fpLoadDll; 
    	char cCache[1024];            
    	if((fpLoadDll = fopen(strDllPath.c_str(),"rb")) == NULL) { 
    		return 0;
    	} 
    	DWORD dwNowReadId = 0;
    	while (1) { 
    		ZeroMemory(cCache ,sizeof(cCache));
    		DWORD dwReadSize = fread(cCache,1,1024 ,fpLoadDll);
    		DWORD dwErrorCode = GetLastError();
    		if(dwReadSize == 0){
    			break;
    		}
    		for(int i = 1 ;i <= dwReadSize ;i ++){
    			bMemory[dwNowReadId++] = cCache[i-1];
    		}
    	} 
    	fclose(fpLoadDll);     
    	return dwNowReadId;
    }
    
    
    VOID SetCurrentDir(){
    	WCHAR wcLocalPath[MAX_PATH*2] = {0};
    	GetModuleFileName(0 ,wcLocalPath ,MAX_PATH);
    	PathRemoveFileSpec(wcLocalPath);
    	SetCurrentDirectory(wcLocalPath);
    }
    
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    //mark : After loading a function related to the memory will be released, that is, only one function can be loaded to perform
    
    
    	SetCurrentDir();
    
    
    	DWORD dwFileLength = dwLoadDll2Memory("TestDll.dll");
    	CMemLoadDll *clLoadClass = new CMemLoadDll();
    	BOOL  bLoadDllResult  = clLoadClass->MemLoadLibrary(bMemory ,dwFileLength);	
    
    
    	if(bLoadDllResult){
    	    typedef VOID (*TYPEPRINTFMSE)(const string &strMessage);
    	    TYPEPRINTFMSE _PrintfMse = (TYPEPRINTFMSE)clLoadClass->MemGetProcAddress("PrintfMse");
    		if(_PrintfMse){
    			_PrintfMse("Memory load function executed successfully!");
    		}else{
    			// getprocaddress error
    		}
    	}else{
    		//loadlibrary error
    	}
    
    
    	delete clLoadClass;
    	return 0;
    }
    




  • 相关阅读:
    JS: 子项可以来回交换的两个下拉列表
    DOM事件
    DOM基础2——元素
    DOM基础1
    JS: 随机点名程序与万年历
    G_S男女匹配算法(算法的第一个程序2016.09.19)
    Java IO流详尽解析(大神之作)
    细讲解JAVA中的IO流
    c++运算符的优先级(收好不谢)
    java程序——输出当月日历表
  • 原文地址:https://www.cnblogs.com/csnd/p/12062142.html
Copyright © 2011-2022 走看看