[toc]
常用代码段
0x01 GetProcessId-获取进程id
获取进程id
CreateToolhelp32Snapshot
Process32First
Process32Next
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 DWORD processNameToId (LPCTSTR lpszProcessName) { HANDLE hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 ); PROCESSENTRY32 pe; pe.dwSize = sizeof (PROCESSENTRY32); if (!Process32First (hSnapshot, &pe)) { MessageBox (NULL , "The frist entry of the process list has not been copyied to the buffer" , "Notice" , MB_ICONINFORMATION | MB_OK); return 0 ; } while (Process32Next (hSnapshot, &pe)) { if (!strcmp (lpszProcessName, pe.szExeFile)) { return pe.th32ProcessID; } } return 0 ; }
1 2 3 4 5 DWORD dwProcessId = processNameToId (szExeName);if (dwProcessId == 0 ) { MessageBox (NULL , "The target process have not been found !" , "Notice" , MB_ICONINFORMATION | MB_OK); return -1 ; }
0x04 OpenProcess-打开目标进程
1 2 3 4 5 HANDLE hTargetProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, dwProcessId);if (!hTargetProcess) { MessageBox (NULL , "Open target process failed !" , "Notice" , MB_ICONINFORMATION | MB_OK); return 0 ; }
0x03 IsWow64-判断目标进程是不是64位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 BOOL IsWow64 (HANDLE hProcess) { typedef BOOL (WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL) ; LPFN_ISWOW64PROCESS fnIsWow64Process; BOOL bIsWow64 = FALSE; fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress ( GetModuleHandle ("kernel32" ), "IsWow64Process" ); if (NULL != fnIsWow64Process) { fnIsWow64Process (hProcess, &bIsWow64); } return bIsWow64; }
0x04 Is64BitOs-判断当前机器是不是 64bit。
主要用的API为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 BOOL Is64BitOS () { typedef VOID (WINAPI* LPFN_GetNativeSystemInfo) (__out LPSYSTEM_INFO lpSystemInfo) ; LPFN_GetNativeSystemInfo fnGetNativeSystemInfo = (LPFN_GetNativeSystemInfo)GetProcAddress (GetModuleHandle ("kernel32" ), "GetNativeSystemInfo" ); if (fnGetNativeSystemInfo) { SYSTEM_INFO stInfo = { 0 }; fnGetNativeSystemInfo (&stInfo); if (stInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 || stInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { return TRUE; } } return FALSE; }
0x05 EnableDebugPriv-本地提权
OpenProcessToken
LookupPrivilegeValue
AdjustTokenPrivileges
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 ; }
getProcessAddr-获取目标进程首地址
主要逻辑,获取目标进程的快照,检索第一个模块的信息并返回模块的 modBaseAddr
CreateToolhelp32Snapshot:获取指定进程以及这些进程使用的堆、模块和线程的快照。
Module32First
MODULEENTRY32
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 BOOL CImageBloodDlg::getProcessAddr (DWORD dwPID, DWORD& baseAddr) { HANDLE hModuleSnap = INVALID_HANDLE_VALUE; MODULEENTRY32 me32; hModuleSnap = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, dwPID); if (hModuleSnap == INVALID_HANDLE_VALUE) { AfxMessageBox (_T("CreateToolhelp32Snapshot (of modules) fail" )); return (FALSE); } me32.dwSize = sizeof (MODULEENTRY32); if (!Module32First (hModuleSnap, &me32)) { AfxMessageBox (_T("Module32First fail" )); CloseHandle (hModuleSnap); return (FALSE); } baseAddr = (DWORD)me32.modBaseAddr; CloseHandle (hModuleSnap); return (TRUE); }
获取PEB
来源:libpeconv/libpeconv/src/peb_lookup.cpp· hasherezade/libpeconv
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 inline PPEB get_peb () {#if defined(_WIN64) return (PPEB)__readgsqword(0x60 );#else return (PPEB)__readfsdword(0x30 );#endif }
判断磁盘时候开启了写保护
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 BOOL IsWriteProtected ( TCHAR wcDrive ) { TCHAR szPath[10 ] = L"\\\\.\\A:\0" ; szPath[4 ] = wcDrive; HANDLE hDevice = CreateFile (szPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL , OPEN_EXISTING, 0 , NULL ); if (hDevice == INVALID_HANDLE_VALUE) { return FALSE; } BOOL bRet = FALSE; DWORD dwBytesReturn = 0 ; BOOL bWriteable = ::DeviceIoControl (hDevice, IOCTL_DISK_IS_WRITABLE, NULL , 0 , NULL , 0 , (LPDWORD) &dwBytesReturn, NULL ); if (bWriteable) { bRet = FALSE; } else { bRet = ::GetLastError () == ERROR_WRITE_PROTECT ? TRUE:FALSE; } ::CloseHandle (hDevice); return bRet; }
经验
0x01 临时关闭编译告警
1 2 3 4 #pragma warning (push) #pragma warning (disable:4305) pCandidate=(VOID PTR_T PTR_T)ModuleSectionInfo.pBase;#pragma warning (pop)
0x02 修改结构体对齐方式
使用 #pragma pack(1)
之后,结构体最小对齐的字节为1。好处是可以让编译器按照更紧凑的方式存储数据,从而节省内存空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 struct TestStruct { char a; int b; double c; }; #pragma pack(1) struct TestPackStruct { char a; int b; double c; }; #pragma pack()
0x03 未使用的参数、变量
消除未使用参数和结构体警告可以使用下面几个宏:
1 2 3 4 #define UNREFERENCED_PARAMETER(P) {(P) = (P);} #define UNREFERENCED_LOCAL_VARIABLE(V) {(V) = (V);} #define DBG_UNREFERENCED_PARAMETER(P) (P) #define DBG_UNREFERENCED_LOCAL_VARIABLE(V) (V)