用AheadLib进行简单的DLL注入

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_15727809/article/details/83409980

参考链接:http://www.voidcn.com/article/p-hwvwbvwu-xz.html

1、首先编写要注入的DLL文件:dllTest_dll.dll
只进行两个数的简单相加

#include "dllTest_dll.h"

int add(int x,int y)
{
	return x+y;
}

DLL的头文件dllTest_dll.h

#ifndef LIB_H
#define LIB_H

// 这种声明方式是强制用c语言方式进行修饰,且用C的默认约定__cdecl方式。
// 这种方式编译产生的DLL中有一个导出函数:add,不加任何修饰。
extern "C" int __declspec(dllexport)add(int x,int y);
#endif

2、DLL文件的调用文件dllTest.cpp

// dllTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "stdio.h"
#include "windows.h"

typedef int (*lpAddFun)(int,int); // 函数声明 lpAddFun是一个指向函数的指针,该函数有两个参数都是int类型,函数的返回值也是int类型
// int *function(int,int)表示函数的两个参数都是int类型,函数的返回值是指向Int类型的指针;

int _tmain(int argc, _TCHAR* argv[])
{
	HINSTANCE hDll; // DLL句柄
	lpAddFun addFun; // 函数指针
	//TCHAR tzPath[MAX_PATH];

	hDll = LoadLibraryW(L"dllTest_dll.dll");// 如果不加L会报错 “LoadLibraryW”: 不能将参数 1 从“const char [16]”转换为“LPCWSTR”
                                            //与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换
	if(hDll != NULL)
	{
		addFun = (lpAddFun)GetProcAddress(hDll,"add");
		if(addFun != NULL)
		{
			int result = addFun(2,3);
			printf("%d\n",result);
			//GetSystemDirectory(tzPath,MAX_PATH); //得到系统目录……没用啊……这是谁写的程序
		}
		FreeLibrary(hDll);
	}
	system("pause");
	return 0;
}

测试一下:
在这里插入图片描述

3、用AheadLib反编译DLL,命名为dllTest_dll2.dll

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 头文件
#include <Windows.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
#pragma comment(linker, "/EXPORT:add=_AheadLib_add,@1")
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 宏定义
#define EXTERNC extern "C"
#define NAKED __declspec(naked)
#define EXPORT __declspec(dllexport)

#define ALCPP EXPORT NAKED
#define ALSTD EXTERNC EXPORT NAKED void __stdcall
#define ALCFAST EXTERNC EXPORT NAKED void __fastcall
#define ALCDECL EXTERNC NAKED void __cdecl
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Hook 命名空间
namespace Hook
{
	HHOOK m_hHook;// HOOK 句柄
			


	// HOOK 函数
	// LRESULT是一种数据类型,从窗口程序或回调函数返回的32位值
	LRESULT CALLBACK HookProc(INT iCode, WPARAM wParam, LPARAM lParam)
	{
		if (iCode > 0)
		{
			;
		}

		return CallNextHookEx(m_hHook, iCode, wParam, lParam);
	}

	// Hook
	inline BOOL WINAPI Hook(INT iHookId = WH_CALLWNDPROC)
	{
		m_hHook = SetWindowsHookEx(iHookId, HookProc, NULL, GetCurrentThreadId());
		return (m_hHook != NULL);
	}

	// Unhook
	inline VOID WINAPI Unhook()
	{
		if (m_hHook)
		{
			UnhookWindowsHookEx(m_hHook);
		}
	}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AheadLib 命名空间
namespace AheadLib
{
	HMODULE m_hModule = NULL;	// 原始模块句柄
	DWORD m_dwReturn[1] = {0};	// 原始函数返回地址


	// 加载原始模块
	inline BOOL WINAPI Load()
	{
		TCHAR tzPath[MAX_PATH];
		TCHAR tzTemp[MAX_PATH * 2];

		lstrcpy(tzPath, TEXT("dllTest_dllOrg"));

		// 添加这一句是为了证明我的dll能被执行;
		// 消息框的标题是DLL Path,内容是dllTest_dllOrg也就是原来的dll
		MessageBox(NULL,tzPath,TEXT("DLL Path"),MB_ICONSTOP);//MB_ICONSTOP消息框会出现一个停止图标

		m_hModule = LoadLibrary(tzPath); // 加载原来的dll
		if (m_hModule == NULL)
		{
			wsprintf(tzTemp, TEXT("无法加载 %s,程序无法正常运行。"), tzPath);
			MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
		}

		return (m_hModule != NULL);	
	}
		
	// 释放原始模块
	inline VOID WINAPI Free()
	{
		if (m_hModule)
		{
			FreeLibrary(m_hModule);
		}
	}

	// 获取原始函数地址
	FARPROC WINAPI GetAddress(PCSTR pszProcName)
	{
		FARPROC fpAddress;
		CHAR szProcName[16];
		TCHAR tzTemp[MAX_PATH];

		fpAddress = GetProcAddress(m_hModule, pszProcName);
		if (fpAddress == NULL)
		{
			if (HIWORD(pszProcName) == 0)
			{
				wsprintf(szProcName, "%d", pszProcName);
				pszProcName = szProcName;
			}

			wsprintf(tzTemp, TEXT("无法找到函数 %hs,程序无法正常运行。"), pszProcName);
			MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
			ExitProcess(-2);
		}

		return fpAddress;
	}
}
using namespace AheadLib;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 入口函数
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		// 表示禁用dll的DLL_THREAD_ATTACH和DLL_THREAD_DETACH通知,这样可以减少某些程序的工作集的大小
		// 成功返回非零值,失败返回零值;
		DisableThreadLibraryCalls(hModule);

		Hook::Hook();

		return Load();
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
		Free();
		Hook::Unhook();

	}

	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_add(void)
{
	// 保存返回地址
	__asm POP m_dwReturn[0 * TYPE long];

	// 调用原始函数
	GetAddress("add")();

	// 转跳到返回地址
	__asm JMP m_dwReturn[0 * TYPE long];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

4、将上述文件重新编译,
将dllTest_dll2.dll改名为dllTest_dll.dll,原来的dllTest_dll.dll改名为dllTest_dllOrg.dll,则运行dllTest.exe
则发现首先弹出我们自己定义的MessageBox,
在这里插入图片描述
点击确定后,成功调用原始的dll
在这里插入图片描述

说明dll劫持成功!
以后可以仿照这个例子进行dll劫持了!

AheadLib.exe下载地址

系统目录说明:
32位系统:C:\Windows\System32文件夹
64位系统:

  1. 64位文件默认放:C:\Windows\System32文件夹(为了兼容性)
  2. 32位文件默认放:C:\Windows\SysWOW64文件
展开阅读全文

关于用CreateRemoteThread进行Dll注入的问题

04-16

刚测试了使用CreateRemoteThread将Dll注入到其他进程中的方法,在测试中发现一个有意思的问题,以我的知识无法回答,请哪位高手解释一下:rnrn注入程序如下rn#include "stdafx.h"rnrnchar *pstrDll = "G:\\Service.dll";rnrnint APIENTRY WinMain(HINSTANCE hInstance,rn HINSTANCE hPrevInstance,rn LPSTR lpCmdLine,rn int nCmdShow)rnrn // TODO: Place code here.rn DWORD dwProcessID;rn HMODULE hDll= LoadLibrary( pstrDll );rnrn FARPROC fpLoadLibrary = GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA");rn HWND hwNotePad = FindWindow("Notepad", NULL);rn GetWindowThreadProcessId(hwNotePad, &dwProcessID);rn HANDLE hProcess = OpenProcess(rn PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE,rn FALSE,rn dwProcessID);rn LPVOID lpDllName = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT, PAGE_READWRITE);rn WriteProcessMemory(hProcess, lpDllName, pstrDll, MAX_PATH,NULL);rn HANDLE hT = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)fpLoadLibrary, lpDllName, 0, NULL);rn CloseHandle(hT);rn CloseHandle(hProcess);rn// ExitProcess(NULL);rn return 0;rnrnrnDll如下:rnBOOL APIENTRY DllMain( HANDLE hModule, rn DWORD ul_reason_for_call, rn LPVOID lpReservedrn )rnrn char strShow[128];rnrn switch (ul_reason_for_call)rn rn case DLL_PROCESS_ATTACH:rn sprintf(strShow, "DLL_PROCESS_ATTACH: %d", GetCurrentThreadId());rn MessageBox(NULL, strShow, "Test", MB_OK);rn break;rn case DLL_THREAD_ATTACH:rn sprintf(strShow, "DLL_THREAD_ATTACH: %d", GetCurrentThreadId());rn MessageBox(NULL, strShow, "Test", MB_OK);rn break;rn case DLL_THREAD_DETACH:rn sprintf(strShow, "DLL_THREAD_DETACH: %d", GetCurrentThreadId());rn MessageBox(NULL, strShow, "Test", MB_OK);rn break;rn case DLL_PROCESS_DETACH:rn sprintf(strShow, "DLL_PROCESS_DETACH: %d", GetCurrentThreadId());rn MessageBox(NULL, strShow, "Test", MB_OK);rn break;rn rn return TRUE;rnrnrn在注入后,我监测到了两个DLL_PROCESS_ATTACH消息,一个DLL_PROCESS_DETACH消息,rn一个DLL_THREAD_DETACH消息,一个DLL_THREAD_ATTACHrn在关闭被注入的进程Notpad后又收到一个DLL_PROCESS_DETACH消息rnrn哪位能解释一下这个过程? 论坛

远程线程进行DLL注入

07-17

[code=C/C++]// myDll.cpp开头rnrn#include "stdafx.h"rnrn rnrn rnrn#ifdef _MANAGEDrnrn#pragma managed(push, off)rnrn#endifrnrnvoid myTestFun();rnrnBOOL APIENTRY DllMain( HMODULE hModule,rnrn DWORD ul_reason_for_call,rnrn LPVOID lpReservedrnrn )rnrnrnrn switch (ul_reason_for_call)rnrn rnrn case DLL_PROCESS_ATTACH:rnrn myTestFun();rnrn break;rnrn case DLL_THREAD_ATTACH:rnrn break;rnrn case DLL_THREAD_DETACH:rnrn break;rnrn case DLL_PROCESS_DETACH:rnrn break;rnrn rnrn return TRUE;rnrnrnrn rnrn#ifdef _MANAGEDrnrn#pragma managed(pop)rnrn#endifrnrn rnrnvoid myTestFun()rnrnrnrn MessageBoxEx(NULL,_TEXT("测试文本"),_TEXT("测试标题"),MB_OK,0);rnrnrnrn// myDll.cpp结尾rnrn rnrn rnrn rnrnExe工程DllLoader.exernrn// DllLoader.cpp开头rnrn#include "stdafx.h"rnrn rnrnint _tmain(int argc, _TCHAR* argv[])rnrn rnrn // 我们自己的DLL文件的文件名,如果不在同一目录下,需要指定完成路径rnrn TCHAR * pcFileName = _TEXT("myDll.dll");rnrn // 计算文件名字符串的长度rnrn int iSize = ( _tcslen(pcFileName) + 1 ) * sizeof(TCHAR);rnrn // 要写入目标进程的字符串参数的地址rnrn TCHAR * pcLibFileRemote = NULL;rnrn // 目标程序的文件名rnrn TCHAR * pcTargetFileName=_TEXT("ollyDbgTest.exe");rnrn rnrn // 创建进程所需的进程信息结构体rnrn PROCESS_INFORMATION ProcessInfo; rnrn // 创建进程所需的启动信息结构体rnrn STARTUPINFO StartupInfo;rnrn ZeroMemory(&StartupInfo, sizeof(StartupInfo)); // 初始化工作rnrn StartupInfo.cb = sizeof StartupInfo; // 计算大小rnrn rnrn // 开始为目标程序建立进程rnrn if(CreateProcess(pcTargetFileName, NULL,NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo,&ProcessInfo))rnrn rnrn // 打开进程,并获得所有权限rnrn HANDLE handleTarget=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessInfo.dwProcessId);rnrn // 在目标进程中分配iSize大小的空间以便将我们的DLL的文件名作为参数写入目标进程rnrn pcLibFileRemote=(TCHAR*)VirtualAllocEx(handleTarget,NULL,iSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);rnrn // 分配成功rnrn if(NULL != pcLibFileRemote)rnrn rnrn // 把我们的DLL文件名写入目标进程的内存中rnrn if(WriteProcessMemory(handleTarget,pcLibFileRemote,(LPVOID)pcFileName,iSize,NULL))rnrn rnrn // 我们要在内存中执行的LoadLibrary函数所在的系统DLLrnrn HMODULE hmoduleKernel32 = LoadLibrary(_TEXT("Kernel32"));rnrn // 获取Kernel32.dll中的Loadlibrary函数的地址rnrn #ifdef UNICODE // 为了适应UNICODE和ANSI两种编码方式rnrn PTHREAD_START_ROUTINE pStart = (PTHREAD_START_ROUTINE)GetProcAddress(hmoduleKernel32,"LoadLibraryW");rnrn #elsernrn PTHREAD_START_ROUTINE pStart = (PTHREAD_START_ROUTINE)GetProcAddress(hmoduleKernel32,"LoadLibraryA");rnrn #endifrnrn rnrn /* 建立远程线程进行注入。这里多说几句CreateRemoteThread函数是在我们的引导程序DllLoader.exe中执行的,如果lpParamter参数直接传递字符串的话这个字符串的内存是在DllLoader.exe中的,目标进程是无法访问这个地址的,这就是之所以前面很麻烦的把我们的DLL的文件名用WriteProcessMemory写入到目标进程的内存中的原因,只有这样目标进程才能正确的得到文件名参数。 */rnrn CreateRemoteThread(handleTarget,NULL,0,pStart,pcLibFileRemote,0,NULL);rnrn rnrn rnrn rnrn return 0;rnrnrnrn// DllLoader.cpp结尾rnrnrn本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ScienWu/archive/2006/11/22/1404405.aspx[/code]rnrn======================================================================================================rnrnrn这段代码就能在建立的目标进程中创建远程线程,并让远程线程一启动就执行LoadLibrary函数加载我们的myDll.dll,使得我们写的代码得以执行。其效果就是在目标程序启动之前,先弹出了一个对话框,确定了之后才启动目标程序。rnrnrn请教高手, 远程进程的主线程和RemoteThread有什么区别?rnrn为什么RemoteThread会在远程进程的主线程前面执行?rn 论坛

没有更多推荐了,返回首页