您的位置:首页 > 其它

CreateRemoteThread 牛刀小试

2015-06-08 07:15 302 查看
// RmtTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <windows.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "Advapi32.lib")

BOOL SetSeDebugPrivilege(BOOL bEnablePrivilege,   // TRUE to enable.  FALSE to disable
DWORD *pErrCode)
{
BOOL bRet = 0;
DWORD dwErr = 0;

HANDLE hToken = NULL;

TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious;
HANDLE hThread = GetCurrentThread();
LPCTSTR Privilege = SE_DEBUG_NAME;

do
{
//OpenThreadToken
{
if(OpenThreadToken(hThread, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
{
}
else
{
dwErr = GetLastError();
if (dwErr != ERROR_NO_TOKEN)
{
bRet = -1;
break;
}

if (!ImpersonateSelf(SecurityImpersonation))
{
dwErr = GetLastError();
bRet = -2;
break;
}

if(!OpenThreadToken(hThread, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
{
dwErr = GetLastError();
bRet = -3;
break;
}
}
}

//LookupPrivilegeValue
{
if(!LookupPrivilegeValue( NULL, Privilege, &luid ))
{
dwErr = GetLastError();
bRet = -4;
break;
}

// first pass.  get current privilege setting
tp.PrivilegeCount           = 1;
tp.Privileges[0].Luid       = luid;
tp.Privileges[0].Attributes = 0;
if(!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
&tpPrevious, &cbPrevious))
{
dwErr = GetLastError();
bRet = -5;
break;
}

// second pass.  set privilege based on previous setting
tpPrevious.PrivilegeCount       = 1;
tpPrevious.Privileges[0].Luid   = luid;
if(bEnablePrivilege)
{
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
}
else
{
tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
}

if(!AdjustTokenPrivileges(hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL))
{
dwErr = GetLastError();
bRet = -6;
break;
}
}

bRet = TRUE;
dwErr = 0;
}while(0);

if(hToken)
{
CloseHandle(hToken);
hToken = NULL;
}

if(pErrCode)
*pErrCode = dwErr;

return bRet;
}

//DLL注入
BOOL InjectDll(DWORD dwPID, LPCSTR szDllName, DWORD *pErrCode)
{
BOOL bRet = FALSE;
DWORD dwErr = 0;

HANDLE hProcess = NULL;
HMODULE hKernel32Lib = NULL;
FARPROC pThreadProc = NULL;
LPVOID pRemoteBuf = NULL;
SIZE_T NumberOfBytesWritten;
HANDLE hRemoteThread = NULL;
DWORD dwRemoteThreadID = 0;
const SIZE_T nStringLen = strlen(szDllName)+1;

do
{
//先检测DLL文件是否存在
if(!PathFileExistsA(szDllName))
{
dwErr = GetLastError();
bRet = -1;
break;
}

//Load Kernel32.dll
hKernel32Lib = LoadLibrary(_T("kernel32.dll"));
if(hKernel32Lib == NULL)
{
dwErr = GetLastError();
bRet = -2;
break;
}
pThreadProc = GetProcAddress(hKernel32Lib, "LoadLibraryA");
if(pThreadProc == NULL)
{
bRet = -3;
break;
}

//提升到DEBUG权限 SE_DEBUG_NAME
if(SetSeDebugPrivilege(TRUE, &dwErr) <= 0)
{
bRet = -4;
break;
}

//打开进程
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if(hProcess == NULL)
{
dwErr = GetLastError();
bRet = -5;
break;
}

//申请内存
pRemoteBuf = VirtualAllocEx(hProcess, NULL, nStringLen, MEM_COMMIT, PAGE_READWRITE);
if(pRemoteBuf == NULL)
{
dwErr = GetLastError();
bRet = -6;
break;
}

//写入路径
if(!WriteProcessMemory(hProcess, pRemoteBuf, szDllName, nStringLen, &NumberOfBytesWritten))
{
dwErr = GetLastError();
bRet = -7;
break;
}

//启动远程线程
hRemoteThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf, 0, &dwRemoteThreadID);
if(hRemoteThread == NULL)
{
dwErr = GetLastError();
bRet = -8;
break;
}

//wait for thread startup
Sleep(500);
bRet = TRUE;

}while(0);

//结束清理
{
if(hRemoteThread)
{
CloseHandle(hRemoteThread);
hRemoteThread = NULL;
}

if(hProcess && pRemoteBuf)
{
VirtualFreeEx(hProcess, pRemoteBuf, nStringLen, MEM_DECOMMIT);
pRemoteBuf = NULL;
}

if(hProcess)
{
CloseHandle(hProcess);
hProcess = NULL;
}

if(hKernel32Lib)
{
FreeLibrary(hKernel32Lib);
hKernel32Lib = NULL;
}
}

if(pErrCode)
*pErrCode = dwErr;

return bRet;
}

#include <stdlib.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
int iRet = 0;
DWORD dwErr = 0;

DWORD dwPID = 4704;//计算器
LPCSTR szDllName = "D:\\VC_Project\\RmtTest\\x64\\Debug\\RmtDll.dll";

//注入自己测试
HMODULE hDLL = LoadLibraryA(szDllName);
if(hDLL)
{
FreeLibrary(hDLL);
}

iRet = InjectDll(dwPID, szDllName, &dwErr);

return iRet;
}


//测试用DLL

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
{
CHAR szDbg[512];
CHAR szProcessFile[MAX_PATH + 1];
CHAR szDllFile[MAX_PATH+1];
GetModuleFileNameA(NULL, szProcessFile, MAX_PATH);
GetModuleFileNameA(hModule, szDllFile, MAX_PATH);
sprintf_s(szDbg, "Process %d (%s)\r\nDLL file (%s) hModule=%p\r\nreason=%u\r\n",
GetCurrentProcessId(), szProcessFile, szDllFile, hModule, ul_reason_for_call);
OutputDebugStringA(szDbg);
::MessageBoxA(NULL, szDbg, "RmtTest", MB_OK);
break;
}
}

return TRUE;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: