• windows-DLL注入


    DLL注入
        刚刚整理的代码注入(远程线程注入)现在整理这个DLL注入,DLL注入比较常用,相比远程代码注入DLL注入没有什么太多的限制,而且实现起来比较简单,当然远程线程需要注意的问题DLL很多情况都需要注意,这里不做重复,只说代码注入里面没有说过的部分。DLL注入的方式不唯一,比如你如果完全看懂了代码注入,那么你直接LoadLibrary地址和一个dll路径传进去然后在里面load一下就行了,也就是之前的代码注入完全可以实现dll注入,今天就说下一通常dll的注入方式吧,通常dll的注入比我刚刚说的那个方法还要简单,流程和代码注入差不多但是简单了很多,思路是这样,LoadLibrary这个函数所有的进程都是地址一样,我们直接获取LoadLibrary的地址,然后在CreateRemoteThread里面直接把这个地址作为线程地址传过去,然后参数就是我们已经拷贝到对方内存里的那个字符串,这样直接就跑起来了,非常简单,在DLL里想干什么就干什么,可以和本地写代码一样,然后还有一个问题,就是注意一下,dll在入口的switch里面的第一个分支直接调用你想干的事就行了,那个分支的意思就是说当dll被第一次载入的时候就自动执行了,OK就这么简单,如果你觉得没听懂,那么需要看我之前说的那个代码注入,这个里面只说了新的东西,还有就是dll注入应该注意的几个地方:
    1.dll的入口记得就调用自己的函数,别走正当的流程,如果你非蛋疼的想调用某个指定函数,当然可以用代码注入结合dll注入的方式,但是 然并卵。
    2.注意系统问题,32exe+32dll注入32位程序,64exe+64dll注入64位程序。

    3.加入你注入了QQ,发现第一次注入成功了,但是第二次注入代码没报错,但是么执行自己想要的,什么情况?,原因在于同一个dll被加同一个程序加载两次的时候,第二次不会加载,给优化掉了,把QQ关了重开就行,或者自己找到某个地方free掉自己的dll。OK一共就这些,接下来是我封装好的一个DLL调用库,没有写的很细,如果是使用建议简单修改整理(我写了测试例子,在这里http://download.csdn.net/detail/u013761036/9603051)。

    .H
        #pragma once
        #include <Windows.h>
        #include <stdlib.h>
        #include <tlhelp32.h>
        #include <Psapi.h>
        #include <string>
        
        using std::string;
        using std::wstring;
        
        #pragma comment (lib,"Psapi.lib")
        
        #pragma warning(disable:4996)
        
        class CInstDll
        {
        private:
        	bool AdjustProcessTokenPrivilege();
        	bool Camp2str(wstring wsStrA ,wstring wsStrB);
        	DWORD GetProcessIdByName(const wstring &wsProcessName);
        	std::string  ws2s(const std::wstring& s_src,UINT CodePage = CP_ACP);
        	std::wstring s2ws( const std::string& s_src,UINT CodePage = CP_ACP);
        
        public:
            bool InjectionDll2ProA(const string &strPorcessName ,const string &strDllPath);
        	bool InjectionDll2ProW(const wstring &wsPorcessName ,const wstring &wsDllPath);
        };
    
    .CPP
        #include "stdafx.h"
        #include "InstDll.h"
        
        bool CInstDll::AdjustProcessTokenPrivilege()
        {
        	LUID luidTmp;
        	HANDLE hToken;
        	TOKEN_PRIVILEGES tkp;
        
        	if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        		return false;
        	if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidTmp))
        	{     
        		CloseHandle(hToken);
        		return FALSE;
        	}
        	tkp.PrivilegeCount = 1;
        	tkp.Privileges[0].Luid = luidTmp;
        	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        
        	if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
        	{
        		CloseHandle(hToken);
        		return FALSE;
        	}
        	return true;
        }
        
        
        bool CInstDll::Camp2str(wstring wsStrA ,wstring wsStrB)
        {
        	int nSize = wsStrA.length();
        	for(int i = 0 ;i < nSize ;i ++)
        	{
        		if(wsStrA[i] >= 'A' && wsStrA[i] <= 'Z')
        			wsStrA[i] += 'a'- 'A';
        	}
        
        	nSize = wsStrB.length();
        	for(int i = 0 ;i < nSize ;i ++)
        	{
        		if(wsStrB[i] >= 'A' && wsStrB[i] <= 'Z')
        			wsStrB[i] += 'a'- 'A';
        	}
        
        	return wsStrA == wsStrB;
        }
        
        
        DWORD CInstDll::GetProcessIdByName(const wstring &wsProcessName)
        {
        	HANDLE hProcess = 0;
        	DWORD  dwProcess[2048] ,dwNeeded;
        	TCHAR  tcProcName[MAX_PATH] = {0};
        	wstring wsNowProcessName = L"";
        	int nTempSize = 0;
        	int nPos = 0;
        
        	EnumProcesses(dwProcess, sizeof(dwProcess), &dwNeeded);
        
        	for(int i = 0 ;i < dwNeeded / sizeof(DWORD) ;i++)
        	{
        		if(0 != dwProcess[i])
        		{
        			hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcess[i]);
        			GetModuleFileNameEx(hProcess, NULL, tcProcName, MAX_PATH);
        			nPos = wstring(tcProcName).find_last_of(L'\');
        			if(nPos != wstring::npos)
        			{
        				wsNowProcessName = wstring(wstring(tcProcName).substr(nPos + 1));
        				if(Camp2str(wsProcessName ,wsNowProcessName))
        				{
        					DWORD aa = dwProcess[i];
        					return aa;
        				}
        				//if(wsProcessName == wsNowProcessName)
        				// return dwProcess[i];
        			}
        		}
        	}
        	return 0;
        }
        
        std::string CInstDll::ws2s(const std::wstring& wide, UINT CodePage)
        {
        	int wide_length = static_cast<int>(wide.length());
        	if (wide_length == 0)
        		return std::string();
        
        	// Compute the length of the buffer we'll need.
        	int charcount = WideCharToMultiByte(CodePage, 0, wide.data(), wide_length,
        		NULL, 0, NULL, NULL);
        	if (charcount == 0)
        		return std::string();
        
        	std::string mb;
        	mb.resize(charcount);
        	WideCharToMultiByte(CodePage, 0, wide.data(), wide_length,
        		&mb[0], charcount, NULL, NULL);
        
        	return mb;
        }
        
        std::wstring CInstDll::s2ws( const std::string& mb,UINT CodePage)
        {
        	if (mb.empty())
        		return std::wstring();
        
        	int mb_length = static_cast<int>(mb.length());
        	// Compute the length of the buffer.
        	int charcount = MultiByteToWideChar(CodePage, 0,
        		mb.data(), mb_length, NULL, 0);
        	if (charcount == 0)
        		return std::wstring();
        
        	std::wstring wide;
        	wide.resize(charcount);
        	MultiByteToWideChar(CodePage, 0, mb.data(), mb_length, &wide[0], charcount);
        
        	return wide;
        }
        
        
        bool CInstDll::InjectionDll2ProW(const wstring &wsPorcessName ,const wstring &wsDllPath)
        {
        //1.提权
        if(!AdjustProcessTokenPrivilege())
            return false;
        
        //2.获取pid
        DWORD dwProPID = 0;
        if((dwProPID = GetProcessIdByName(wsPorcessName)) == 0)
        	return false;
        
        //3.打开进程
        HANDLE hProcess = NULL;
        if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE ,dwProPID)) == NULL)
        	return false;
        
        //4.初始化参数数据
        
        PTHREAD_START_ROUTINE dwLoadLibraryAddress =  (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),"LoadLibraryA");
        if(dwLoadLibraryAddress == 0)
        	return false;
        char tcCache[MAX_PATH] = {0};
        strcat(tcCache ,ws2s(wsDllPath).c_str());
        
        //5.在宿主进程里分配内存,用于存参数
        char *pPara = NULL;
        pPara = (char *)VirtualAllocEx(hProcess , 0 ,sizeof(tcCache) ,MEM_COMMIT,PAGE_READWRITE);
        if(pPara == NULL)  return false;
        
        //6.把参数写入宿主进程里,注意结构体的命名(_REMOTE_PARAMETER)
        if(!WriteProcessMemory(hProcess ,pPara ,tcCache ,sizeof(tcCache) ,0))
        	return false;
        
        //7.启动注入宿主进程的进程
        DWORD dwThreadId = 0;
        HANDLE hThread = CreateRemoteThread(hProcess ,0 ,0 ,dwLoadLibraryAddress ,pPara ,0 ,&dwThreadId);
        if(!hThread) return false;
        
        //9.等待线程结束,然后清理内存	
        
        WaitForSingleObject(hThread ,INFINITE);
        CloseHandle(hThread);
        VirtualFreeEx(hProcess ,pPara ,0 ,MEM_RELEASE);
        CloseHandle(hProcess);
        return true;
        }
        
        bool CInstDll::InjectionDll2ProA(const string &strPorcessName ,const string &strDllPath)
        {
        	return InjectionDll2ProW(s2ws(strPorcessName) ,s2ws(strDllPath));
        }
    	
    USER
        #include "stdafx.h"
        #include "InstDll.h"
        
        
        int _tmain(int argc, _TCHAR* argv[])
        {
        	CInstDll cIn;
        	//cIn.InjectionDll2ProW(L"qq.exe" ,L"c:\MyFirstDll32.dll"); //"explorer.exe
        	cIn.InjectionDll2ProA("explorer.exe" ,"c:\MyFirstDll64.dll"); //"explorer.exe
        	return 0;
        }	
    	
    我再把当时测试用的一个简单DLL代码贴出来吧
        // dllmain.cpp : 定义 DLL 应用程序的入口点。
        #include "stdafx.h"
        
        
        void DoSomethings()
        {
        	MessageBoxW(NULL ,L"do some things" ,L"T" ,MB_OK);
        }
        
        BOOL APIENTRY DllMain( HMODULE hModule,
                               DWORD  ul_reason_for_call,
                               LPVOID lpReserved
        					 )
        {
        	switch (ul_reason_for_call)
        	{
        	case DLL_PROCESS_ATTACH:
        	{
        		DoSomethings();
        	}break;
        	case DLL_THREAD_ATTACH:
        	case DLL_THREAD_DETACH:
        	case DLL_PROCESS_DETACH:
        		break;
        	}
        	return TRUE;
        }
    	


  • 相关阅读:
    单例模型
    数据库7 索引
    数据库6.高级
    数据库5 不想改
    绑定方法与非绑定方法 反射 内置方法
    组合 封装 多态
    面向对象之继承
    面向过程编程
    logging hashlib 模块
    pickle json xml shelve configparser模块
  • 原文地址:https://www.cnblogs.com/csnd/p/12062293.html
Copyright © 2020-2023  润新知