MSG msg; if(::PeekMessage(&msg;,NULL,0,0,PM_REMOVE)){ if(msg.message==WM_QUIT) { ::PostQuitMessage(-1); }
if(!AfxGetApp()->PreTranslageMessage(&msg;)) { ::TranslateMessage(&msg;); ::DispatchMessage(&msg;); }
君看一叶舟,出没风波里
MSG msg; if(::PeekMessage(&msg;,NULL,0,0,PM_REMOVE)){ if(msg.message==WM_QUIT) { ::PostQuitMessage(-1); }
if(!AfxGetApp()->PreTranslageMessage(&msg;)) { ::TranslateMessage(&msg;); ::DispatchMessage(&msg;); }
核心代码片断:
void CLoadLibraryTestDlg::OnLoad() { typedef int (WINAPI MyFun)(HWND,LPCTSTR,LPCTSTR,UINT); MyFun fun=NULL; HINSTANCE hHandle; hHandle=LoadLibrary(“user32.dll”); fun=(int (WINAPI )(HWND,LPCTSTR,LPCTSTR,UINT))::GetProcAddress(hHandle,”MessageBoxA”); if(fun!=NULL) { fun(NULL,”hahahahahahahaha”,”success :)”,MB_OK); } }
// Injection.cpp : 定义控制台应用程序的入口点。 //
#include “stdafx.h”
#include “Injection.h”
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
typedef struct _RemotePara{//参数结构 char pMessageBox[12]; DWORD dwMessageBox; }RemotePara; //远程线程 DWORD stdcall ThreadProc (RemotePara *lpPara){ typedef int (stdcall *MMessageBoxA)(HWND,LPCTSTR,LPCTSTR,DWORD);//定义MessageBox函数 MMessageBoxA myMessageBoxA; myMessageBoxA =(MMessageBoxA) lpPara->dwMessageBox ;//得到函数入口地址 myMessageBoxA(NULL,lpPara->pMessageBox ,lpPara->pMessageBox,0);//call return 0; } void EnableDebugPriv();//提升应用级调试权限
int _tmain(int argc, TCHAR argv[], TCHAR envp[]) { const DWORD THREADSIZE=10244; DWORD byte_write; EnableDebugPriv();//提升权限 HANDLE hWnd = ::OpenProcess (PROCESS_ALL_ACCESS,FALSE,760); if(!hWnd)return 0; void pRemoteThread =::VirtualAllocEx(hWnd,0,THREADSIZE,MEM_COMMIT| MEM_RESERVE,PAGE_EXECUTE_READWRITE); if(!pRemoteThread)return 0; if(!::WriteProcessMemory(hWnd,pRemoteThread,&ThreadProc;,THREADSIZE,0)) return 0;
//再付值 RemotePara myRemotePara; ::ZeroMemory(&myRemotePara;,sizeof(RemotePara)); HINSTANCE hUser32 = ::LoadLibrary (“user32.dll”); myRemotePara.dwMessageBox =(DWORD) ::GetProcAddress (hUser32 , “MessageBoxA”); strcat(myRemotePara.pMessageBox,”hello\0”); //写进目标进程 RemotePara pRemotePara =(RemotePara ) ::VirtualAllocEx (hWnd ,0,sizeof(RemotePara),MEM_COMMIT,PAGE_READWRITE);//注意申请空间时的页面属性 if(!pRemotePara)return 0; if(!::WriteProcessMemory (hWnd ,pRemotePara,&myRemotePara;,sizeof myRemotePara,0))return 0;
//启动线程 HANDLE hThread = ::CreateRemoteThread (hWnd ,0,0,(DWORD (__stdcall )(void ))pRemoteThread ,pRemotePara,0,&byte;_write); if(!hThread){ return 0; } return 0; }
void EnableDebugPriv( void ) { HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp;
if ( ! OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken; ) ) return; if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue; ) ){ CloseHandle( hToken ); return; } 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 ); }
核心代码片断:
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken;)) { MessageBox(“OpenProcessToken failed!”); }
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges;[0].Luid); //获得本地机唯一的标识
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp;, 0,(PTOKEN_PRIVILEGES) NULL, 0); //调整获得的权限
if (GetLastError() != ERROR_SUCCESS)
{
MessageBox("切换系统级权限失败!");
}
fResult =InitiateSystemShutdown(
NULL, // 要关的计算机用户名
"关机时间已到,WINDOWS将在上面的时间内关机,请做好保存工作!", // 显示的消息
10, // 关机所需的时间
TRUE, // ask user to close apps
FALSE); //设为TRUE为重起,设为FALSE为关机
if(!fResult)
{
MessageBox("初始化系统关机失败!");
}
tkp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tkp;, 0,(PTOKEN_PRIVILEGES) NULL, 0);
if (GetLastError() != ERROR_SUCCESS)
{
MessageBox("AdjustTokenPrivileges disable failed.");
}
ExitWindowsEx(EWX_SHUTDOWN,0);
枚举注册表键名与键值的一个函数:
// QueryKey - Enumerates the subkeys of key, and the associated // values, then copies the information about the keys and values // into a pair of edit controls and list boxes. // hDlg - Dialog box that contains the edit controls and list boxes. // hKey - Key whose subkeys and values are to be enumerated.
void QueryKey(HWND hDlg, HANDLE hKey) { CHAR achKey[MAX_PATH]; CHAR achClass[MAX_PATH] = “”; // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time
DWORD i, j;
DWORD retCode, retValue;
CHAR achValue[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
CHAR achBuff[80];
// Get the class name and the value count.
RegQueryInfoKey(hKey, // key handle
achClass, // buffer for class name
&cchClassName;, // size of class string
NULL, // reserved
&cSubKeys;, // number of subkeys
&cbMaxSubKey;, // longest subkey size
&cchMaxClass;, // longest class string
&cValues;, // number of values for this key
&cchMaxValue;, // longest value name
&cbMaxValueData;, // longest value data
&cbSecurityDescriptor;, // security descriptor
&ftLastWriteTime;); // last write time
SetDlgItemText(hDlg, IDE_CLASS, achClass);
SetDlgItemInt(hDlg, IDE_CVALUES, cValues, FALSE);
SendMessage(GetDlgItem(hDlg, IDL_LISTBOX),
LB_ADDSTRING, 0, (LONG) "..");
// Enumerate the child keys, until RegEnumKeyEx fails. Then
// get the name of each child key and copy it into the list box.
SetCursor(LoadCursor(NULL, IDC_WAIT));
for (i = 0, retCode = ERROR_SUCCESS;
retCode == ERROR_SUCCESS; i++)
{
retCode = RegEnumKeyEx(hKey,
i,
achKey,
MAX_PATH,
NULL,
NULL,
NULL,
&ftLastWriteTime;);
if (retCode == (DWORD)ERROR_SUCCESS)
{
SendMessage(GetDlgItem(hDlg, IDL_LISTBOX),
LB_ADDSTRING, 0, (LONG) achKey);
}
}
SetCursor(LoadCursor (NULL, IDC_ARROW));
// Enumerate the key values.
SetCursor(LoadCursor(NULL, IDC_WAIT));
if (cValues)
{
for (j = 0, retValue = ERROR_SUCCESS;
j < cValues; j++)
{
cchValue = MAX_VALUE_NAME;
achValue[0] = '\0';
retValue = RegEnumValue(hKey, j, achValue,
&cchValue;,
NULL,
NULL, // &dwType;,
NULL, // &bData;,
NULL); // &bcData;
if (retValue == (DWORD) ERROR_SUCCESS )
{
achBuff[0] = '\0';
// Add each value to a list box.
if (!lstrlen(achValue))
lstrcpy(achValue, "");
wsprintf(achBuff, "%d) %s ", j, achValue);
SendMessage(GetDlgItem(hDlg,IDL_LISTBOX2),
LB_ADDSTRING, 0, (LONG) achBuff);
}
}
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
【问题】怎样删除一个非空目录,及其目录里面所有内容: 【解答1】如果不进行递归删除。你可以使用API函数SHFileOperation,它可以一次删除目录及其下面的子目录和文件。 示例代码: BOOL DelTree(LPCTSTR lpszPath) { SHFILEOPSTRUCT FileOp; FileOp.fFlags = FOF_NOCONFIRMATION; FileOp.hNameMappings = NULL; FileOp.hwnd = NULL; FileOp.lpszProgressTitle = NULL; FileOp.pFrom = lpszPath; FileOp.pTo = NULL; FileOp.wFunc = FO_DELETE; return SHFileOperation(&FileOp;) == 0; }
【解答2】使用递归调用,逐个删除: 示例代码:
BOOL DeleteDirectory(char DirName)//如删除 DeleteDirectory(“c:\aaa”) { CFileFind tempFind; char tempFileFind[MAX_PATH]; sprintf(tempFileFind,”%s\.*”,DirName); BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind); while(IsFinded) { IsFinded=(BOOL)tempFind.FindNextFile(); if(!tempFind.IsDots()) { char foundFileName[MAX_PATH]; strcpy(foundFileName,tempFind.GetFileName().GetBuffer(MAX_PATH)); if(tempFind.IsDirectory()) { char tempDir[MAX_PATH]; sprintf(tempDir,”%s\%s”,DirName,foundFileName); DeleteDirectory(tempDir); } else { char tempFileName[MAX_PATH]; sprintf(tempFileName,”%s\%s”,DirName,foundFileName); DeleteFile(tempFileName); } } } tempFind.Close(); if(!RemoveDirectory(DirName)) { MessageBox(0,”删除目录失败!”,”警告信息”,MB_OK);//比如没有找到文件夹,删除失败,可把此句删除 return FALSE; } return TRUE; }
回调函数:
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { BOOL fEatKeystroke = FALSE; PKBDLLHOOKSTRUCT p = NULL;
if (nCode == HC_ACTION)
{
p = (PKBDLLHOOKSTRUCT) lParam;
switch (wParam)
{
case WM_KEYDOWN:
// Backdoor to user information
if (p->vkCode == VK_F8)
{
::MessageBox(NULL,"Let's make things better and better!\n","HQ Tech",MB_OK);
break;
}
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
fEatKeystroke = (p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN) || // 屏蔽Win
// 屏蔽Alt+Tab
((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) ||
// 屏蔽Alt+Esc
((p->vkCode == VK_ESCAPE) && ((p->flags & LLKHF_ALTDOWN) != 0)) ||
// 屏蔽Ctrl+Esc
((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0));
break;
default:
break;
}
}
return (fEatKeystroke ? TRUE : CallNextHookEx(glhHook,nCode,wParam,lParam)); }
安装及卸载钩子:
void _stdcall StartKeyMask() { // 安装钩子 glhHook = SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,glhInstance,0); }
void _stdcall StopKeyMask() { // 卸载钩子 if (glhHook!=NULL) UnhookWindowsHookEx(glhHook); }
示例代码:
void CModifylayerDlg::OnChange() { HWND hWindow=NULL; hWindow=::FindWindow(NULL,”扫雷”); typedef BOOL (WINAPI *lpfn)(HWND hWnd,COLORREF cr,BYTE bAlpha,DWORD dwFlags); lpfn g_pSetLayeredWindowAttributes; HMODULE hUser32 = GetModuleHandle(_T(“USER32.DLL”)); g_pSetLayeredWindowAttributes = (lpfn)GetProcAddress(hUser32,”SetLayeredWindowAttributes”); ::SetWindowLong(hWindow,GWL_EXSTYLE,GetWindowLong(hWindow,GWL_EXSTYLE)^WS_EX_LAYERED); g_pSetLayeredWindowAttributes(hWindow,5,50,2); ::RedrawWindow(hWindow, NULL, NULL,RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); }
void EnablePrivilege() { HANDLE hProcess; HANDLE hCurrentProcess; HANDLE hProcessToken; TOKEN_PRIVILEGES tp; LUID luid; hCurrentProcess=GetCurrentProcess(); OpenProcessToken(hCurrentProcess,TOKEN_ALL_ACCESS,&hProcessToken;); LookupPrivilegeValue(NULL,”SeDebugPrivilege”,&luid;); tp.PrivilegeCount=1; tp.Privileges[0].Luid=luid; tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges( hProcessToken, FALSE, &tp;, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL); }
包含头文件:
#include “tlhelp32.h” 示例:
void CTerminateProcessDlg::OnGetProcess() { m_ListBox.ResetContent(); CString m_output; HANDLE hProcessSnap=NULL; PROCESSENTRY32 pe32={0}; hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if(hProcessSnap==(HANDLE)-1) { ::MessageBox(NULL,”查询进程失败!:(“,”错误提示”,MB_OK);
}
pe32.dwSize=sizeof(PROCESSENTRY32);
if(Process32First(hProcessSnap,&pe32;))
{
do
{
m_output.Format("%-20s ID:%-5d",pe32.szExeFile,pe32.th32ProcessID);
m_ListBox.AddString(m_output);
}
while(Process32Next(hProcessSnap,&pe32;));
}
else
{
::MessageBox(NULL,"出现意外错误!","错误提示",MB_OK);
}
CloseHandle(hProcessSnap);
}
在OnPaint函数中加入:
CPaintDC dc(this); CRect rect; GetClientRect(▭);//得到窗体的大小 CDC dcMem; dcMem.CreateCompatibleDC(&dc;); CBitmap bmpBackground; bmpBackground.LoadBitmap(IDB_BITMAPBACKGROUND);//加载背景图片 BITMAP bitMap; bmpBackground.GetBitmap(&bitMap;); CBitmap *pbmpOld=dcMem.SelectObject(&bmpBackground;); dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem;,0,0,bitMap.bmWidth,bitMap.bmHeight,SRCCOPY);//画窗体
在一般情况下编写的对话框程序,用户在运行的时候,如果不注意按下了ENTER或者ESC键,程序就会立刻退出,之所以会这样,是因为按下Enter键时,Windows就会自动去找输入焦点落在了哪一个按钮上,当获得焦点的按钮的四周将被点线矩形包围。如果所有按钮都没有获得输入焦点,Windows就会自动去寻找程序或资源所指定的默认按钮(默认按钮边框较粗)。如果对话框没有默认按钮,那么即使对话框中没有OK按钮,OnOK函数也会自动被调用,对于一个普通的对话框程序来说,OnOK函数的调用,以为着程序会立刻退出。为了使Enter键无效,最简单的办法就是将CExDlg的OnOK函数写成空函数,然后针对OK按钮写一个新的函数来响应。ESC键的原理也是如此,它是默认和OnCancel函数映射在一起的。对于ESC键,需要自己重载CDialog类的PreTranslateMessage函数,当发现是ESC键的时候,过滤掉这个消息或者是替换掉这个消息。
一下是简单的代码示例:
[biggrin]【方法1】 可以先重载OnOK函数 voidCTestDlg::OnOK() { //里面什么也不写}
然后重载PreTranslateMessage函数 把ESC键的消息,用RETURN键的消息替换,这样,按ESC的时候,也会执行刚才的OnOK函数,这样问题就可以解决了。
BOOL CxxxDlg::PreTranslateMessage(MSG* pMsg) { if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_ESCAPE) { pMsg->wParam=VK_RETURN; //将ESC键的消息替换为回车键的消息,这样,按ESC的时候 //也会去调用OnOK函数,而OnOK什么也不做,这样ESC也被屏蔽 } return CDialog::PreTranslateMessage(pMsg);
}
[biggrin]【方法2】
直接在重载的PreTranslateMessage函数中屏蔽回车和ESC的消息,和以上方法大同小异:
BOOL CxxxDlg::PreTranslateMessage(MSG* pMsg) { if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_ESCAPE) return TRUE; if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN) return TRUE; else return CDialog::PreTranslateMessage(pMsg); }