ExFreePool

ExFreePool

The ExFreePool routine deallocates a block of pool memory.

VOID
ExFreePool(
IN PVOID P
    );

Parameters
P
Specifies the address of the block of pool memory being deallocated.
Return Value

None

Comments

This routine releases memory allocated by ExAllocatePool , ExAllocatePoolWithTag , ExAllocatePoolWithQuota , or ExAllocatePoolWithQuotaTag . The memory block must not be accessed after it is freed.

Drivers can also use the ExFreePoolWithTag routine to free buffers allocated by ExAllocatePoolWithTag and ExAllocatePoolWithQuotaTag .

Callers of ExFreePool must be running at IRQL <= DISPATCH_LEVEL. A caller at DISPATCH_LEVEL must have specified a NonPaged Xxx PoolType when the memory was allocated. Otherwise, the caller must be running at IRQL <= APC_LEVEL.

Requirements

IRQL: <= DISPATCH_LEVEL (see Comments section)

Headers: Declared in Wdm.h . Include Wdm.h , Ntddk.h , or Ntifs.h .

#pragma warning( disable: 4100 4103 4706) #include "ntifs.h" #include "processlist.h" #include "threads.h" #include "memscan.h" #include "ultimap2.h" PRTL_GENERIC_TABLE InternalProcessList = NULL; PEPROCESS WatcherProcess = NULL; BOOLEAN ProcessWatcherOpensHandles = TRUE; RTL_GENERIC_COMPARE_RESULTS NTAPI ProcessListCompare(__in struct _RTL_GENERIC_TABLE *Table, __in PProcessListData FirstStruct, __in PProcessListData SecondStruct) { //DbgPrint("ProcessListCompate"); if (FirstStruct->ProcessID == SecondStruct->ProcessID) return GenericEqual; else { if (SecondStruct->ProcessID < FirstStruct->ProcessID) return GenericLessThan; else return GenericGreaterThan; } } PVOID NTAPI ProcessListAlloc(__in struct _RTL_GENERIC_TABLE *Table, __in CLONG ByteSize) { PVOID r=ExAllocatePool(PagedPool, ByteSize); RtlZeroMemory(r, ByteSize); //DbgPrint("ProcessListAlloc %d",(int)ByteSize); return r; } VOID NTAPI ProcessListDealloc(__in struct _RTL_GENERIC_TABLE *Table, __in __drv_freesMem(Mem) __post_invalid PVOID Buffer) { //DbgPrint("ProcessListDealloc"); ExFreePool(Buffer); } VOID GetThreadData(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { struct ThreadData *tempThreadEntry; PETHREAD selectedthread; HANDLE tid; LARGE_INTEGER Timeout; PKAPC AP; tempThreadEntry=Context; DbgPrint("Gathering PEThread thread\n"); Timeout.QuadPart = -1; KeDelayExecutionThread(KernelMode, TRUE, &Timeout); selectedthread=NULL; if (ExAcquireResourceSharedLite(&ProcesslistR, TRUE)) { tid = tempThreadEntry->ThreadID; AP = &tempThreadEntry->SuspendApc; PsLookupThreadByThreadId((PVOID)tid, &selectedthread); if (selectedthread) { DbgPrint("PEThread=%p\n", selectedthread); KeInitializeApc(AP, (PKTHREAD)selectedthread, 0, (PKKERNEL_ROUTINE)Ignore, (PKRUNDOWN_ROUTINE)NULL, (PKNORMAL_ROUTINE)SuspendThreadAPCRoutine, KernelMode, NULL); ObDereferenceObject(selectedthread); } else { DbgPrint("Failed getting the pethread.\n"); } } ExReleaseResourceLite(&ProcesslistR); } VOID CreateThreadNotifyRoutine(IN HANDLE ProcessId,IN HANDLE ThreadId,IN BOOLEAN Create) { if (KeGetCurrentIrql()==PASSIVE_LEVEL) { /*if (DebuggedProcessID==(ULONG)ProcessId) { // PsSetContextThread (bah, xp only) }*/ if (ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE)) { if (ThreadEventCount < 50) { ThreadEventData[ThreadEventCount].Created = Create; ThreadEventData[ThreadEventCount].ProcessID = (UINT_PTR)ProcessId; ThreadEventData[ThreadEventCount].ThreadID = (UINT_PTR)ThreadId; /* if (Create) DbgPrint("Create ProcessID=%x\nThreadID=%x\n",(UINT_PTR)ProcessId,(UINT_PTR)ThreadId); else DbgPrint("Destroy ProcessID=%x\nThreadID=%x\n",(UINT_PTR)ProcessId,(UINT_PTR)ThreadId); */ ThreadEventCount++; } } ExReleaseResourceLite(&ProcesslistR); KeSetEvent(ThreadEvent, 0, FALSE); KeClearEvent(ThreadEvent); } } VOID CreateProcessNotifyRoutine(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create) { PEPROCESS CurrentProcess = NULL; HANDLE ProcessHandle = 0; /* if (PsSuspendProcess) { DbgPrint("Suspending process %d", PsGetCurrentThreadId()); PsSuspendProcess(PsGetCurrentProcess()); DbgPrint("After PsGetCurrentProcess()"); } */ if (KeGetCurrentIrql()==PASSIVE_LEVEL) { struct ProcessData *tempProcessEntry; //aquire a spinlock if (ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE)) { if (PsLookupProcessByProcessId((PVOID)ProcessId, &CurrentProcess) != STATUS_SUCCESS) { ExReleaseResourceLite(&ProcesslistR); return; } if ((ProcessWatcherOpensHandles) && (WatcherProcess)) { if (Create) { //Open a handle to this process /* HANDLE ph = 0; NTSTATUS r = ObOpenObjectByPointer(CurrentProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &ph); DbgPrint("CreateProcessNotifyRoutine: ObOpenObjectByPointer=%x ph=%x", r, ph); r = ZwDuplicateObject(ZwCurrentProcess(), ph, WatcherHandle, &ProcessHandle, PROCESS_ALL_ACCESS, 0, DUPLICATE_CLOSE_SOURCE); DbgPrint("CreateProcessNotifyRoutine: ZwDuplicateObject=%x (handle=%x)", r, ProcessHandle); */ KAPC_STATE oldstate; KeStackAttachProcess((PKPROCESS)WatcherProcess, &oldstate); __try { __try { ObOpenObjectByPointer(CurrentProcess, 0, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &ProcessHandle); } __except (1) { DbgPrint("Exception during ObOpenObjectByPointer"); } } __finally { KeUnstackDetachProcess(&oldstate); } } if (InternalProcessList == NULL) { InternalProcessList = ExAllocatePool(PagedPool, sizeof(RTL_GENERIC_TABLE)); if (InternalProcessList) RtlInitializeGenericTable(InternalProcessList, ProcessListCompare, ProcessListAlloc, ProcessListDealloc, NULL); } if (InternalProcessList) { ProcessListData d, *r; d.ProcessID = ProcessId; d.PEProcess = CurrentProcess; d.ProcessHandle = ProcessHandle; r = RtlLookupElementGenericTable(InternalProcessList, &d); if (Create) { //add it to the list BOOLEAN newElement = FALSE; if (r) //weird { DbgPrint("Duplicate PID detected..."); RtlDeleteElementGenericTable(InternalProcessList, r); } r = RtlInsertElementGenericTable(InternalProcessList, &d, sizeof(d), &newElement); DbgPrint("Added handle %x for pid %d to the list (newElement=%d r=%p)", (int)(UINT_PTR)d.ProcessHandle, (int)(UINT_PTR)d.ProcessID, newElement, r); } else { //remove it from the list (if it's there) DbgPrint("Process %d destruction. r=%p", (int)(UINT_PTR)d.ProcessID, r); if (r) { DbgPrint("Process that was in the list has been closed"); //if (r->ProcessHandle) // ZwClose(r->ProcessHandle); //RtlDeleteElementGenericTable(InternalProcessList, r); r->Deleted = 1; } if (CurrentProcess == WatcherProcess) { DbgPrint("CE Closed"); //ZwClose(WatcherHandle); CleanProcessList(); //CE closed WatcherProcess = 0; } } } } //fill in a processcreateblock with data if (ProcessEventCount < 50) { ProcessEventdata[ProcessEventCount].Created = Create; ProcessEventdata[ProcessEventCount].ProcessID = (UINT_PTR)ProcessId; ProcessEventdata[ProcessEventCount].PEProcess = (UINT_PTR)CurrentProcess; ProcessEventCount++; } //if (!HiddenDriver) if (FALSE) //moved till next version { if (Create) { //allocate a block of memory for the processlist tempProcessEntry = ExAllocatePool(PagedPool, sizeof(struct ProcessData)); tempProcessEntry->ProcessID = ProcessId; tempProcessEntry->PEProcess = CurrentProcess; tempProcessEntry->Threads = NULL; DbgPrint("Allocated a process at:%p\n", tempProcessEntry); if (!processlist) { processlist = tempProcessEntry; processlist->next = NULL; processlist->previous = NULL; } else { tempProcessEntry->next = processlist; tempProcessEntry->previous = NULL; processlist->previous = tempProcessEntry; processlist = tempProcessEntry; } } else { //find this process and delete it tempProcessEntry = processlist; while (tempProcessEntry) { if (tempProcessEntry->ProcessID == ProcessId) { int i; if (tempProcessEntry->next) tempProcessEntry->next->previous = tempProcessEntry->previous; if (tempProcessEntry->previous) tempProcessEntry->previous->next = tempProcessEntry->next; else processlist = tempProcessEntry->next; //it had no previous entry, so it's the root /* if (tempProcessEntry->Threads) { struct ThreadData *tempthread,*tempthread2; KIRQL OldIrql2; tempthread=tempProcessEntry->Threads; tempthread2=tempthread; DbgPrint("Process ended. Freeing threads\n"); while (tempthread) { tempthread=tempthread->next; DbgPrint("Free thread %p (next thread=%p)\n",tempthread2,tempthread); ExFreePool(tempthread2); tempthread2=tempthread; } } ExFreePool(tempProcessEntry);*/ i = 0; tempProcessEntry = processlist; while (tempProcessEntry) { i++; tempProcessEntry = tempProcessEntry->next; } DbgPrint("There are %d processes in the list\n", i); break; } tempProcessEntry = tempProcessEntry->next; } } } } ExReleaseResourceLite(&ProcesslistR); if (CurrentProcess!=NULL) ObDereferenceObject(CurrentProcess); //signal process event (if there's one waiting for a signal) if (ProcessEvent) { KeSetEvent(ProcessEvent, 0, FALSE); KeClearEvent(ProcessEvent); } } } VOID CreateProcessNotifyRoutineEx(IN HANDLE ParentId, IN HANDLE ProcessId, __in_opt PPS_CREATE_NOTIFY_INFO CreateInfo) { DbgPrint("CreateProcessNotifyRoutineEx"); CreateProcessNotifyRoutine(ParentId, ProcessId, CreateInfo!=NULL); } HANDLE GetHandleForProcessID(IN HANDLE ProcessID) { if (InternalProcessList) { ProcessListData d, *r; d.ProcessID = ProcessID; r = RtlLookupElementGenericTable(InternalProcessList, &d); if (r) { DbgPrint("Found a handle for PID %d (%x)", (int)(UINT_PTR)ProcessID, (int)(UINT_PTR)r->ProcessHandle); return r->ProcessHandle; // r->ProcessHandle; } } return 0; } VOID CleanProcessList() { if (InternalProcessList) { PProcessListData li; if (ExAcquireResourceExclusiveLite(&ProcesslistR, TRUE)) { KAPC_STATE oldstate; BOOLEAN ChangedContext; if ((WatcherProcess) && (WatcherProcess != PsGetCurrentProcess())) { KeStackAttachProcess((PKPROCESS)WatcherProcess, &oldstate); ChangedContext = TRUE; } while (li = RtlGetElementGenericTable(InternalProcessList, 0)) { if ((li->ProcessHandle) && (WatcherProcess)) ZwClose(li->ProcessHandle); RtlDeleteElementGenericTable(InternalProcessList, li); } ExFreePool(InternalProcessList); InternalProcessList = NULL; } ExReleaseResourceLite(&ProcesslistR); } }
最新发布
09-29
#include <ntifs.h> #include <ntddk.h> #include <ntimage.h> #define RELOC_FLAG64(ReInfo) ((ReInfo>>0x0C)==IMAGE_REL_BASED_DIR64) #define RELOC_FLAG RELOC_FLAG64 ULONG64 g_fnLoadLibrary ; ULONG64 g_fnGetProcAddress ; ULONG64 g_fnRtlAddFuntion ; void Log(const char* sz_info, bool is_error, ULONG err_code); EXTERN_C NTSTATUS MmCopyVirtualMemory( IN PEPROCESS FromProcess, IN CONST VOID* FromAddress, IN PEPROCESS ToProcess, OUT PVOID ToAddress, IN SIZE_T BufferSize, IN KPROCESSOR_MODE PreviousMode, OUT PSIZE_T NumberOfBytesCopied ); EXTERN_C NTSTATUS NTAPI ZwSetInformationProcess( __in HANDLE ProcessHandle, __in PROCESSINFOCLASS ProcessInformationClass, __in_bcount (ProcessInformationLength) PVOID ProcessInformation, __in ULONG ProcessInformationLength ); typedef PVOID HINSTANCE, HMODULE; using f_LoadLibraryA = HMODULE(_stdcall*)(const char* lpLibFileName); using f_GetProcAddress = PVOID(_stdcall*)(HMODULE hModule, LPCSTR lpProcName); using f_DLL_ENTRY_POINT = BOOLEAN(_stdcall*)(PVOID DllHandle, ULONG Reason, PVOID Reserved); using f_RtlAddFunctionTable = BOOLEAN(_stdcall*)(_IMAGE_RUNTIME_FUNCTION_ENTRY* FunctionTable, DWORD32 EntryCount, DWORD64 BaseAddress); struct Manual_Mapping_data { //用于重定位iat f_LoadLibraryA pLoadLibraryA; f_GetProcAddress pGetProcAddress; //x64专有 f_RtlAddFunctionTable pRtlAddFunctionTable; char* pBase; DWORD32 dwReadson; //设置为0线程开始时执行dll PVOID reserveParam; BOOLEAN bFirst;//只允许第一次系统调用进入 BOOLEAN bStart;//开始执行shellcode了 可以同步关闭instCallBack BOOLEAN bContinue;//用于继续执行 去掉pe头后执行dllmain size_t DllSize; }; void __stdcall InstruShellCode(Manual_Mapping_data* pData); #pragma pack(push) #pragma pack(1) struct shellcode_t { private: char padding[43]; public: uintptr_t manual_data; private: char pdding[47]; public: uintptr_t rip; uintptr_t shellcode; }; char g_instcall_shel1code[] = { 0x50, 0x51, 0x52, 0x53, 0x55, 0x56, 0x57, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48,0x89 ,0x25,0x4C,0x00,0x00,0x00, 0x48, 0x83, 0xEC, 0x38, 0x48,0x81,0xE4,0xF0,0xFF,0xFF,0xFF, 0x48,0xB9,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, 0xFF,0x15,0x29,0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,//call 0x48, 0x8B, 0x25, 0x22,0x00,0x00,0x00, 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58, 0x5F, 0x5E, 0x5D, 0x5B, 0x5A, 0x59, 0x58, 0x41, 0xFF, 0xE2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; #pragma pack(pop) NTSTATUS inst_callback_set_callback(PVOID inst_callback) { NTSTATUS status = STATUS_SUCCESS; PVOID InstCallBack = inst_callback; PACCESS_TOKEN Token{ 0 }; PULONG TokenMask{ 0 }; Token = PsReferencePrimaryToken(IoGetCurrentProcess()); TokenMask = (PULONG)((ULONG_PTR)Token + 0x40);//取_TOKEN结构下Privileges TokenMask[0] |= 0x100000; TokenMask[1] |= 0x100000; TokenMask[2] |= 0x100000; status = ZwSetInformationProcess(NtCurrentProcess(), ProcessInstrumentationCallback, &InstCallBack, sizeof(PVOID)); if (!NT_SUCCESS(status)) { Log("failed to set instrcallback !", true, status); } else { Log("failed to set instrcallback SUCCESS!", false, 0); } return status; } void Log(const char* sz_info, bool is_error, ULONG err_code) { if (is_error) { DbgPrintEx(77, 0, "[instCallBack Error] : %s err_code:%x\n", sz_info, err_code); } else { DbgPrintEx(77, 0, "[instCallBack] : %s \n", sz_info); } } PUCHAR inst_callback_get_dll_memory(UNICODE_STRING* us_dll_path) { NTSTATUS status = STATUS_SUCCESS; HANDLE hFile = 0; OBJECT_ATTRIBUTES objattr = { 0 }; IO_STATUS_BLOCK IoStatusBlock = { 0 }; LARGE_INTEGER lainter = { 0 }; LARGE_INTEGER byteOffset = { 0 }; FILE_STANDARD_INFORMATION fileinfo = { 0 }; ULONG64 fileSize = 0; PUCHAR pDllMemory = 0; InitializeObjectAttributes(&objattr, us_dll_path, OBJ_CASE_INSENSITIVE, 0, 0); status = ZwCreateFile(&hFile, GENERIC_READ, &objattr, &IoStatusBlock, &lainter, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, FILE_OPEN, 0, 0, 0); if (!NT_SUCCESS(status)) { Log("failed to Create File!", true, status); return 0; } status = ZwQueryInformationFile(hFile, &IoStatusBlock, &fileinfo, sizeof(fileinfo), FileStandardInformation); fileSize = (ULONG)fileinfo.AllocationSize.QuadPart; if (!NT_SUCCESS(status)) { Log("failed to get File size!", true, status); return 0; } fileSize += 0x1000; fileSize = (ULONG64)PAGE_ALIGN(fileSize); //ExAllocatePoolWithTag pDllMemory = (PUCHAR)ExAllocatePoolWithTag(PagedPool, fileSize, 'Dllp'); //pDllmem = (PUCHAR)ExAllocatePool3(NonPagedPool, fileSize, 'Dllp', NULL, NULL);//NonPagedPool PagedPool RtlSecureZeroMemory(pDllMemory, fileSize); status = ZwReadFile(hFile, 0, 0, 0, &IoStatusBlock, pDllMemory, fileSize, &byteOffset, 0); ZwFlushBuffersFile(hFile, &IoStatusBlock); if (!NT_SUCCESS(status)) { ExFreePool(pDllMemory); ZwClose(hFile); Log("failed to read File context!", true, status); return 0; } ZwClose(hFile); return pDllMemory; } NTSTATUS inst_callback_alloc_memory(PUCHAR p_dll_memory, _Out_ PVOID* inst_callbak_addr, PVOID* p_manual_data) { PEPROCESS Process{ 0 }; IMAGE_NT_HEADERS* pNtHeader = nullptr; IMAGE_FILE_HEADER* pFileHeader = nullptr; IMAGE_OPTIONAL_HEADER* pOptheader = nullptr; NTSTATUS status = STATUS_SUCCESS; PVOID pManualMapData = 0,pShellCode = 0; char* pStartMapAdd = 0; size_t AllocSize = 0, RETSize; Manual_Mapping_data ManualMapData{ 0 }; if (reinterpret_cast<IMAGE_DOS_HEADER*>(p_dll_memory)->e_magic != 0x5A4D) { status = STATUS_INVALID_PARAMETER; Log("the dll is not valid pe structure\n", true, status); return status; } pNtHeader = (IMAGE_NT_HEADERS*)((ULONG_PTR)p_dll_memory + reinterpret_cast<IMAGE_DOS_HEADER*>(p_dll_memory)->e_lfanew); pFileHeader = &pNtHeader->FileHeader; pOptheader = &pNtHeader->OptionalHeader; if (pFileHeader->Machine != IMAGE_FILE_MACHINE_AMD64) { status = STATUS_INVALID_PARAMETER; Log("the dll is is x86 structure ,not support!\n", true, status); return status; } AllocSize = pOptheader->SizeOfImage; status = ZwAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&pStartMapAdd, 0, &AllocSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(status)) { Log("failed to alloc Memory!", true, status); return status; } RtlSecureZeroMemory(pStartMapAdd, AllocSize); ManualMapData.dwReadson = 0; ManualMapData.pGetProcAddress = (f_GetProcAddress)g_fnGetProcAddress; ManualMapData.pLoadLibraryA = (f_LoadLibraryA)g_fnLoadLibrary; ManualMapData.pRtlAddFunctionTable = (f_RtlAddFunctionTable)g_fnRtlAddFuntion; ManualMapData.pBase = pStartMapAdd; ManualMapData.bContinue = false;//判断是否抹除了pe标识 ManualMapData.bFirst = true; ManualMapData.bStart = false; ManualMapData.DllSize = AllocSize; Process = IoGetCurrentProcess(); status = MmCopyVirtualMemory(Process, p_dll_memory, Process, pStartMapAdd, PAGE_SIZE, KernelMode, &RETSize); if (!NT_SUCCESS(status)) { Log("failed to load pe header!", true, status); return status; } IMAGE_SECTION_HEADER* pSectionHeadr = IMAGE_FIRST_SECTION(pNtHeader); for (size_t i = 0; i < pFileHeader->NumberOfSections; i++, pSectionHeadr++) { if (pSectionHeadr->SizeOfRawData) { status = MmCopyVirtualMemory(Process, p_dll_memory + pSectionHeadr->PointerToRawData, Process, pStartMapAdd + pSectionHeadr->VirtualAddress, pSectionHeadr->SizeOfRawData, KernelMode, &RETSize); if (!NT_SUCCESS(status)) { Log("failed to load pe header!", true, status); return status; } } } AllocSize = PAGE_SIZE; status = ZwAllocateVirtualMemory(NtCurrentProcess(), &pManualMapData, 0, &AllocSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(status)) { Log("failed to alloc Memory for maunalmapdata!", true, status); return status; } RtlSecureZeroMemory(pManualMapData, AllocSize); status = MmCopyVirtualMemory(Process, &ManualMapData, Process, pManualMapData, sizeof(ManualMapData), KernelMode, &RETSize); if (!NT_SUCCESS(status)) { Log("failed to write Memory for maunalmapdata!", true, status); return status; } //重定位ShellCode status = ZwAllocateVirtualMemory(NtCurrentProcess(), &pShellCode, 0, &AllocSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(status)) { Log("failed to alloc Memory for shellcode!", true, status); return status; } RtlSecureZeroMemory(pShellCode, AllocSize); status = MmCopyVirtualMemory(Process, InstruShellCode, Process, pShellCode, AllocSize, KernelMode, &RETSize); if (!NT_SUCCESS(status)) { Log("failed to write Memory for shellcode!", true, status); return status; } //ShellCode shellcode_t shell_code; memset(&shell_code, 0, sizeof shell_code); memcpy(&shell_code, &g_instcall_shel1code, sizeof shellcode_t); shell_code.manual_data = (UINT64)pManualMapData; shell_code.rip = (UINT64)pShellCode; status = ZwAllocateVirtualMemory(NtCurrentProcess(), inst_callbak_addr, 0, &AllocSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(status)) { Log("failed to alloc Memory for instrcall shellcode!", true, status); return status; } RtlSecureZeroMemory(*inst_callbak_addr, AllocSize); status = MmCopyVirtualMemory(Process, &shell_code, Process, *inst_callbak_addr, sizeof shell_code, KernelMode, &RETSize); if (!NT_SUCCESS(status)) { Log("failed to write Memory for instrcall shellcode!", true, status); return status; } *p_manual_data = pManualMapData; return status; } NTSTATUS inst_callback_inject(HANDLE process_id, UNICODE_STRING* us_dll_path) { NTSTATUS status = STATUS_SUCCESS; PEPROCESS pEhtreadyx = NULL; KAPC_STATE apc_state; PUCHAR pDllMem = 0; PVOID InstCallBack = 0, pManualMapData = 0; status = PsLookupProcessByProcessId(process_id, &pEhtreadyx); if (!NT_SUCCESS(status)) { Log("failed to get process!", true, status); status = STATUS_UNSUCCESSFUL; return status; } KeStackAttachProcess(pEhtreadyx, &apc_state); while (true) { pDllMem = inst_callback_get_dll_memory(us_dll_path); if (!pDllMem) { status = STATUS_UNSUCCESSFUL; break; } status = inst_callback_alloc_memory(pDllMem, &InstCallBack, &pManualMapData); if (!NT_SUCCESS(status))break; //设置instrecallback status = inst_callback_set_callback(InstCallBack); break; } if (pManualMapData && MmIsAddressValid(pManualMapData)) { __try { while (1) { if (((Manual_Mapping_data*)pManualMapData)->bStart)break; } } __except (1) { Log("process exit! 1", true, 0); ObDereferenceObject(pEhtreadyx); KeUnstackDetachProcess(&apc_state); return status; } } inst_callback_set_callback(0); if (pManualMapData && MmIsAddressValid(pManualMapData) && PsLookupProcessByProcessId(process_id, &pEhtreadyx) != STATUS_PENDING) { __try { *(PUCHAR)((((Manual_Mapping_data*)pManualMapData))->pBase) = 0; ((Manual_Mapping_data*)pManualMapData)->bContinue = true; } __except (1) { Log("process exit!", true, 0); } } ObDereferenceObject(pEhtreadyx); KeUnstackDetachProcess(&apc_state); if (pDllMem && MmIsAddressValid(pDllMem))ExFreePool(pDllMem); return status; } void __stdcall InstruShellCode(Manual_Mapping_data* pData) { if (!pData->bFirst)return; pData->bFirst = false; pData->bStart = true; char* pBase = pData->pBase; auto* pOptionHeader = &reinterpret_cast<IMAGE_NT_HEADERS*>(pBase + reinterpret_cast<IMAGE_DOS_HEADER*> ((uintptr_t)pBase)->e_lfanew)->OptionalHeader; char* LocationDelta = pBase - pOptionHeader->ImageBase;//差值 if (LocationDelta) { if (pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) { auto* pRelocData = reinterpret_cast<IMAGE_BASE_RELOCATION*> (pBase + pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); auto* pRelocEnd = reinterpret_cast<IMAGE_BASE_RELOCATION*>(reinterpret_cast<uintptr_t>(pRelocData) + pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); while (pRelocData< pRelocEnd && pRelocData->SizeOfBlock) { UINT64 AmountOfEntries = (pRelocData->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(short); unsigned short* pRelativeInfo = reinterpret_cast<unsigned short*>(pRelocData + 1); for (UINT64 i = 0; i != AmountOfEntries;++pRelativeInfo) { if (RELOC_FLAG(*pRelativeInfo)) { //计算出需要重定位的地址 auto* pPatch = reinterpret_cast<UINT_PTR*>(pBase + pRelocData->VirtualAddress + ((*pRelativeInfo) & 0xFFF)); //手动重定位 *pPatch += reinterpret_cast<UINT_PTR>(LocationDelta); } } pRelocData = reinterpret_cast<IMAGE_BASE_RELOCATION*>(reinterpret_cast<char*>(pRelocData) + pRelocData->SizeOfBlock); } } } if (pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size) { IMAGE_IMPORT_DESCRIPTOR* pImportDescr = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*> (pBase+pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); while (pImportDescr->Name) { HMODULE hDll = pData->pLoadLibraryA(pBase + pImportDescr->Name); //INT IAT //int ULONG_PTR* pInt = (ULONG_PTR*)(pBase + pImportDescr->OriginalFirstThunk); ULONG_PTR* pIat = (ULONG_PTR*)(pBase + pImportDescr->FirstThunk); //IAT if (!pInt)pInt = pIat; for (; *pIat; ++pIat, ++pInt) { if (IMAGE_SNAP_BY_ORDINAL(*pInt)) { *pIat = (ULONG_PTR)pData->pGetProcAddress(hDll, (char*)(*pInt & 0xffff)); } else { IMAGE_IMPORT_BY_NAME* pImport = (IMAGE_IMPORT_BY_NAME*)(pBase + *pInt); *pIat = (ULONG_PTR)pData->pGetProcAddress(hDll, pImport->Name); } } pImportDescr++; } } #define DLL_PROCESS_ATTACH 1 if (pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) { auto* pTLS = reinterpret_cast<IMAGE_TLS_DIRECTORY*> (pBase + pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); auto* pCallBack = reinterpret_cast<PIMAGE_TLS_CALLBACK*>(pTLS->AddressOfCallBacks); for (;pCallBack && *pCallBack; ++pCallBack) { (*pCallBack)(pBase, DLL_PROCESS_ATTACH, nullptr); } } auto excep = pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION]; if (excep.Size) { pData->pRtlAddFunctionTable((_IMAGE_RUNTIME_FUNCTION_ENTRY*) (pBase + excep.VirtualAddress), excep.Size / sizeof(_IMAGE_RUNTIME_FUNCTION_ENTRY),(DWORD64)pBase); } while (!pData->bContinue); //手动调用dllmain ((f_DLL_ENTRY_POINT)(pBase+pOptionHeader->AddressOfEntryPoint))(pBase, DLL_PROCESS_ATTACH, 0); } 注入dll会触发c000005异常
08-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值