0%

C-06_32位下dll注入

VirtualAllocEx 其他进程的地址空间申请内存

WriteProcessMemory 将代码数据写入到目的进程

CreateRomoteThread 在其他进程中创建线程

  1. 将需要执行的代码写到一个dll中
  2. 在目标进程申请一块内存将dll文件名写入
  3. 将目标进程地址空间中的Loadlibary当作线程函数执行

1.

dll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>

BOOL APIENTRY DLLMain(HMODULE hmodle,DWORD dwReason,void* p) {
switch (dwReason)
{
case DLL_PROCESS_ATTACH: //进程创建时调用 刚加载时会被执行
MessageBoxA(0, "注入成功", "注入成功", 0);
break;
//case DLL_PROCESS_DETACH: //进程销毁时调用

}
return TRUE;
}

属性页 配置属性->常规-> 生成dll ; c/c++ ->代码生成->Spectre缓解 改为已禁用

main

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
89
90
91
92
93
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>

//注入之前需要对进程提权
int 进程提权() {
int FLAG = 0; //提权是否成功 成功为1
HANDLE 进程访问令牌 ;

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS,&进程访问令牌)) {
TOKEN_PRIVILEGES 令牌权限;
令牌权限.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &令牌权限.Privileges[0].Luid);//遍历权限

令牌权限.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;//开启特权
if (AdjustTokenPrivileges(进程访问令牌,FALSE,&令牌权限,sizeof(令牌权限),NULL,NULL)) {
FLAG = 1;
}
}
CloseHandle(进程访问令牌);
return FLAG;
}


//遍历进程 // 目前在进程遍历时无法找到对应名 。。。
int _findProcess(char* name) {
HANDLE 快照 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
Process32First(快照, &pe32);

while (Process32Next(快照,&pe32)){
if (_strcmpi(pe32.szExeFile, name) == 0) {
return pe32.th32ProcessID;
}
}
return 0; //找不到返回0

}

//注入的exe 和 使用的dll名
void dllinject(char* exename, char* dllname) {
printf("aaaa");

if (进程提权() == 1) {
HANDLE 目标进程ID = _findProcess(exename);
if (目标进程ID!=0) { //找到目标进程
HANDLE 目标进程句柄 = OpenProcess(PROCESS_ALL_ACCESS, TRUE, 目标进程ID);
if (目标进程句柄 != NULL) {
printf("bbbb");
//开始注入
//获取dlllength 在目标申请一块内存 写入dll
int dllLength = strlen(dllname);
void * dll文件名地址 = VirtualAllocEx(目标进程句柄,NULL, dllLength, MEM_COMMIT, PAGE_READWRITE);
if (dll文件名地址 == NULL) {
printf("分配内存失败");
}
else {
printf("cccc");
WriteProcessMemory(目标进程句柄, dll文件名地址, dllname, dllLength, 0); //写入内存

//创建远程线程
HMODULE hmode = GetModuleHandleA("Kernel32.dll"); // LoadLibrary 在ker32下
LPTHREAD_START_ROUTINE 函数地址 = GetProcAddress(hmode, "LoadLibraryA"); // LPTHREAD_START_ROUTINE

HANDLE hthread = CreateRemoteThread(目标进程句柄,NULL,0,函数地址,dll文件名地址,0,0);
if (hthread == NULL) {
printf("创建远程线程失败");
}
}
}
else {
GetLastError();
printf("进程打开失败");
}
}
}
else {
GetLastError();
printf("进程提权失败");
}
}

void main() {

char* exename = "AsmDEMO.exe";
char* dllname = "32injectdll.dll";

dllinject(exename,dllname);
system("pause");

}

使用一个32位demo.exe测试

1
2
3
4
5
6
#include <stdio.h>

void main() {
printf("hellworld");
system("pause");
}

经过调试目前无法通过进程遍历找到所要测试的demo.exe ..... 原因找到了 是因为字符集问题 本来是使用的Unicode 设置成未设置 即可成功读取到进程 成功将dll注入到32位的exe下

img

2.

选择加载dll中的指定函数

dll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>

_declspec(dllexport) void fn() {
MessageBoxA(0, "fn注入成功", "fn注入成功", 0);
}

BOOL APIENTRY DLLMain(HMODULE hmodle,DWORD dwReason,void* p) {
switch (dwReason)
{
case DLL_PROCESS_ATTACH: //进程创建时调用 刚加载时会被执行
MessageBoxA(0, "注入成功", "注入成功", 0);
break;
//case DLL_PROCESS_DETACH: //进程销毁时调用

}
return TRUE;
}
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_DEPRECATE 1
#define _CRT_SECURE_NO_DEPRECATE 1
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <string.h>


//注入之前需要对进程提权
int 进程提权() {
int FLAG = 0; //提权是否成功 成功为1
HANDLE 进程访问令牌 ;

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS,&进程访问令牌)) {
TOKEN_PRIVILEGES 令牌权限;
令牌权限.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &令牌权限.Privileges[0].Luid);//遍历权限

令牌权限.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;//开启特权
if (AdjustTokenPrivileges(进程访问令牌,FALSE,&令牌权限,sizeof(令牌权限),NULL,NULL)) {
FLAG = 1;
}
}
CloseHandle(进程访问令牌);
return FLAG;
}

//遍历进程
int _findProcess(char* name) {
HANDLE 快照 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
Process32First(快照, &pe32);

while (Process32Next(快照, &pe32)) {
if (_strcmpi(pe32.szExeFile, name) == 0) {
printf("找到对应进程名!\n");
return pe32.th32ProcessID;
}
}
return 0; //找不到返回0
}

//注入的exe 和 使用的dll名
void dllinject(char* exename, char* dllname) {
printf("加载dllinject函数\n");

if (进程提权() == 1) {
HANDLE 目标进程ID = _findProcess(exename);
if (目标进程ID!=0) { //找到目标进程
HANDLE 目标进程句柄 = OpenProcess(PROCESS_ALL_ACCESS, TRUE, 目标进程ID);
if (目标进程句柄 != NULL) {
printf("开始注入\n");
//开始注入
//获取dlllength 在目标申请一块内存 写入dll
int dllLength = strlen(dllname);
void * dll文件名地址 = VirtualAllocEx(目标进程句柄,NULL, dllLength, MEM_COMMIT, PAGE_READWRITE);
if (dll文件名地址 == NULL) {
GetLastError();
printf("分配内存失败\n");
}
else {
printf("开始写入内存\n");
WriteProcessMemory(目标进程句柄, dll文件名地址, dllname, dllLength, 0); //写入内存

//创建远程线程
HMODULE hmode = GetModuleHandleA("Kernel32.dll"); // LoadLibrary 在ker32下
LPTHREAD_START_ROUTINE 函数地址 = GetProcAddress(hmode, "LoadLibraryA"); // LPTHREAD_START_ROUTINE

HANDLE hthread = CreateRemoteThread(目标进程句柄,NULL,0,函数地址,dll文件名地址,0,0);
if (hthread == NULL) {
GetLastError();
printf("创建远程线程失败\n");
}
}
}
else {
GetLastError();
printf("进程打开失败\n");
}
}
else {
printf("找不到对应进程!\n");
}
}
else {
GetLastError();
printf("进程提权失败");
}
}

void dllinjectfn(char* exename, char* dllname, char* fnname) {
printf("加载dllinjectfn函数\n");
HMODULE dll模块首地址 = LoadLibrary(dllname);

void(*fn函数地址)() = (void(*)()) GetProcAddress(dll模块首地址,fnname);

int 偏移量 = (char*)fn函数地址 - (char*)dll模块首地址;

if (进程提权() == 1) {
HANDLE 目标进程ID = _findProcess(exename);
if (目标进程ID != 0) { //找到目标进程
HANDLE 目标进程句柄 = OpenProcess(PROCESS_ALL_ACCESS, TRUE, 目标进程ID);
if (目标进程句柄 != NULL) {
printf("开始注入\n");
//开始注入
//获取dlllength 在目标申请一块内存 写入dll
int dllLength = strlen(dllname);
void* dll文件名地址 = VirtualAllocEx(目标进程句柄, NULL, dllLength, MEM_COMMIT, PAGE_READWRITE);
if (dll文件名地址 == NULL) {
GetLastError();
printf("分配内存失败\n");
}
else {
printf("开始写入内存\n");
WriteProcessMemory(目标进程句柄, dll文件名地址, dllname, dllLength, 0); //写入内存

//创建远程线程
HMODULE hmode = GetModuleHandleA("Kernel32.dll"); // LoadLibrary 在ker32下
LPTHREAD_START_ROUTINE 函数地址 = GetProcAddress(hmode, "LoadLibraryA"); // LPTHREAD_START_ROUTINE

HANDLE hthread = CreateRemoteThread(目标进程句柄, NULL, 0, 函数地址, dll文件名地址, 0, 0);
if (hthread == NULL) {
GetLastError();
printf("创建远程线程失败\n");
}

WaitForSingleObject(hthread, INFINITE);

DWORD dll模块 = 0; //初始化
GetExitCodeThread(hthread, &dll模块);
void(*fn)() = (dll模块 + 偏移量); //返回一个地址 void(*)
//创建一个远程线程
hthread = CreateRemoteThread(目标进程句柄, NULL, 0, (LPTHREAD_START_ROUTINE)fn, 0, 0, 0);

if (hthread == NULL) {
GetLastError();
printf("创建远程线程失败\n");
}

WaitForSingleObject(hthread, INFINITE);
}
}
else {
GetLastError();
printf("进程打开失败\n");
}
CloseHandle(目标进程ID);

}
else {
GetLastError();
printf("找不到对应进程!\n");
}
}
else {
GetLastError();
printf("进程提权失败\n");
}
}

void main() {

char* exename = "test32.exe";
char* dllname = "32injectdll.dll";
char* fnname = "fn";
//dllinject(exename,dllname);
dllinjectfn(exename, dllname, "fn");

system("pause");

}

欢迎关注我的其它发布渠道

------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------