获取中...

-

Just a minute...

dll注入是指向运行中的其他进程强制插入特定的dll文件

三个重要的dll

1.kernel32.dll:包含用于管理内存,进程和线程的各个函数。

2.User32.dll:包含用于执行用户界面任务的(如窗口创建和消息传送)的各个函数

3.GDI32.dll:包含用于画图和实现文本的各个函数

dll注入概念

dll注入是指向运行中的其他进程强制插入特定的dll文件。dll注入命令其他进程自行调动LoadLibrary()
API,加载用户指定的dll文件。

dll被加载到进程后会自动运行DllMain()函数,可以把想执行的代码放到dllmain()函数,每当加载dll时,添加的代码就会运行。

DllMain()函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD dwReason,LPVOID lpvReserved)
{
switch( dwReason )
{
case DLL_PROCESS_ATTACH:
break;
//添加想执行的代码
case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;

case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

dll注入原理

使用LoadLibary()API加载dll时,dll中的DllMain()函数就会被调用执行。dll注入就是从外部促使目标进程调用LoadLibary()API(与一般的dll加载相同),所以会强制调用执行DLL的DllMain()函数。被注入的dll拥有目标进程内存的访问权限。

应用

  • 改善功能与修复bug
    dll注入技术可以改善功能和修复bug。没有对应程序的源代码时或直接修改程序比较困难时,可以用dll注入技术为程序添加新功能,类似于插件,或修改有问题的代码或数据。
  • 消息钩取
    windows操作系统默认提供的消息钩取功能就是一种dll注入技术。与常规的dll注入不同的是,OS会直接将已注册的钩取dll注入目标进程。
  • API钩取
    API钩取是常用dll注入技术,因为被注入的dll拥有目标进程内存访问权限。的先创建好dll形态的钩取函数,注入要钩取的目标进程,完成API钩取。
  • 监视管理pc用户的应用程序
    用于阻止特定程序运行,禁止访问有害网站等
  • 恶意代码

DLL注入方法

1.创建远程线程(CreatRemoteThread()API)

2.使用注册表(AooInit_DLLs值)

3.消息钩取(SetWindowsHookEx()API)

创建远程线程(CreatRemote Thread)

把myhack.dll注入notepad,exe进程

myhack.dll是用来联网下载http://www.naver.com/index.html文件,InjectDll.exe是将myhack.dll注入notepad.exe进程的。
把myhack.dll和InjectDll.exe放在同一目录下,运行notepad.exe程序,notepad.exe的PID值为4632

打开命令窗口输入相应参数

myhack.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "windows.h"
#include "tchar.h"

#pragma comment(lib, "urlmon.lib")

#define DEF_URL (L"http://www.naver.com/index.html")
#define DEF_FILE_NAME (L"index.html")

HMODULE g_hMod = NULL;

DWORD WINAPI ThreadProc(LPVOID lParam)
{
TCHAR szPath[_MAX_PATH] = {0,};

if( !GetModuleFileName( g_hMod, szPath, MAX_PATH ) )
return FALSE;

TCHAR *p = _tcsrchr( szPath, '\\' );
if( !p )
return FALSE;

_tcscpy_s(p+1, _MAX_PATH, DEF_FILE_NAME);

URLDownloadToFile(NULL, DEF_URL, szPath, 0, NULL);

return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
HANDLE hThread = NULL;

g_hMod = (HMODULE)hinstDLL;

switch( fdwReason )
{
case DLL_PROCESS_ATTACH :
OutputDebugString(L"<myhack.dll> Injection!!!");
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
CloseHandle(hThread);
break;
}

return TRUE;
}

1.Dllmain函数中,当DLL被加载(DLL_PROCESS_ATTACH)时,先输出一个调试字符串”<myhack.dll> Injection!!!”,

2.利用CreateThread() 创建一个线程,创建后立即被激活,直接调用ThreadProc函数。

3.在ThreadProc()函数中通过调用调用URLDownloadToFile() 下载指定网站的index.html文件

向进程注入dll时会调用这个dll的dllmain()函数,当myhack.dll注入notepad.exe时会主动调用myhack.dll的dllmain()函数,进而调用执行URLDownloadToFile()API

InjectDll.cpp

InjectDll.exe用来把myhack.dll注入notepad.exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "windows.h"
#include "tchar.h"

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
HANDLE hProcess = NULL, hThread = NULL;
HMODULE hMod = NULL;
LPVOID pRemoteBuf = NULL;
DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
LPTHREAD_START_ROUTINE pThreadProc;

// #1. 使用dwPID 获取目标进程(notepad.exe)句柄.
if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
{
_tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());

return FALSE;
}

// #2.在目标进程(notepad.exe) 内存中分配 szDllName 大小的内存.
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

// #3. 将myhack.dll 路径("C:\Shin\myhack.dll")写入分配的内存
WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);

// #4. 获取LoadLibraryA() API 的地址.
hMod = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");

// #5. 在notepad.exe 进程中运行线程
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
WaitForSingleObject(hThread, INFINITE);

CloseHandle(hThread);
CloseHandle(hProcess);

return TRUE;
}
int _tmain(int argc, TCHAR *argv[])
{
if( argc != 3)
{
_tprintf(L"USAGE : %s <pid> <dll_path>\n", argv[0]);

return 1;
}

// inject dll
if( InjectDll((DWORD)_tstol(argv[1]), argv[2]) )
_tprintf(L"InjectDll(\"%s\") success!!!\n", argv[2]);
else
_tprintf(L"InjectDll(\"%s\") failed!!!\n", argv[2]);

return 0;
}

1.获取目标进程的句柄

调用OpenProcess()API,借助程序运行时以参数形式传递来的dwPID值获得目标进程的句柄(PROCESS_ALL_SUCCESS权限),使获取的句柄(hProcess)控制相应的进程(notepad.exe)

2.将要注入的dll路径写入目标进程内存

因任何内存空间都无法进行写入操作,先用VirtualAllocEx()API 在目标进程空间分配一块缓冲区,用来写入DLL的路径。

VirtualAllocEx()API 的返回值pRemoteBuf为分配缓冲区的地址,不是程序InjectDll自身的地址,而是句柄指向的目标进程notepad.exe的内存地址

用WriteProcessMemory() 将DLL路径字符串写入刚分配的内存。

3.获取LoadLicraryW()API地址

利用GetModuleHandle() 和GetProcessAddress() 得到LoadLibrary() 的地址。用来加载DLL

4.在目标进程中运行远程线程(Remote Thread)

利用CreateRemoteThread() 使LoadLibrary()加载DLL,实现DLL的注入。

CreatRemote Thread()API在目标进程中执行创建出的线程原理

1
2
3
4
5
6
7
8
9
10
CreatRemoteThread()
HANDLE WINAPI CreateRemoteThread(
_ _in HANDLE hProcess //目标进程句柄
_ _in LPSECURITY_ATTRIBUTES lpTreadAttributes,
_ _in SIZE_T dwStrackSize,
_ _in LPTHREAD_START_ROUTINE lpStartAddress, //线程函数地址
_ _in LPVOID lpParameter, //线程参数地址
_ _in DWORD dwCreationFlags,
_ _out LPDWORD lpThreadId
);

hProcess参数执行线程的目标进程,lpStartAddress和lpParameter分别给出了线程的函数地址和参数地址,这两个地址在目标进程虚拟内存空间中,这样目标进程才能辨别。

调试

运行notepad.exe,用Attach附加新生成的notepad.exe

选择中断与新模块

当有新的dll被加载到notepad.exe时,会在插入的dll的EP处暂停。进行DLL注入时也会在DLL的EP处暂停。当InjectDLL.exe将myhack.exe注入进程时,调试器将暂停。

使用注册表(AppInit_DLLs)

windows操作系统的注册表中默认提供了AppInit_Dlls和LoadAppInit_DLLs两个注册表项

原理

在注册表编辑器中,将要注入的DLL的路径字符串写入AppInt_DLLs项目,把LoadAppInit_DLL的项目值设为1。重启后,指定DLL会注入所有运行的进程。
其实user32.dll被加载到进程时,会读取AppInit_DLLs注册表项,若有值,调用LoadLibrary加载用户DLL。因此严格讲,该DLL只是被加载到加载user32.dll的进程。

myhack2.cpp

若当前加载了notepad.exe,就运行IE,链接指定网站

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// myhack2.cpp

#include "windows.h"
#include "tchar.h"

#define DEF_CMD L"c:\\Program Files\\Internet Explorer\\iexplore.exe"
#define DEF_ADDR L"http://www.naver.com"
#define DEF_DST_PROC L"notepad.exe"

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
TCHAR szCmd[MAX_PATH] = {0,};
TCHAR szPath[MAX_PATH] = {0,};
TCHAR *p = NULL;
STARTUPINFO si = {0,};
PROCESS_INFORMATION pi = {0,};

si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;

switch( fdwReason )
{
case DLL_PROCESS_ATTACH :
if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )
break;

if( !(p = _tcsrchr(szPath, '\\')) )
break;

if( _tcsicmp(p+1, DEF_DST_PROC) )
break;

wsprintf(szCmd, L"%s %s", DEF_CMD, DEF_ADDR);
if( !CreateProcess(NULL, (LPTSTR)(LPCTSTR)szCmd,
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi) )
break;

if( pi.hProcess != NULL )
CloseHandle(pi.hProcess);

break;
}

return TRUE;
}

复制文件到合适位置

运行注册表编译器(regedit.exe),进入HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows

修改AppInit_DLLs表项的值,输入myhack2.dll的完整路径

修改LoadAppInit_DLLs注册表项值为1

重启系统,修改生效。myhack2注入notepad.exe

相关文章
评论
分享
  • 网鼎杯部分wp

    pwnboom1分析远程已经打不通了,远程的偏移和本地的偏移不一样,只能复现一下本地的了。 首先看到流程图,代码量很大,有很大的switch语句和嵌套结构,可能是虚拟机或者是解析器。 从下图看出是一个C语言的解析器。 然后看了...

    网鼎杯部分wp
  • 网络设备配置与管理

    Linux网络设备与管理大作业 下图为某企业网络拓扑图,接入层采用二层交换机2960,汇聚和核心层使用了一台三层交换机3560 24PS,局域网边缘采用一台路由器LanRouter用于连接到外部网络的Isp Router两台路由器...

    网络设备配置与管理
  • 数字中国创新大赛

    又是自闭的一天。。 game这一题是关于python字节码的题目,之前没有了解过,看了几篇关于python字节码的文章,死磕,手工还原。。 python字节码 12345678910111213141516171819202122...

    数字中国创新大赛
Please check the parameter of comment in config.yml of hexo-theme-Annie!