天行健,君子应自强不息 --- 注入DLL,显示窗体
挫折也是进步的原动力.近期郁闷,因为各种原因,不得不开始我不太喜欢的VC++学习.
以前也认真学过一段时间,现在回头发现全忘了.
随笔备份,以防再忘记了又白白浪费时间复习.
注入DLL,比较熟悉的简单东西,就不多说.
1 void CMainDlg::OnOK()
2 {
3 // TODO: Add extra validation here
4
5 HWND hwnd = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
6 TCHAR szClass[MAX_PATH] = {0};
7 TCHAR szText[MAX_PATH] = {0};
8 int nCount = 0;
9 while(hwnd)
10 {
11 ::GetClassName(hwnd, szClass, MAX_PATH);
12 ::GetWindowText(hwnd, szText, MAX_PATH);
13 if(_tcscmp(szClass, _TARGET_CLASS_) == 0)
14 {
15 Install(hwnd);
16 ++nCount;
17 }
18 hwnd = ::GetNextWindow(hwnd, GW_HWNDNEXT);
19 }
20
21 _stprintf(szClass, _T("共计加载 %d 个"), nCount);
22
23 MessageBox(szClass);
24
25 return;
26 }
27
28 BOOL CMainDlg::Install(HWND hwnd)
29 {
30 // get process id
31 DWORD dwProcessID = 0;
32 GetWindowThreadProcessId(hwnd, &dwProcessID);
33 if(!dwProcessID)
34 {
35 MessageBox(_T("ProcessID = 0 ~!!"));
36 return FALSE;
37 }
38
39 // open process by id
40 HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
41 if (!hProc)
42 {
43 MessageBox(_T("can't open process"));
44 return FALSE;
45 }
46
47 // get kernel path
48 char szPath[MAX_PATH] = {0};
49 strcpy(szPath, m_szPath);
50 strcat(szPath, "\\kernel.dll");
51
52 // write path into game's process
53 int nLen = (int)strlen(szPath) + 1;
54 LPVOID AllocMem = VirtualAllocEx(hProc, NULL, nLen * sizeof(char), MEM_COMMIT, PAGE_READWRITE);
55 DWORD dwWritten = 0;
56 WriteProcessMemory(hProc, AllocMem , szPath, nLen * sizeof(char), &dwWritten);
57
58 // get LoadLibraryA
59 FARPROC pLoadLibrary = (FARPROC)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
60 if(!pLoadLibrary)
61 {
62 MessageBox(_T("can't load kernel32.dll"));
63 return FALSE;
64 }
65 HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibrary, (void*)AllocMem, 0, NULL);
66 if(!hThread)
67 {
68 MessageBox(_T("can't create remote thread"));
69 return FALSE;
70 }
71 DWORD Result = WaitForSingleObject(hThread, 15 * 1000); //Time out : 15 seconds
72 if(Result == WAIT_ABANDONED || Result == WAIT_TIMEOUT || Result == WAIT_FAILED)
73 {
74 MessageBox(_T("final error"));
75 return FALSE;
76 }
77 VirtualFreeEx(hProc, (void*)AllocMem, 0, MEM_RELEASE);
78
79 if(hThread)
80 CloseHandle(hThread); // (MSDN: Closing a thread handle does not terminate the associated thread.)
81
82 // finally
83 return TRUE;
84 }
DLL,显示窗体,TabCtrl控件的使用.
建立DLL的时候会有3个类型选择,会导致代码有比较大的区别.见图:
有DllMain的处理方法:
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH:
{
MessageBox( NULL, _T("DLL已进入目标进程。"), _T("信息"), MB_ICONINFORMATION );
}
break;
case DLL_PROCESS_DETACH:
{
MessageBox( NULL, _T("DLL已从目标进程卸载。"), _T("信息"), MB_ICONINFORMATION );
}
break;
default:
break;
}
return TRUE;
}
详细说下没有DllMain的处理方法.其实和上面的没啥太大区别.
CMain *pMain; //全局变量
DWORD WINAPI CreateMyDialog(LPVOID lpParameter)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); //这个不能少.用到资源的时候就加上,原理还不是很清楚
pMain = new CMain; //new个空间出来
pMain->Create(IDD_MAIN); //创建主框架
pMain->ShowWindow(SW_SHOW); //显示主框架
return 0;
}
BOOL CKernelApp::InitInstance() //在CxxxApp类中添加虚函数
{
// TODO: Add your specialized code here and/or call the base class
::CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)CreateMyDialog, (LPVOID)pMain , 0, NULL);
return CWinApp::InitInstance();
}
再所说TabCtrl控件的使用.
1.在主框架上建TabCtrl控件,并关联控件变量m_TabCtrl;
2.建两对话框来用作TabCtrl的页,改对话框属性为child,框架为None,为两个对话框建立两个类;
3.在主界面类的里,建立两个对话框的实例,如: CPage1 m_page1;
4.再主框架类里添加函数,如下;
BOOL CMain::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
//添加页
m_tabCtrl.InsertItem(0, "page1");
m_tabCtrl.InsertItem(1, "page2");
//创建页
m_page1.Create(IDD_PAGE1, &m_tabCtrl);
m_page2.Create(IDD_PAGE2, &m_tabCtrl);
//获取位置,并移动
CRect rc;
m_tabCtrl.GetClientRect(&rc);
rc.top += 30;
rc.bottom -= 8;
rc.left += 8;
rc.right -= 8;
m_page1.MoveWindow(&rc);
m_page2.MoveWindow(&rc);
//保存页面指针,方便操作
pPage[0] = &m_page1;
pPage[1] = &m_page2;
//显示窗口
pPage[0]->ShowWindow(SW_SHOW);
pPage[1]->ShowWindow(SW_HIDE);
//保存当前显示窗口的序号
m_CurPage = 0; //全局变量
this->ShowWindow(SW_SHOW);
this->UpdateWindow();
MSG msg;
while(::GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
5.为TabCtrl添加消息响应处理页面的选择
void CMain::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
//选页消息响应
pPage[m_CurPage]->ShowWindow(SW_HIDE); //隐藏上一页
m_CurPage = m_tabCtrl.GetCurSel(); //获取选中的页
pPage[m_CurPage]->ShowWindow(SW_SHOW); //显示选中的页
*pResult = 0;
}

浙公网安备 33010602011771号