读书人

把DLL注入计算器如何计算器 崩溃了

发布时间: 2013-12-22 15:06:55 作者: rapoo

把DLL注入计算器,怎么计算器 崩溃了,高手指点一下,10多天了无法解决
以下是把DLL注入计算器,怎么计算器 崩溃了
MFC 代码:

BOOL EnableDebugPriv()
{
TOKEN_PRIVILEGES tp;
LUID luid;
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken);
if (hToken==NULL)
{
AfxMessageBox("没有得到令牌句柄");
return 0;
}
///获得进程本地唯一ID
LookupPrivilegeValue(0,SE_DEBUG_NAME,&luid);
tp.PrivilegeCount=1;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid=luid;
//调整权限
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
return TRUE;
}
void Main()
{
CString ErrStr;
if (!EnableDebugPriv())
{
return ;
}

char dllFullPath[MAX_PATH]={"H:\\VC++编程\\数据库\\TestDll\\TestHook\\Debug\\Hook.dll"};
//dllFullPath="H:\\VC++编程\\数据库\\TestDll\\TestHook\\Debug\\Hook.dll";
HWND hCal=::FindWindow(NULL,"计算器");
if (hCal==0)
{
AfxMessageBox("请先打开计算器");
return;
}
DWORD Pid;
DWORD hThread=::GetWindowThreadProcessId(hCal,&Pid);
HANDLE hProcess=::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,FALSE,Pid);
if (hProcess==NULL)
{
AfxMessageBox("无法打开计算器");
return;
}
int cb=(1+lstrlen(dllFullPath))*sizeof(char);
LPVOID lpDllRemote=::VirtualAllocEx(hProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
if (lpDllRemote==NULL)
{
AfxMessageBox("无法分配内存");
return;
}
DWORD dwWriteBuf;
WriteProcessMemory(hProcess,lpDllRemote,dllFullPath,cb,(LPDWORD)&dwWriteBuf);
if (cb!=dwWriteBuf)
{
AfxMessageBox("写入内存失败");
return;
}
HMODULE hMod=::LoadLibrary("Hook.dll");
LPTHREAD_START_ROUTINE StartHook=(LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"StartHook");
if ((DWORD)StartHook==0)
{
AfxMessageBox("取函数地址失败");
return;
}
HANDLE hCreateThread=::CreateRemoteThread(hProcess,NULL,0,StartHook,lpDllRemote,0,NULL);
//hCreateThread运行后,计算器 崩溃了 显示 "0x00d2dv7b"指令引用的"0x00d2dv7b" 内存。该内存不能为"written"
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL,::GetLastError(),0,(LPTSTR)&ErrStr,0,NULL);
AfxMessageBox(ErrStr);
WaitForSingleObject(hCreateThread,INFINITE);
CloseHandle(hCreateThread);
CloseHandle(hProcess);
}
[解决办法]

引用:
远程线程注入的话, 一般是在写入dll路径后, 调用远程的LoadLibrary函数来加载这个dll. 然后在dll入口函数中自动调用你需要要函数.

对啊,我就是这样做的啊。
我是自学VC++,教材上是这么做,为什么我不成功呢?

注意人家说的,是调用远程的LoadLibrary,是远程的LoadLibrary,对你而言就是计算器进程中的LoadLibrary,你上面代码不是这样写的。因为几乎每个进程都会加载Kernel32.dll,而Kernel32中存在函数LoadLibary,因为不管哪个进程,加载的Kernel32的虚拟地址总是一样的,所以你可以在自己的进程中用LPTHREAD_START_ROUTINE pfnThread=(LPTHREAD_START_ROUTINE )::GetProcAddress(::GetModuleHandle(_T("Kernel32")),"LoadLibraryW")获取LoadLibrary的虚拟地址,这个虚拟地址和目标进程中的LoadLibrary的虚拟地址是一样的,所以你可以用这个地址来调用CreateRemoteThread,启动远程进程,也就是通过CreateRemoteThread来调用目标进程中的LoadLibrary,因为此时的LoadLibrary是通过目标进程启动的,所以它加载的DLL当然就是加载进目标进程了,所以也就达到注入的目的了。
[解决办法]
DLL

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

HHOOK hook;

LRESULT CALLBACK KeyProc(int Code,WPARAM wparam,LPARAM lparam)
{
if (wparam==VK_F4)
{
/*CTestDialog dlg;
dlg.DoModal();
dlg.ShowWindow(TRUE);*/
::MessageBox(0, L"F4", 0, 0);
return 0;
}
return CallNextHookEx(hook,Code,wparam,lparam);
}

void _stdcall StartHook()
{
HWND hCal=::FindWindow(NULL,L"计算器");
if (hCal==0)
{
::MessageBox(0, L"请先打开计算器", 0, 0);
return;
}
DWORD hThread=::GetWindowThreadProcessId(hCal,NULL);
hook=::SetWindowsHookEx(WH_KEYBOARD,KeyProc,::GetModuleHandle(_T("Hook.dll")),hThread);
if (hook==NULL)
{
::MessageBox(0, L"没有得到hook", 0, 0);
return;
}
}


EXE
#include "stdafx.h"
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hDll = LoadLibrary(TEXT("hook.dll"));
FARPROC StartHook = GetProcAddress(hDll,"StartHook");
StartHook();
return 0;
}


以上代码完全是没问题的.
DLL注入可以用CreateRemoteThread远程线程方式注入,
也可以用SetWindowsHookEx消息钩子注入

读书人网 >VC/MFC

热点推荐