windows-DLL注入「建议收藏」

windows-DLL注入「建议收藏」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;
    }
	

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/145428.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Python 读取txt、csv、mat数据并载入到数组

    一、txt文件数据载入到数组    这里结合上一篇博文的数据来讲怎么方便的载入.txt文件到一个数组,数据如下所示:1、自己写Python代码实现txt文本数据读取并载入成数组形式(PS:下面给了三种方法,选择理解)#-*-coding:cp936-*-importreimportlinecacheimportnumpyasnpimportosfilename=…

  • 中通笔试题:翻转字符串,例如abcd打印出dcba

    中通笔试题:翻转字符串,例如abcd打印出dcba翻转一个字符,比如:abcd—&gt;dcbapublic class 倒转字符串 { public static void main(String[] args) { System.out.print("翻转后字符串:" ); String str = "abcde"; for (int i = str.length()-1; i&gt;=0; i–) { S…

  • 【前端】HTML详细教程(下篇)[通俗易懂]

    【前端】HTML详细教程(下篇)[通俗易懂]❤️HTML必备知识详解❤️☀️第三部分:特殊符号❄️(1)什么是特殊符号?????(2)为什么需要特殊符号?☔️第四部分:表格⛄️(1)什么是表格?????(2)表格如今用来干啥?????(3)表格初识????实现效果:☁️第五部分:表单(很重要哦!!!)⚡️1.是什么&什么作用&哪些应用????(1)表单是什么?????(2)表单的作用?????(3)表单的应用?????2.表单(form)的属性:????3.表单常用的标签:????(1)input标签:????1.input标

  • Python代码缩进的使用方法_python退格快捷键

    Python代码缩进的使用方法_python退格快捷键和其它程序设计语言(如Java、C语言)采用大括号“{}”分隔代码块不同,Python采用代码缩进和冒号(:)来区分代码块之间的层次。在Python中,对于类定义、函数定义、流程控制语句、异常处理语句等,行尾的冒号和下一行的缩进,表示下一个代码块的开始,而缩进的结束则表示此代码块的结束。注意,Python中实现对代码的缩进,可以使用空格或者Tab键实现。但无论是手动敲空格,还是…

  • 腾讯云 Ubuntu16.04.1 允许 root 用户 SSH登录 修改 sshd_config PermitRootLogin 后登录失败[通俗易懂]

    腾讯云 Ubuntu16.04.1 允许 root 用户 SSH登录 修改 sshd_config PermitRootLogin 后登录失败[通俗易懂]腾讯云Ubuntu16.04.1允许root用户SSH登录修改sshd_configPermitRootLogin后登录失败今天重装了吃灰很久的服务器,选择的是Ubuntu,腾讯云默认会创建名为ubuntu的用户用于ssh登录。ubuntu执行某些命令时权限不够需要加sudo,我超级不喜欢输入命令行时加上sudo的╰(‵□′)╯。解决

  • arraylist和linkedlist的区别_arraylist 和linkedlist

    arraylist和linkedlist的区别_arraylist 和linkedlist&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这段时间把疯狂JAVA再看了一遍,发现Stack,ArrayDeque,LinkedList都可以作为栈使用,所以就稍微从性能以及实现的细节对比这三者的区别。类继承树&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由继承树看出,三者都是Collection的间接实现类。&

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号