看流星社区

 找回密码
 注册账号
查看: 7797|回复: 2

一个PsSetLoadImageNotifyRoutine回调内核注入DLL,支持xp ~ win7源码

[复制链接]

该用户从未签到

发表于 2011-9-14 13:50:51 | 显示全部楼层 |阅读模式
一个PsSetLoadImageNotifyRoutine回调内核注入DLL,支持xp ~ win7源码

最近看sudimi大牛写的《一个有趣的内核注DLL的sys》文章,确实很有趣,可惜没开源,俺也写个,把完整代码也贴上来了,欢迎拍砖。


安装驱动,打开dbgview.exe,注入mydll.dll!!
  1. [hide]
  2. VOID Start (
  3.       IN PUNICODE_STRING  FullImageName,
  4.       IN HANDLE  ProcessId, // where image is mapped
  5.       IN PIMAGE_INFO  ImageInfo
  6.       )
  7. {

  8.   NTSTATUS ntStatus;
  9.   PIMAGE_IMPORT_DESCRIPTOR pImportNew;

  10.   HANDLE hProcessHandle;
  11.   int nImportDllCount = 0;

  12.   int size;


  13.   // PID改变时,可以说明已经注入DLL了。
  14.   if(g_ulPid != (ULONG)ProcessId && g_ulPid != 0 && g_psaveDes != NULL)
  15.   {
  16.     KAPC_STATE apcState;
  17.     BOOLEAN bAttached = FALSE;

  18.     //_asm int 3;

  19.     if(g_psaveDes!= NULL)
  20.     {
  21.       if(PsGetCurrentProcess() != g_eprocess) {
  22.         KeStackAttachProcess((PRKPROCESS)g_eprocess, &apcState);
  23.         bAttached = TRUE;
  24.       }

  25.       //
  26.       __asm {
  27.         cli;
  28.         mov eax, cr0;
  29.         mov oldCr0, eax;
  30.         and eax, not 10000h;
  31.         mov cr0, eax
  32.       }

  33.       // 改导出表
  34.       pHeader->OptionalHeader.DataDirectory[1].Size -= sizeof(IMAGE_IMPORT_DESCRIPTOR);
  35.       pHeader->OptionalHeader.DataDirectory[1].VirtualAddress = (ULONG)g_psaveDes - ulBaseImage;

  36.       __asm {
  37.         mov eax, oldCr0;
  38.         mov cr0, eax;
  39.         sti;
  40.       }
  41.       g_psaveDes = NULL;

  42.       if(bAttached)
  43.         KeUnstackDetachProcess(&apcState);


  44.     }
  45.   
  46.     return ;
  47.   }
  48.   // 注入进程没退出。
  49.   if(g_eprocess != NULL)
  50.     return;

  51.    if(_stricmp(PsGetProcessImageFileName(PsGetCurrentProcess()), "dbgview.exe") == 0)
  52.   {
  53.     //_asm int 3;
  54.     g_eprocess = PsGetCurrentProcess();

  55.     g_ulPid = (ULONG )ProcessId;

  56.      ulBaseImage = (ULONG)ImageInfo->ImageBase;// 进程基地址

  57.     pDos =(PIMAGE_DOS_HEADER) ulBaseImage;
  58.     pHeader = (PIMAGE_NT_HEADERS)(ulBaseImage+(ULONG)pDos->e_lfanew);
  59.     pImportDesc  = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)pHeader->OptionalHeader.DataDirectory[1].VirtualAddress + ulBaseImage);



  60.     // 导入DLL个数   
  61.     nImportDllCount = pHeader->OptionalHeader.DataDirectory[1].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);

  62.     // 把原始值保存。
  63.     g_psaveDes = pImportDesc;


  64.     ntStatus = ObOpenObjectByPointer(g_eprocess, OBJ_KERNEL_HANDLE, NULL, 0x008, //PROCESS_VM_OPERATION
  65.       NULL, KernelMode, &hProcessHandle);

  66.     if(!NT_SUCCESS(ntStatus))  
  67.       return ;
  68.     //                          加上一个自己的结构。
  69.     size = sizeof(IMAGE_IMPORT_DESCRIPTOR) * (nImportDllCount + 1);

  70.     //  分配导入表
  71.     ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpBuffer, 0, &size,
  72.       MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  73.     if(!NT_SUCCESS(ntStatus)) {
  74.       ZwClose(hProcessHandle);
  75.       return ;
  76.     }
  77.     RtlZeroMemory(lpBuffer,sizeof(IMAGE_IMPORT_DESCRIPTOR) * (nImportDllCount + 1));

  78.     size = 20;
  79.     // 分配当前进程空间。
  80.     ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpDllName, 0, &size,
  81.       MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  82.     if(!NT_SUCCESS(ntStatus)) {

  83.       ZwClose(hProcessHandle);
  84.       return ;
  85.     }
  86.     RtlZeroMemory(lpDllName,20);


  87.     /* 分配导出函数的进程地址空间。
  88.       注意这里是分配高位地址的。如分配低位地址,得到PIMAGE_IMPORT_BY_NAME结构的地址会以,如ff等开头的负数地址,
  89.       这样,系统就会默认按序号查找API地址,会弹出找不到序号的框框。

  90.     */
  91.     size = 20;
  92.     ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpExportApi, 0, &size,
  93.       MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
  94.     if(!NT_SUCCESS(ntStatus)) {

  95.       ZwClose(hProcessHandle);
  96.       return ;
  97.     }
  98.     RtlZeroMemory(lpExportApi,20);

  99.     // 分配当前进程空间。
  100.     size = 20;
  101.     ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpTemp, 0, &size,
  102.       MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  103.     if(!NT_SUCCESS(ntStatus)) {

  104.       ZwClose(hProcessHandle);
  105.       return ;
  106.     }
  107.     RtlZeroMemory(lpTemp,20);

  108.     // 分配当前进程空间。
  109.     size = 20;
  110.     ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpTemp2, 0, &size,
  111.       MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  112.     if(!NT_SUCCESS(ntStatus)) {

  113.       ZwClose(hProcessHandle);
  114.       return ;
  115.     }
  116.     RtlZeroMemory(lpTemp2,20);


  117.     pImportNew = lpBuffer;

  118.     // 把原来数据保存好。
  119.     RtlCopyMemory(pImportNew+1, pImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR) * nImportDllCount );


  120.     // 构造自己的DLL    IMAGE_IMPORT_DESCRIPTOR结构
  121.     {
  122.       IMAGE_IMPORT_DESCRIPTOR Add_ImportDesc;
  123.       PULONG ulAddress;
  124.       ULONG oldCr0;
  125.       ULONG Func;
  126.       PIMAGE_IMPORT_BY_NAME ptmp;
  127.       IMAGE_THUNK_DATA  *pThunkData=(PIMAGE_THUNK_DATA)lpTemp2;


  128.       //_asm int 3;
  129.       //
  130.       // ThunkData结构的地址
  131.       //
  132.       ptmp  =  (PIMAGE_IMPORT_BY_NAME)lpExportApi;
  133.       ptmp->Hint=0;
  134.       // 至少要一个导出API
  135.       RtlCopyMemory(ptmp->Name,"ExportedFunction",18);

  136.       *(PULONG)lpTemp =(DWORD)ptmp-ulBaseImage;
  137.       pThunkData->u1.AddressOfData  =(DWORD)ptmp-ulBaseImage;
  138.       //pThunkData[1].u1.AddressOfData  =  0;//导出函数截断
  139.       Add_ImportDesc.Characteristics = (DWORD)pThunkData-ulBaseImage;

  140.       Add_ImportDesc.TimeDateStamp = 0;
  141.       Add_ImportDesc.ForwarderChain = 0;

  142.       //
  143.       // DLL名字的RVA
  144.       //   
  145.       RtlCopyMemory(lpDllName,"mydll.dll",20);
  146.       Add_ImportDesc.Name = (DWORD)lpDllName-ulBaseImage;
  147.       Add_ImportDesc.FirstThunk = Add_ImportDesc.Characteristics;


  148.       RtlCopyMemory(pImportNew, &Add_ImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR));



  149.       __asm {
  150.         cli;
  151.         mov eax, cr0;
  152.         mov oldCr0, eax;
  153.         and eax, not 10000h;
  154.         mov cr0, eax
  155.       }

  156.       // 改导出表
  157.       pHeader->OptionalHeader.DataDirectory[1].Size += sizeof(IMAGE_IMPORT_DESCRIPTOR);
  158.       pHeader->OptionalHeader.DataDirectory[1].VirtualAddress = (ULONG)pImportNew - ulBaseImage;


  159.       __asm {
  160.         mov eax, oldCr0;
  161.         mov cr0, eax;
  162.         sti;
  163.       }

  164.     }
  165.     ZwClose(hProcessHandle);
  166.     hProcessHandle = NULL;
  167.   }
  168. } [/hide]
复制代码

该用户从未签到

发表于 2019-3-28 14:38:30 | 显示全部楼层
支持楼主,支持看流星社区,以后我会经常来!

该用户从未签到

发表于 2019-3-28 16:02:14 | 显示全部楼层
支持楼主,支持看流星社区,以后我会经常来!
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-20 10:37

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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