|
-
- 首先做一个Dll,名字叫DllInsert.dll,我们在DllMain中的DLL_PROCESS_ATTACH分支写一个::MessageBox(NULL, "You are Load dll now!", "Load", NULL); 在DLL_PROCESS_DETACH中写一个::MessageBox(NULL, "You are Free dll now!", "Free", NULL); ok Dll写完了,把这个Dll放到System32目录中
- 下面来注入他到Explorer.exe进程,注意:Debug版本会崩溃,Release版本没问题的,原因不白
- #include "Tlhelp32.h."
- #include "Psapi.h."
- //提升权限
- BOOL ImproveProcPriv()
- {
- HANDLE token;
- //提升权限
- if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&token))
- {
- // MessageBox(NULL,"打开进程令牌失败...","错误",MB_ICONSTOP);
- return FALSE;
- }
- TOKEN_PRIVILEGES tkp;
- tkp.PrivilegeCount = 1;
- ::LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid);
- tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- if(!AdjustTokenPrivileges(token,FALSE,&tkp,sizeof(tkp),NULL,NULL))
- {
- // MessageBox(NULL,"调整令牌权限失败...","错误",MB_ICONSTOP);
- return FALSE;
- }
- CloseHandle(token);
- return TRUE;
- }
- //这个函数名字取反了,- -! 尴尬
- DWORD GetProcNameByPID(char *strName)
- {
- HANDLE hprocessSnap = NULL;
- PROCESSENTRY32 pe32;
- memset(&pe32, 0, sizeof(PROCESSENTRY32));
- hprocessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//创建进程快照
- // 如果创建快照失败就返回1;
- if (hprocessSnap == INVALID_HANDLE_VALUE)
- {
- printf("\nCreateToolhelp32Snapshot()failed:%d",GetLastError());
- return 0;
- }
- pe32.dwSize = sizeof(PROCESSENTRY32); //初始化pe32的dwsize值
- //遍历快照
- if (Process32First(hprocessSnap,&pe32))
- {
- do
- {
- //如果name(要查找的进程的名字)等于pe32.szExeFile(本进程的名字),就返pe32.the32ProcessID (进程ID)
- if (!stricmp(strName, pe32.szExeFile))
- {
- return (DWORD)pe32.th32ProcessID;
- }
- }while (Process32Next(hprocessSnap,&pe32));
- }
- //如果没找到就返回0
- CloseHandle (hprocessSnap);
- return 0;
- }
- // ========== 定义一个代码结构,本例为一个对话框============
- //类似的可以调用Dll里面是函数,只是要把函数名字作为参数传进来
- struct MyData
- {
- char sz[64]; // 对话框显示内容
- DWORD dwLoadLibrary; // LoadLibrary的地址
- DWORD dwFreeLibrary;
- };
- // ========== 远程线程的函数 ==============================
- DWORD __stdcall RMTFunc(MyData *pData)
- {
- typedef HMODULE(__stdcall *MLoadLibrary)(LPCTSTR);
- typedef void (__stdcall *MFreeLibrary)(HMODULE);
- MLoadLibrary Mloaddll = (MLoadLibrary )(pData->dwLoadLibrary);
- MFreeLibrary Mfreedll = (MFreeLibrary )(pData->dwFreeLibrary);
- HMODULE hDll = Mloaddll(pData->sz);
- Mfreedll(hDll);
- return 0;
- }
- void CInsertExplorerDlg::OnOK()
- {
- ImproveProcPriv();
- DWORD dwIDExplorer = GetProcNameByPID("Explorer.exe");
- if (dwIDExplorer == 0)
- {
- ::MessageBox(m_hWnd, "Get Pro ID Error!", NULL, NULL);
- }
- HANDLE hProcess = OpenProcess(
- PROCESS_ALL_ACCESS,
- FALSE,
- dwIDExplorer);
- if (hProcess == NULL)
- {
- ::MessageBox(m_hWnd, "Open Process Error!", NULL, NULL);
- return ;
- }
- // ========= 代码结构 ================================================
- MyData data;
- ZeroMemory(&data, sizeof (MyData));
- strcpy(data.sz, "DllInsert.dll");
- HINSTANCE hUser = LoadLibrary("kernel32.dll");
- if (! hUser)
- {
- printf("Can not load library.\n");
- return ;
- }
- data.dwLoadLibrary = (DWORD)GetProcAddress(hUser, "LoadLibraryA");
- data.dwFreeLibrary = (DWORD)GetProcAddress(hUser, "FreeLibrary");
- FreeLibrary(hUser);
- if (! data.dwLoadLibrary)
- return ;
- // ======= 分配空间 ===================================================
- void *pRemoteThread
- = VirtualAllocEx(hProcess, 0,
- 1024*4, MEM_COMMIT|MEM_RESERVE,
- PAGE_EXECUTE_READWRITE);
- if (! pRemoteThread)
- return ;
- if (! WriteProcessMemory(hProcess, pRemoteThread, &RMTFunc, 1024*4, 0))
- return ;
- MyData *pData
- = (MyData*)VirtualAllocEx(hProcess, 0,
- sizeof (MyData), MEM_COMMIT,
- PAGE_READWRITE);
- if (!pData)
- return ;
- if (! WriteProcessMemory(hProcess, pData, &data, sizeof (MyData), 0))
- return ;
- // =========== 创建远程线程 ===========================================
- HANDLE hThread
- = CreateRemoteThread(hProcess, 0,
- 0, (LPTHREAD_START_ROUTINE)pRemoteThread,
- pData, 0, 0);
- if (! hThread)
- {
- printf("远程线程创建失败");
- return ;
- }
- CloseHandle(hThread);//这个CloseHandle是不会关掉远程线程的,TerminateThread能关掉
- VirtualFreeEx(hProcess, pRemoteThread, 1024*4, MEM_RELEASE);
- VirtualFreeEx(hProcess, pData, sizeof (MyData), MEM_RELEASE);
- CloseHandle(hProcess);
- return ;
- }
- 前面说的那个为什么会崩溃,查了一下原因:
- 原因是Debug模式下编译器会自动在代码中插入esp的check routine.它可以使Remote Thread崩溃.
- 在DEBUG模式下常有这一句:
- 0043E604 call @ILT+4380(__RTC_CheckEsp) (42E121h)
- CreateRemoteThread中莫名其妙的崩溃常由它导致.由于没有你所有的代码,所以只是推测,没有办法详细了.
- 一般来说这是由于在Debug模式下,编译会在每个函数执行后自动加入
- 恢复stockheap地址等相关指令,也就是说,它会调用自动恢复stockheap地址函数。
- 而这个函数在远程地址空间中是不存在的,所以执行时会出错,
- 如在Release模式下,编译器就不会插入这个指令,所以执行没有问题。
- 其实这个问题跟远程执行插入你自己的代码也是一样的,都需要在release下面才能
- 执行成功。
复制代码 |
|