2008年8月27日星期三

shimeng注入

#include "ntifs.h"

typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;

#define SEC_IMAGE 0x01000000
#define SHIM_DEBUG 1

__declspec(dllimport) DWORD PsLookupProcessByProcessId(HANDLE ProcessId,PEPROCESS* pProcess);
__declspec(dllimport) DWORD ZwOpenProcess(PHANDLE ProcessHandle,ULONG DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID Cid);
__declspec(dllimport) DWORD ZwQueryInformationProcess(HANDLE ProcessHandle,PROCESSINFOCLASS ProcessInformationClass,PVOID ProcessInformation,ULONG ProcessInformationLength,PULONG ReturnLength);
__declspec(dllimport) BYTE *PsGetProcessPeb(PEPROCESS Process);


#ifdef _WIN64
#define SHIM_OFFSET 0x2d8
#else*/
#define SHIM_OFFSET 0x1e8
#endif

UNICODE_STRING shimRegRoot;

WCHAR shimName[]=L"shimeng.dll";
WCHAR shimSection[]=L"\\knowndlls\\shimeng.dll";
UNICODE_STRING shimDllRegKey;
HANDLE hShimSection;


#ifdef _WIN64
WCHAR shimSection32[]=L"\\knowndlls32\\shimeng.dll";
UNICODE_STRING shimDll32RegKey;
HANDLE hShimSection32;
#endif

void processNotify(HANDLE parentId,HANDLE processId,BOOLEAN createFlag){
PVOID memAddress=0;
SIZE_T memSize=sizeof(shimName);
HANDLE hProcess;
BYTE *pPeb;
OBJECT_ATTRIBUTES objAttr;
CLIENT_ID idClient;
PEPROCESS pEProcess;
DWORD ntStatus;
KAPC_STATE kaps;

if(createFlag){
RtlZeroMemory(&objAttr,sizeof(OBJECT_ATTRIBUTES));
idClient.UniqueProcess=processId;
idClient.UniqueThread=0;
if(ZwOpenProcess(&hProcess,PROCESS_DUP_HANDLE,&objAttr,&idClient)!=0){
return;
}
if(PsLookupProcessByProcessId(processId,&pEProcess)!=0){
return;
}
pPeb=PsGetProcessPeb(pEProcess);
if(pPeb==0){
return;
}
ntStatus=ZwAllocateVirtualMemory(hProcess,&memAddress,0,&memSize,MEM_COMMIT,PAGE_READWRITE);
if(ntStatus!=0){
#ifdef SHIM_DEBUG
DbgPrint("ZwAllocateVirtualMemory fails");
#endif
return;
}
KeStackAttachProcess(pEProcess,&kaps);
__try
{
memcpy(memAddress,shimName,sizeof(shimName));
*(WCHAR**)(pPeb+SHIM_OFFSET)=memAddress;
}__except(EXCEPTION_EXECUTE_HANDLER)
{
#ifdef SHIM_DEBUG
DbgPrint("Write lMemory fails");
#endif
}
KeUnstackDetachProcess(&kaps);
}
return;
}

void driverUnload(PDRIVER_OBJECT DriverObject){
PsSetCreateProcessNotifyRoutine(processNotify,TRUE);
ZwClose(hShimSection);

#ifdef _WIN64
ZwClose(hShimSection32);
#endif
#ifdef SHIM_DEBUG
DbgPrint("shim injector: unloaded");
#endif
return;
}

NTSTATUS mapShim(HANDLE *pSection,PUNICODE_STRING dllName,WCHAR *sectionName)
{
HANDLE hFile;
OBJECT_ATTRIBUTES objAttr;
IO_STATUS_BLOCK ioStatusBlock;
UNICODE_STRING usFileName;
DWORD ntStatus;
HANDLE hRegKey;
PKEY_VALUE_PARTIAL_INFORMATION regKeyInfo=0;
DWORD regKeySize=sizeof(KEY_VALUE_PARTIAL_INFORMATION)+0x200;
ULONG retSize=0;
WCHAR wdllImage[128]={L"\0"};

InitializeObjectAttributes(&objAttr,&shimRegRoot,0,0,0);
ntStatus=ZwOpenKey(&hRegKey,KEY_QUERY_VALUE,&objAttr);
if(ntStatus!=STATUS_SUCCESS){
#ifdef SHIM_DEBUG
DbgPrint("ZwOpenKey fails");
#endif
return ntStatus;
}
regKeyInfo=(KEY_VALUE_PARTIAL_INFORMATION*)ExAllocatePoolWithTag(PagedPool,regKeySize,'SHIE');
if(regKeyInfo==0){
#ifdef SHIM_DEBUG
DbgPrint("Allocate memory fails");
#endif
ZwClose(hRegKey);
return ntStatus;
}


ntStatus=ZwQueryValueKey(hRegKey,dllName,KeyValuePartialInformation,(PVOID)regKeyInfo,regKeySize,&retSize);
ZwClose(hRegKey);
if(ntStatus!=STATUS_SUCCESS){
#ifdef SHIM_DEBUG
DbgPrint("ZwQueryValueKey fails");
#endif
ExFreePool(regKeyInfo);
return ntStatus;
}
#ifdef SHIM_DEBUG
DbgPrint("shim injector: shim %ls added",regKeyInfo->Data);
#endif
/*
ntStatus = RtlMultiByteToUnicodeN(wdllImage,128,0,regKeyInfo->Data,strlen(regKeyInfo->Data));
if(ntStatus != STATUS_SUCCESS)
{
#ifdef SHIM_DEBUG
DbgPrint("RtlMultiByteToUnicodeN fails");;
#endif
ExFreePool(regKeyInfo);
return ntStatus;
}*/

DbgPrint("\n%ws\n",regKeyInfo->Data);
if(wcsncmp((PCWSTR)regKeyInfo->Data,L"\\??\\",wcslen(L"\\??\\"))!= 0)
{
wcscat(wdllImage,L"\\??\\");
wcscat(wdllImage,(PCWSTR)regKeyInfo->Data);
}
else
{
wcscat(wdllImage,(PCWSTR)regKeyInfo->Data);
}
DbgPrint("\n%ws\n",wdllImage);
RtlInitUnicodeString(&usFileName,wdllImage);
InitializeObjectAttributes(&objAttr,&usFileName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
ntStatus=ZwOpenFile(&hFile,FILE_GENERIC_EXECUTE,&objAttr,&ioStatusBlock,FILE_SHARE_READ,FILE_SYNCHRONOUS_IO_NONALERT);
if(ntStatus!=STATUS_SUCCESS){
#ifdef SHIM_DEBUG
DbgPrint("Opel file fails");
#endif
ExFreePool(regKeyInfo);
return ntStatus;
}
RtlInitUnicodeString(&usFileName,sectionName);
ntStatus=ZwCreateSection(pSection,SECTION_ALL_ACCESS,&objAttr,0,PAGE_EXECUTE,SEC_IMAGE,hFile);
ZwClose(hFile);
ExFreePool(regKeyInfo);
return ntStatus;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DWORD ntStatus;
#ifdef SHIM_DEBUG
DbgPrint("shim injector: loaded");
#endif
RtlInitUnicodeString(&shimRegRoot,L"\\REGISTRY\\MACHINE\\SOFTWARE\\shim");
RtlInitUnicodeString(&shimDllRegKey,L"shimdll");


#ifdef _WIN64
RtlInitUnicodeString(&shimDll32RegKey,L"shimdll32");
#endif

ntStatus=mapShim(&hShimSection,&shimDllRegKey,shimSection);


#ifdef _WIN64
if(ntStatus==STATUS_SUCCESS)
{
ntStatus=mapShim(&hShimSection32,&shimDll32RegKey,shimSection32);
}
#endif

if(ntStatus==STATUS_SUCCESS)
{
ntStatus=PsSetCreateProcessNotifyRoutine(processNotify,FALSE);
}

if(ntStatus!=STATUS_SUCCESS)
{
ZwClose(hShimSection);

#ifdef _WIN64
ZwClose(hShimSection32);
#endif
#ifdef SHIM_DEBUG
DbgPrint("shim injector: unloaded (0x%x)",ntStatus);
#endif
}
DriverObject->DriverUnload=driverUnload;
return ntStatus;
}
在HKEY_LOCAL_MACHINE\software建立Shim项,在shim项下建立一为shimdll的字符串值,其值存为要注入的dll的全路径
测试了下,对于dll有特殊的要求,自己随便写的dll在进程创建时会发送0xc0000005的错误而利用系统的shimeng.dll会注入成功,写一个马甲dll也不成功,不知道什么原因??

没有评论: