• 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;
    }
    




  • 相关阅读:
    websocket协议图
    go深浅拷贝
    nginx不匹配location前缀
    nginx localtion 的alias是一个目录别名的定义,root则是最上层目录的定义
    启动了多个redis,怎么知道哪个redisserver使用的是哪个配置文件?
    go打印地址
    Linux之pureftpd安装和使用
    Xtrabackup异机远程备份
    产品新版本发布前要做那些事呢
    2014年新的一年,新的起点。。。
  • 原文地址:https://www.cnblogs.com/csnd/p/12062142.html
Copyright © 2020-2023  润新知