首页
社区
课程
招聘
[讨论][求助]利用回调修改导入表注入
发表于: 2015-8-15 16:41 7358

[讨论][求助]利用回调修改导入表注入

2015-8-15 16:41
7358
利用PsSetLoadImageNotifyRoutine回调修改exe的导入表,想要加载自己的.dll文件来达到注入的目的,dll文件中的MessageBox执行了,但是之后就说程序初始化失败

PIMAGE_IMPORT_DESCRIPTOR g_OldImportDesc;
KIRQL Irql;
PEPROCESS g_TargetProcess;
HANDLE    g_TargetProcessId;

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath)
{

  DbgPrint("驱动加载\r\n");
  DriverObject->DriverUnload = UnloadDriver;
  PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)LoadImageNotifyRoutine);
  return STATUS_SUCCESS;
}

VOID UnloadDriver(PDRIVER_OBJECT DriverObject)
{
  PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)LoadImageNotifyRoutine);
  DbgPrint("驱动卸载\r\n");
}



VOID LoadImageNotifyRoutine(PUNICODE_STRING FullImageName,HANDLE  ProcessId,PIMAGE_INFO  ImageInfor)
{
  NTSTATUS Status;
  PVOID DriverEntryAddress = NULL;
  char szFullImageName[260]={0};
  PEPROCESS TatgetProcess = NULL;
  KAPC_STATE apcState;
  BOOLEAN     bAttached =FALSE;
  HANDLE    hProcess;
  Status  = PsLookupProcessByProcessId(ProcessId,&TatgetProcess);
  if (!NT_SUCCESS(Status))
  {
    return ;
  }
  if (strstr(PsGetProcessImageFileName(TatgetProcess),"cc.exe")) //当前进程是cc.exe
  {
    UnicodeToChar(FullImageName,szFullImageName);

    if (strstr(szFullImageName,"cc.exe"))  //加载的是cc.exe
    {
      g_TargetProcessId = ProcessId;
      Status = ObOpenObjectByPointer(TatgetProcess, 
        OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, 
        NULL, 
        GENERIC_ALL, 
        *PsProcessType, 
        KernelMode, 
        &hProcess
        );
      if (!NT_SUCCESS(Status))
      {
        ObDereferenceObject(TatgetProcess);
        return; 
      }
      g_TargetProcess = TatgetProcess;
      __try
      {
        //KeStackAttachProcess(TatgetProcess,&apcState);
        if (MmIsAddressValid(ImageInfor->ImageBase))
        {
          PIMAGE_DOS_HEADER pDos;
          PIMAGE_NT_HEADERS pHeader = NULL;
          PIMAGE_IMPORT_DESCRIPTOR  pImportDesc;
          //ZwUnmapViewOfSection(hProcess,ImageInfor->ImageBase);
          ULONG nImportDllCount;
          PVOID ulImageBase = ImageInfor->ImageBase;
          ULONG nNewImportSize;
          ULONG nNewDllNameSize = 0x20;
          PIMAGE_IMPORT_DESCRIPTOR lpNewImportDesc = NULL;
          PVOID lpDllName = NULL;
          IMAGE_IMPORT_DESCRIPTOR Add_ImportDesc;
          PIMAGE_THUNK_DATA    lpNewThunkData = NULL;
          ULONG nNewThunkDataSize = 0x20;
          PIMAGE_IMPORT_BY_NAME lpImportApi = NULL;
          ULONG nNewImportApiSize  = 0x20;
          pDos =(PIMAGE_DOS_HEADER) ulImageBase;

          pHeader = (PIMAGE_NT_HEADERS)((ULONG)ulImageBase+(ULONG)pDos->e_lfanew);
          pImportDesc  = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress \
            + (ULONG)ulImageBase);
          //导入表项个数
          nImportDllCount = pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);

          g_OldImportDesc = pImportDesc;//原始的导入表

          nNewImportSize = sizeof(IMAGE_IMPORT_DESCRIPTOR)*(nImportDllCount+1);//加上自己的

          Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &lpNewImportDesc, 0, &nNewImportSize,
            MEM_COMMIT, PAGE_EXECUTE_READWRITE);
          if (!NT_SUCCESS(Status))
          {
            ObDereferenceObject(TatgetProcess);
            ObDereferenceObject(TatgetProcess);
            return;
          }
          RtlZeroMemory(lpNewImportDesc,nNewImportSize);

          Status = ZwAllocateVirtualMemory(hProcess, &lpDllName, 0, &nNewDllNameSize,
            MEM_COMMIT, PAGE_EXECUTE_READWRITE);
          if (!NT_SUCCESS(Status))
          {
            ZwFreeVirtualMemory(hProcess,&lpNewImportDesc,0,MEM_RELEASE);
            ObDereferenceObject(TatgetProcess);
            ObDereferenceObject(TatgetProcess);
            return;
          }

          RtlZeroMemory(lpDllName,nNewDllNameSize);

          //ThunkData
          Status = ZwAllocateVirtualMemory(hProcess, &lpNewThunkData, 0, &nNewThunkDataSize,
            MEM_COMMIT, PAGE_EXECUTE_READWRITE);
          if (!NT_SUCCESS(Status))
          {
            ZwFreeVirtualMemory(hProcess,&lpNewImportDesc,0,MEM_RELEASE);
            ZwFreeVirtualMemory(hProcess,&lpDllName,0,MEM_RELEASE);
            ObDereferenceObject(TatgetProcess);
            ObDereferenceObject(TatgetProcess);
            return;
          }
          RtlZeroMemory(lpNewThunkData,nNewThunkDataSize);          
          //IMAGE_IMPORT_BY_NAME
          Status = ZwAllocateVirtualMemory(hProcess, &lpImportApi, 0, &nNewImportApiSize,
            MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
          if (!NT_SUCCESS(Status))
          {
            ZwFreeVirtualMemory(hProcess,&lpNewImportDesc,0,MEM_RELEASE);
            ZwFreeVirtualMemory(hProcess,&lpDllName,0,MEM_RELEASE);
            ZwFreeVirtualMemory(hProcess,&lpNewThunkData,0,MEM_RELEASE);
            ObDereferenceObject(TatgetProcess);
            ObDereferenceObject(TatgetProcess);
            return;
          }
          RtlZeroMemory(lpImportApi,nNewImportApiSize);
          //原始的导入表,留出一个表项
          RtlCopyMemory(lpNewImportDesc+1,pImportDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR)*nImportDllCount);
          lpImportApi->Hint = 0;
          RtlCopyMemory(lpImportApi->Name,"DllMain",0x20);
          lpNewThunkData->u1.AddressOfData = (ULONG)lpImportApi-(ULONG)ulImageBase;
        
          Add_ImportDesc.OriginalFirstThunk = (ULONG)lpNewThunkData-(ULONG)ulImageBase;
          Add_ImportDesc.TimeDateStamp = 0;
          Add_ImportDesc.ForwarderChain = 0;
          RtlCopyMemory(lpDllName,"test.dll",0x20);
          Add_ImportDesc.Name = (ULONG)lpDllName-(ULONG)ulImageBase;
          Add_ImportDesc.FirstThunk = Add_ImportDesc.OriginalFirstThunk;          
          RtlCopyMemory(lpNewImportDesc,&Add_ImportDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR));
          WPOFF(); //修改Descriptor
          pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size += sizeof(IMAGE_IMPORT_DESCRIPTOR);
          pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = (ULONG_PTR)lpNewImportDesc - (ULONG_PTR)ulImageBase;
          WPON();

        }
        //KeUnstackDetachProcess(&apcState);
      }__except(EXCEPTION_EXECUTE_HANDLER){
      }
      ObDereferenceObject(TatgetProcess);
    }
  }

  ObDereferenceObject(TatgetProcess);
}




VOID WPOFF()
{
  ULONG_PTR cr0 = 0;
  Irql = KeRaiseIrqlToDpcLevel();
  cr0 =__readcr0();
  cr0 &= 0xfffffffffffeffff;
  __writecr0(cr0);

}



VOID WPON()
{

  ULONG_PTR cr0=__readcr0();
  cr0 |= 0x10000;
  __writecr0(cr0);
  KeLowerIrql(Irql);
}


VOID UnicodeToChar(PUNICODE_STRING uniSource, CHAR *szDest)
{                                                  
  ANSI_STRING ansiTemp;                                
  RtlUnicodeStringToAnsiString(&ansiTemp,uniSource,TRUE);   

  strcpy(szDest,ansiTemp.Buffer);
  RtlFreeAnsiString(&ansiTemp);
}

顺便推销一下自己的博客 个人博客

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 65
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
切换CR0(包括使用MDL)来修改导入表,会导致Copy-On-Write机制失效,因此,最好的方式是使用未导出的ZwProtectVirtualMemory,修改导入表对应的DataDirectory,即可稳定加载。
2015-8-21 14:02
0
雪    币: 938
活跃值: (1178)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我该怎么说呢,系统calc.exe自身有对导入表检测的代码,你可以windbg ba r4 address(新的导入表地址) 下个断点看看,xp,win7都有检测的.
2016-1-11 14:03
0
雪    币: 112
活跃值: (501)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我也是遇到这个问题,不知道怎么解决
2016-7-16 08:15
0
雪    币: 938
活跃值: (1178)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
把 预加载那个表清零。
2016-7-25 20:50
0
游客
登录 | 注册 方可回帖
返回