标签:
//提升进程访问权限
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)) {
CloseHandle(hToken);
return false;
}
return true;
}
struct ToRemoteProccess
{
char title[256];
char content[256];
DWORD MsgBoxAddress;
};
////定义MessageBox类型的函数指针
typedef void (__stdcall *Msgbox)(HWND hWnd,LPCTSTR title,LPCTSTR content,DWORD uType );
DWORD threadProc(LPVOID lParam)
{
// //程序崩溃
// MessageBox(NULL, "title", "content", MB_OK);
/*****************************************************************************************************
线程体修改完毕之后我们运行程序,将线程注入到宿主进程之中。不过此时会产生一个非法访问的错误。原
因就是线程体中的MessageBox(NULL, "title", "content", MB_OK);函数的第二和第三个参数所指向的字符串
是存在于当前进程的地址空间中,宿主进程中的线程访问该字符串"hello"就会出现访问内存非法的错误。
解决的方法就是将该字符串的内容也拷贝到宿主进程的地址空间中,而且连同MessageBox函数在User32.dll
中的地址也拷贝到宿主进程之中。
*****************************************************************************************************/
//正确执行
ToRemoteProccess *tmpTRP = (ToRemoteProccess *)lParam;
Msgbox tmpMsgbox;
tmpMsgbox = (Msgbox)(tmpTRP->MsgBoxAddress);
tmpMsgbox(0,tmpTRP->content,tmpTRP->title,0);
//正确执行
// __asm
// {
// mov eax,0x00401480
// call eax
// }
return 0;
}
void CRemoteCallerDlg::OnButton1()
{
// TODO: Add your control notification handler code here
//提升本程序的权限
enableDebugPriv();
//获得远程进程句柄
HWND hWnd=::FindWindow(NULL,_T("BloodTest"));
//目标进程ID
DWORD dwProcessId;
//目标线程ID
DWORD dwThreadId;
dwThreadId=::GetWindowThreadProcessId(hWnd,&dwProcessId);
//目标进程句柄
HANDLE HandlToRemoteProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessId);
if(HandlToRemoteProcess == NULL)
{
AfxMessageBox(_T("OpenProcess失败"));
return;
}
//申请线程函数内存
const DWORD dwThreadSize = 4096;
void* threadProcAddr=::VirtualAllocEx(HandlToRemoteProcess,0,dwThreadSize,MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(threadProcAddr == NULL)
{
AfxMessageBox(_T("VirtualAllocEx失败"));
return;
}
//将线程代码写入到远程进程
DWORD NumberOfBytesWrittenOfProc;
BOOL retWriteProcessMemory=::WriteProcessMemory(HandlToRemoteProcess,threadProcAddr,&threadProc, dwThreadSize, &NumberOfBytesWrittenOfProc);
if(!retWriteProcessMemory)
{
AfxMessageBox(_T("WriteProcessMemory失败"));
return;
}
//构造线程参数
DWORD NumberOfBytesWrittenOfParam;
ToRemoteProccess trp;
ZeroMemory(&trp,sizeof(ToRemoteProccess));
HMODULE hUser32 = LoadLibrary("User32.dll");
trp.MsgBoxAddress = (DWORD)GetProcAddress(hUser32,"MessageBoxA");
_sntprintf(trp.title,sizeof("title"),"%s","title");
_sntprintf(trp.content,sizeof("content"),"%s","content");
//申请参数空间
ToRemoteProccess *pRemoteParamAddr = (ToRemoteProccess *)::VirtualAllocEx(HandlToRemoteProcess,0,sizeof(ToRemoteProccess),MEM_COMMIT,PAGE_READWRITE);
if(pRemoteParamAddr == NULL)
{
AfxMessageBox(_T("VirtualAllocEx失败"));
return;
}
//参数写进内存
retWriteProcessMemory =::WriteProcessMemory(HandlToRemoteProcess,pRemoteParamAddr,&trp, sizeof(ToRemoteProccess), &NumberOfBytesWrittenOfParam);
if(!retWriteProcessMemory)
{
AfxMessageBox(_T("WriteProcessMemory失败"));
return;
}
//创建远程线程
DWORD RemoteThreadId;
HANDLE retRemoteThread=::CreateRemoteThread(HandlToRemoteProcess,NULL,0,(LPTHREAD_START_ROUTINE)threadProcAddr,(LPVOID)pRemoteParamAddr,0 ,&RemoteThreadId);
if (retRemoteThread == NULL)
{
AfxMessageBox(_T("CreateRemoteThread失败"));
return;
}
//清理
VirtualFreeEx(HandlToRemoteProcess,threadProcAddr,dwThreadSize,MEM_RELEASE);
VirtualFreeEx(HandlToRemoteProcess,pRemoteParamAddr,sizeof(ToRemoteProccess),MEM_RELEASE);
FreeLibrary(hUser32);
CloseHandle(HandlToRemoteProcess);
//////////////////////////////////////////////////////////////////////////
// LPVOID VirtualAllocEx(
// HANDLE hProcess,
// LPVOID lpAddress,
// SIZE_T dwSize,
// DWORD flAllocationType,
// DWORD flProtect
// );
//
// hProcess:
// 申请内存所在的进程句柄。
// lpAddress:
// 保留页面的内存地址;一般用NULL自动分配 。
// dwSize:
// 欲分配的内存大小,字节单位;注意实际分 配的内存大小是页内存大小的整数倍
//
// flAllocationType 可取下列值:
// MEM_COMMIT:为特定的页面区域分配内存中或磁盘的页面文件中的物理存储
// MEM_PHYSICAL :分配物理内存(仅用于地址窗口扩展内存)
// MEM_RESERVE:保留进程的虚拟地址空间,而不分配任何物理存储。保留页面可通过继续调用VirtualAlloc()而被占用
// MEM_RESET :指明在内存中由参数lpAddress和dwSize指定的数据无效
// MEM_TOP_DOWN:在尽可能高的地址上分配内存(Windows 98忽略此标志)
// MEM_WRITE_WATCH:必须与MEM_RESERVE一起指定,使系统跟踪那些被写入分配区域的页面(仅针对Windows 98)
//
// flProtect可取下列值:
// PAGE_READONLY: 该区域为只读。如果应用程序试图访问区域中的页的时候,将会被拒绝访
// PAGE_READWRITE 区域可被应用程序读写
// PAGE_EXECUTE: 区域包含可被系统执行的代码。试图读写该区域的操作将被拒绝。
// PAGE_EXECUTE_READ :区域包含可执行代码,应用程序可以读该区域。
// PAGE_EXECUTE_READWRITE: 区域包含可执行代码,应用程序可以读写该区域。
// PAGE_GUARD: 区域第一次被访问时进入一个STATUS_GUARD_PAGE异常,这个标志要和其他保护标志合并使用,表明区域被第一次访问的权限
// PAGE_NOACCESS: 任何访问该区域的操作将被拒绝
// PAGE_NOCACHE: RAM中的页映射到该区域时将不会被微处理器缓存(cached)
//
// 注:PAGE_GUARD和PAGE_NOCHACHE标志可以和其他标志合并使用以进一步指定页的特征。PAGE_GUARD标志指定了一个防护页(guard page),即当一个页被提交时会因第一
// 次被访问而产生一个one-shot异常,接着取得指定的访问权限。PAGE_NOCACHE防止当它映射到虚拟页的时候被微处理器缓存。这个标志方便设备驱动使用直接内存访问方
// 式(DMA)来共享内存块。
//
// 返回值:
// 执行成功就返回分配内存的首地址,不成功就是NULL。
//
//
// BOOL WriteProcessMemory(
// HANDLE hProcess,
// LPVOID lpBaseAddress,
// LPVOID lpBuffer,
// DWORD nSize,
// LPDWORD lpNumberOfBytesWritten
// );
//
// 参数:
// hProcess:由OpenProcess返回的进程句柄。如参数传数据为 INVALID_HANDLE_VALUE 【即-1】目标进程为自身进程
// lpBaseAddress:要写的内存首地址,再写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据。
// lpBuffer:指向要写的数据的指针。
// nSize:要写入的字节数。
// lpNumberOfBytesWritten:成功写入的数据的大小
//
// 返回值:
// 非零值代表成功.
//
// HANDLE CreateRemoteThread(
// HANDLE hProcess,
// LPSECURITY_ATTRIBUTES lpThreadAttributes,
// SIZE_T dwStackSize,
// LPTHREAD_START_ROUTINE lpStartAddress,
// LPVOID lpParameter,
// DWORD dwCreationFlags,
// LPDWORD lpThreadId
// );
// 参数说明:
// hProcess:目标进程的句柄
// lpThreadAttributes:指向线程的安全描述结构体的指针,一般设置为NULL,表示使用默认的安全级别
// dwStackSize:线程堆栈大小,一般设置为0,表示使用默认的大小,一般为1M
// lpStartAddress:线程函数的地址
// lpParameter:线程参数
// dwCreationFlags:线程的创建方式
// lpThreadId:输出参数,记录创建的远程线程的ID
//////////////////////////////////////////////////////////////////////////
}
标签:
原文地址:http://blog.csdn.net/liujiayu2/article/details/45667773