首页
社区
课程
招聘
2
[原创]创建进程时注入DLL
发表于: 2013-11-7 22:19 38705

[原创]创建进程时注入DLL

2013-11-7 22:19
38705
注入DLL时有可能出现这样的情况,需要在程序运行之前注入,这样就需要一个启动器。
当然可以为添加导入表,或者DLL劫持。问题是 这样万一程序更新又要重新弄一次。

我写了个简单的启动器,创建进程,并且注入一个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
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
#include "windows.h"
#include "stdio.h"
 
BOOL StartHook(HANDLE hProcess,HANDLE hThread);
 
BOOL EnableDebugPriv();
int main()
{
    EnableDebugPriv();
    STARTUPINFO sti;
    PROCESS_INFORMATION proci;
    memset(&sti,0,sizeof(STARTUPINFO));
    memset(&proci,0,sizeof(PROCESS_INFORMATION));
    sti.cb=sizeof(STARTUPINFO);
 
    wchar_t ExeName[]=L"notepad.exe";
    DWORD valc=CreateProcess(ExeName,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL\
        ,&sti,&proci);
    if (valc==NULL)
    {
        printf("Creaet Process Failed ERROR=%d\n",GetLastError());
        getchar();
        return 0;
    }
    if (!StartHook(proci.hProcess,proci.hThread))
    {
        TerminateProcess(proci.hProcess,0);
        printf("失败\n");
        getchar();
        return 0;
    }
    ResumeThread(proci.hThread);
    CloseHandle(proci.hProcess);
    CloseHandle(proci.hThread);
    return 0;
}
BYTE ShellCode[64]=
                    {
                    0x60,
                    0x9c,
                    0x68,
                    0xaa,0xbb,0xcc,0xdd,//dll path
                    0xff,0x15,
                    0xdd,0xcc,0xbb,0xaa,//call [xxxx]
                    0x9d,
                    0x61,
                    0xff,0x25,
                    0xaa,0xbb,0xcc,0xdd,// jmp [xxxxx]
                    0xaa,0xaa,0xaa,0xaa,// loadaddr
                    0xaa,0xaa,0xaa,0xaa//  jmpaddr
                    };
/*
{
00973689 >    60                PUSHAD
0097368A      9C                PUSHFD
0097368B      68 50369700       PUSH notepad.00973650
00973690      FF15 70369700     CALL DWORD PTR DS:[973670]
00973696      9D                POPFD
00973697      61                POPAD
00973698    - FF25 30369700     JMP DWORD PTR DS:[973630]
 
 
}
*/
BYTE *DllPath;
BOOL StartHook(HANDLE hProcess,HANDLE hThread)
{
 
 
    CONTEXT ctx;
    ctx.ContextFlags=CONTEXT_ALL;
    if (!GetThreadContext(hThread,&ctx))
    {
        printf("GetThreadContext Error\n");
        return FALSE;
    }
    LPVOID LpAddr=VirtualAllocEx(hProcess,NULL,64,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    if (LpAddr==NULL)
    {
        printf("VirtualAlloc Error\n");
        return FALSE;
    }
    DWORD LoadDllAAddr=(DWORD)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"LoadLibraryA");
    if (LoadDllAAddr==NULL)
    {
        printf("LoadDllAddr error\n");
        return FALSE;
    }
    //printf("eip=0x%08x\n",ctx.Eip);
    //printf("lpAddr=0x%08x\n",LpAddr);
    //printf("LoadLibraryAAddr=0x%08x\n",LoadDllAAddr);
 
    /////////////
    _asm mov esp,esp
    DllPath=ShellCode+29;
    strcpy((char*)DllPath,"SomeHook.dll");//这里是要注入的DLL名字
    *(DWORD*)(ShellCode+3)=(DWORD)LpAddr+29;
    ////////////////
    *(DWORD*)(ShellCode+21)=LoadDllAAddr;
    *(DWORD*)(ShellCode+9)=(DWORD)LpAddr+21;
    //////////////////////////////////
    *(DWORD*)(ShellCode+25)=ctx.Eip;
    *(DWORD*)(ShellCode+17)=(DWORD)LpAddr+25;
    ////////////////////////////////////
    if (!WriteProcessMemory(hProcess,LpAddr,ShellCode,64,NULL))
    {
        printf("write Process Error\n");
        return FALSE;
    }
    ctx.Eip=(DWORD)LpAddr;
    if (!SetThreadContext(hThread,&ctx))
    {
        printf("set thread context error\n");
        return FALSE;
    }
    return TRUE;
};
 
 
BOOL EnableDebugPriv()
{
    HANDLE   hToken;
    LUID   sedebugnameValue;
    TOKEN_PRIVILEGES   tkp;
    if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
    {
        return   FALSE;
    }
 
    if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&sedebugnameValue))
    {
        CloseHandle(hToken);
        return   FALSE;
    }
    tkp.PrivilegeCount   =   1;
    tkp.Privileges[0].Luid   =   sedebugnameValue;
    tkp.Privileges[0].Attributes   =   SE_PRIVILEGE_ENABLED;
 
    if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL))
    {
        return   FALSE;
    }  
    CloseHandle(hToken);
    return TRUE;
 
}


把这个exe还有要注入的DLL 和目标程序放在一个目录。
使用这个exe就可以在启动程序时注入DLL.只是目标EXE申请的内存没有释放掉
简单易行。不知道有没有更简单的办法

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
点赞 2
支持
分享
赞赏记录
参与人
雪币
留言
时间
psycongroo
为你点赞~
2020-9-14 16:48
winways
为你点赞~
2020-2-12 20:24
最新回复 (39)
雪    币: 85
活跃值: (51)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
感谢楼主分享,简单的方法有很多,隐蔽才是王道
2013-11-7 22:29
0
雪    币: 27
活跃值: (122)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
感谢楼主分享,应该不错吧。
2013-11-7 22:53
0
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
shellcode有冗余,鉴定完毕
2013-11-7 23:02
0
雪    币: 3436
活跃值: (3736)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#include "stdafx.h"
#include <Windows.h>
 
// 函数声明
typedef BOOL (WINAPI* Proc_CreateProcessW)(LPCWSTR lpApplicationName,
                                           LPWSTR lpCommandLine,
                                           LPSECURITY_ATTRIBUTES lpProcessAttributes,
                                           LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                           BOOL bInheritHandles,
                                           DWORD dwCreationFlags,
                                           LPVOID lpEnvironment,
                                           LPCWSTR lpCurrentDirectory,
                                           LPSTARTUPINFOW lpStartupInfo,
                                           LPPROCESS_INFORMATION lpProcessInformation);
 
typedef HMODULE (WINAPI* Func_LoadLibraryW)(LPCWSTR lpLibFileName);
 
 
BYTE* mov_eax_xx(BYTE* lpCurAddres, DWORD eax)
{
    *lpCurAddres = 0xB8;
    *(DWORD*)(lpCurAddres + 1) = eax;
    return lpCurAddres + 5;
}
 
BYTE* mov_ebx_xx(BYTE* lpCurAddres, DWORD ebx)
{
    *lpCurAddres = 0xBB;
    *(DWORD*)(lpCurAddres + 1) = ebx;
    return lpCurAddres + 5;
}
 
BYTE* mov_ecx_xx(BYTE* lpCurAddres, DWORD ecx)
{
    *lpCurAddres = 0xB9;
    *(DWORD*)(lpCurAddres + 1) = ecx;
    return lpCurAddres + 5;
}
 
BYTE* mov_edx_xx(BYTE* lpCurAddres, DWORD edx)
{
    *lpCurAddres = 0xBA;
    *(DWORD*)(lpCurAddres + 1) = edx;
    return lpCurAddres + 5;
}
 
BYTE* mov_esi_xx(BYTE* lpCurAddres, DWORD esi)
{
    *lpCurAddres = 0xBE;
    *(DWORD*)(lpCurAddres + 1) = esi;
    return lpCurAddres + 5;
}
 
BYTE* mov_edi_xx(BYTE* lpCurAddres, DWORD edi)
{
    *lpCurAddres = 0xBF;
    *(DWORD*)(lpCurAddres + 1) = edi;
    return lpCurAddres + 5;
}
 
BYTE* mov_ebp_xx(BYTE* lpCurAddres, DWORD ebp)
{
    *lpCurAddres = 0xBD;
    *(DWORD*)(lpCurAddres + 1) = ebp;
    return lpCurAddres + 5;
}
 
BYTE* mov_esp_xx(BYTE* lpCurAddres, DWORD esp)
{
    *lpCurAddres = 0xBC;
    *(DWORD*)(lpCurAddres + 1) = esp;
    return lpCurAddres + 5;
}
 
BYTE* mov_eip_xx(BYTE* lpCurAddres, DWORD eip, DWORD newEip)
{
    if ( !newEip )
    {
        newEip = (DWORD)lpCurAddres;
    }
 
    *lpCurAddres = 0xE9;
    *(DWORD*)(lpCurAddres + 1) = eip - (newEip + 5);
    return lpCurAddres + 5;
}
 
BYTE* push_xx(BYTE* lpCurAddres, DWORD dwAdress)
{
 
    *lpCurAddres = 0x68;
    *(DWORD*)(lpCurAddres + 1) = dwAdress;
 
    return lpCurAddres + 5;
}
 
BYTE* Call_xx(BYTE* lpCurAddres, DWORD eip, DWORD newEip)
{
    if ( !newEip )
    {
        newEip = (DWORD)lpCurAddres;
    }
 
    *lpCurAddres = 0xE8;
    *(DWORD*)(lpCurAddres + 1) = eip - (newEip + 5);
    return lpCurAddres + 5;
}
 
BOOL SuspendTidAndInjectCode(HANDLE hProcess, HANDLE hThread, DWORD dwFuncAdress, const BYTE * lpShellCode, size_t uCodeSize)
{
    SIZE_T NumberOfBytesWritten = 0;
    BYTE ShellCodeBuf[0x480];
    CONTEXT Context;
    DWORD flOldProtect = 0;
    LPBYTE lpCurESPAddress = NULL;
    LPBYTE lpCurBufAdress = NULL;
    BOOL bResult = FALSE;
     
 
    // 挂载起线程
    SuspendThread(hThread);
 
    memset(&Context,0,sizeof(Context));
    Context.ContextFlags = CONTEXT_FULL;
 
    if ( GetThreadContext(hThread, &Context))
    {
        // 在对方线程中开辟一个 0x480 大小的局部空
        lpCurESPAddress = (LPBYTE)((Context.Esp - 0x480) & 0xFFFFFFE0);
         
        // 获取指针 用指针来操作
        lpCurBufAdress = &ShellCodeBuf[0];
 
        if (lpShellCode)
        {
            memcpy(ShellCodeBuf + 128, lpShellCode, uCodeSize);
            lpCurBufAdress = push_xx(lpCurBufAdress, (DWORD)lpCurESPAddress + 128); // push
            lpCurBufAdress = Call_xx(lpCurBufAdress, dwFuncAdress, (DWORD)lpCurESPAddress + (DWORD)lpCurBufAdress - (DWORD)&ShellCodeBuf); //Call
        }
 
        lpCurBufAdress = mov_eax_xx(lpCurBufAdress, Context.Eax);
        lpCurBufAdress = mov_ebx_xx(lpCurBufAdress, Context.Ebx);
        lpCurBufAdress = mov_ecx_xx(lpCurBufAdress, Context.Ecx);
        lpCurBufAdress = mov_edx_xx(lpCurBufAdress, Context.Edx);
        lpCurBufAdress = mov_esi_xx(lpCurBufAdress, Context.Esi);
        lpCurBufAdress = mov_edi_xx(lpCurBufAdress, Context.Edi);
        lpCurBufAdress = mov_ebp_xx(lpCurBufAdress, Context.Ebp);
        lpCurBufAdress = mov_esp_xx(lpCurBufAdress, Context.Esp);
        lpCurBufAdress = mov_eip_xx(lpCurBufAdress, Context.Eip, (DWORD)lpCurESPAddress + (DWORD)lpCurBufAdress - (DWORD)&ShellCodeBuf);
        Context.Esp = (DWORD)(lpCurESPAddress - 4);
        Context.Eip = (DWORD)lpCurESPAddress;
         
        if ( VirtualProtectEx(hProcess, lpCurESPAddress, 0x480, PAGE_EXECUTE_READWRITE, &flOldProtect)
            && WriteProcessMemory(hProcess, lpCurESPAddress, &ShellCodeBuf, 0x480, &NumberOfBytesWritten)
            && FlushInstructionCache(hProcess, lpCurESPAddress, 0x480)
            && SetThreadContext(hThread, &Context) )
        {
            bResult = TRUE;
        }
 
    }
     
    // 回复线程
    ResumeThread(hThread);
 
    return TRUE;
}
 
DWORD GetFuncAdress()
{
    return (DWORD)GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryW");
}
 
BOOL WINAPI CreateProcessWithDllW(  LPCWSTR lpApplicationName,
                                    LPWSTR lpCommandLine,
                                    LPSECURITY_ATTRIBUTES lpProcessAttributes,
                                    LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                    BOOL bInheritHandles,
                                    DWORD dwCreationFlags,
                                    LPVOID lpEnvironment,
                                    LPCWSTR lpCurrentDirectory,
                                    LPSTARTUPINFOW lpStartupInfo,
                                    LPPROCESS_INFORMATION lpProcessInformation,
                                    LPWSTR lpDllFullPath,
                                    Proc_CreateProcessW FuncAdress
                                    )
{
    BOOL bResult = FALSE;
    size_t uCodeSize = 0;
    DWORD dwCreaFlags;
    PROCESS_INFORMATION pi;
    ZeroMemory( &pi, sizeof(pi) );
 
    if (FuncAdress == NULL)
    {
        FuncAdress = CreateProcessW;
    }
     
 
    // 设置创建就挂起进程
    dwCreaFlags = dwCreationFlags | CREATE_SUSPENDED;
    if (CreateProcessW(lpApplicationName,
                        lpCommandLine,
                        lpProcessAttributes,
                        lpThreadAttributes,
                        bInheritHandles,
                        dwCreaFlags,
                        lpEnvironment,
                        lpCurrentDirectory,
                        lpStartupInfo,
                        &pi
                     ))
    {
        if ( lpDllFullPath )
            uCodeSize = 2 * wcslen(lpDllFullPath) + 2;
        else
            uCodeSize = 0;
 
        // 得到LoadLibraryW 的地址
        DWORD dwLoadDllProc = GetFuncAdress();
 
        // 挂起线程 写入Shellcode
        if (SuspendTidAndInjectCode(pi.hProcess, pi.hThread, dwLoadDllProc, (BYTE*)lpDllFullPath, uCodeSize))
        {
            if ( lpProcessInformation )
                memcpy(lpProcessInformation, &pi, sizeof(PROCESS_INFORMATION));
 
            if ( !(dwCreationFlags & CREATE_SUSPENDED) )
                ResumeThread(pi.hThread);
 
            bResult = TRUE;
        }
    }
 
    return bResult;
}
 
 
int _tmain(int argc, _TCHAR* argv[])
{  
    WCHAR wszPath[] = L"D:\\TestCreateProcessWithDll.exe";
    WCHAR wszDll[] = L"D:\\SampleDLL.dll";
 
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
     
    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );
    CreateProcessWithDllW(NULL, wszPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi, wszDll, NULL);
 
    return 0;
}


我的有比你更舒服,更简洁嘛
2013-11-8 09:15
0
雪    币: 25
活跃值: (83)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
相比楼主的内容,老兄的ShellCode更人性化一点,免去了调试的过程,不过楼主比你的强的地方在于,至少先拿了个Token,让插入dll更舒服一点~~不过,技术嘛,互相学习~~让我受益匪浅~~
2013-11-8 09:38
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢分享,学习了
2013-11-8 09:53
0
雪    币: 243
活跃值: (244)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看看Detours Express 3.0里的DetourCreateProcessWithDllEx源码也不错,支持64位
2013-11-8 10:20
0
雪    币: 209
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
可以同时支持32位和64位进程的启动注入
2013-11-8 10:22
0
雪    币: 835
活跃值: (4809)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
DetourCreateProcessWithDll
2013-11-8 10:54
0
雪    币: 1993
活跃值: (4255)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
5楼的代码写的挺有意思
可以不这样,申请dll需要的内存,按照目标地址重定位好,拷贝过去。
esp里做个 call dllentry,然后抹去PE头
2013-11-8 11:57
0
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
收藏学习。9楼的头像太可怕了,居然会动。
2013-11-8 14:02
0
雪    币: 1372
活跃值: (5762)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
13
稍微留一点空间。。前面的shellcode是固定的,只有后面的DLL名字可变,所以预留多一点点。
2013-11-8 14:56
0
雪    币: 1372
活跃值: (5762)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
14
寄存器的保护多此一举了吧。用PUSHAD POPAD足够了。堆栈内的代码XP下不一定可以执行吧。我记得。要开启DEP。
如果我去掉返回错误代码的调试,应该是比你更加简洁吧
2013-11-8 14:58
0
雪    币: 1372
活跃值: (5762)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
15
惊了个呆。。我不知道出3.0了,我还用的2.0
2013-11-8 14:59
0
雪    币: 148
活跃值: (59)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
shellcode多麻烦,CREATE_SUSPENDED启动的进程内只有exe和一个ntdll.dll,调用ntdll的LdrLoadDll
2013-11-9 22:24
0
雪    币: 18
活跃值: (117)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17
mark....
2013-11-10 08:57
0
雪    币: 124
活跃值: (494)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
mark一下下
2013-11-10 10:30
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
留个爪,漏洞利用可以用到这个吧?
2014-1-7 16:50
0
雪    币: 77
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
MARK
2014-1-16 14:56
0
雪    币: 1600
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
留个脚印
2014-2-23 11:14
0
雪    币: 8
活跃值: (33)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
make 学习了
2014-4-30 00:32
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
看起来和Detouts的代码很相似 话说你代码那里创建进程应该是FuncAdress()吧
2014-6-12 16:27
0
雪    币: 665
活跃值: (3460)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
两段代码都测试了一个,都过不了壳,微软的detours可以
2014-6-12 21:45
0
雪    币: 13100
活跃值: (5803)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
多谢楼主分享,学习鸟
2014-6-12 21:51
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册