昨天寫(xiě)的那個(gè)
hook?ssdt的驅(qū)動(dòng),用的是硬編碼的辦法,這樣在不同的系統(tǒng)中由于NtShutdownSystem的服務(wù)號(hào)都不相同,所以在不同的操作系統(tǒng)上代碼都要做修改,這個(gè)比較不爽.今天聽(tīng)老大PJF說(shuō)有避免硬編碼的方法,google了下,發(fā)現(xiàn)下面的文章,代碼稍微改了改,用在我的驅(qū)動(dòng)中,果然好使.文章貼在下面:
-------------------------------------------------------------------------------------------
from?http://www.rootkit.com
Hardcoding?the?positions?seems?a?poor?solution,?since?it?means?after?a?new?service?pack,?the?rootkit?may?no?longer?work?and?become?discovered.
As?I?have?found?the?code?on?this?site?extremely?helpful,?I?think?it?is?only?fair?that?I?return?the?favour?;-)
I?have?implemented?the?method?described?in?previous?posts,?whereby?I?have?mapped?a?view?of?ntdll.dll?into?the?process?space?of?whoever?loads?the?driver?initially,?and?then?retrieve?the?required?function?positions?directly?from?the?dll.
This?was?relatively?simple?to?do,?and?only?requires?knowledge?of?the?pe?file?format,?and?a?few?undocumented?apis.
Using?the?function?pasted?below,?when?hooking?you?simply?do?as?follows:
RtlInitUnicodeString(&dllName,?L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntdll.dll");
functionAddress?=?GetDllFunctionAddress(functionName,?&dllName);
position?=?*((WORD*)(functionAddress+1));
????
g_OriginalZwCreateProcessEx?=?(ZWCREATEPROCESSEX)(KeServiceDescriptorTable.ServiceTableBase[position]);
and?here's?the?function?GetDllFunctionAddress:
DWORD?GetDllFunctionAddress(char*?lpFunctionName,?PUNICODE_STRING?pDllName)?
{
????HANDLE?hThread,?hSection,?hFile,?hMod;
????SECTION_IMAGE_INFORMATION?sii;
????IMAGE_DOS_HEADER*?dosheader;
????IMAGE_OPTIONAL_HEADER*?opthdr;
????IMAGE_EXPORT_DIRECTORY*?pExportTable;
????DWORD*?arrayOfFunctionAddresses;
????DWORD*?arrayOfFunctionNames;
????WORD*?arrayOfFunctionOrdinals;
????DWORD?functionOrdinal;
????DWORD?Base,?x,?functionAddress;
????char*?functionName;
????STRING?ntFunctionName,?ntFunctionNameSearch;
????PVOID?BaseAddress?=?NULL;
????SIZE_T?size=0;
????OBJECT_ATTRIBUTES?oa?=?{sizeof?oa,?0,?pDllName,?OBJ_CASE_INSENSITIVE};
????IO_STATUS_BLOCK?iosb;
????//_asm?int?3;
????ZwOpenFile(&hFile,?FILE_EXECUTE?|?SYNCHRONIZE,?&oa,?&iosb,?FILE_SHARE_READ,?FILE_SYNCHRONOUS_IO_NONALERT);
????oa.ObjectName?=?0;
????ZwCreateSection(&hSection,?SECTION_ALL_ACCESS,?&oa,?0,PAGE_EXECUTE,?SEC_IMAGE,?hFile);
????
????ZwMapViewOfSection(hSection,?NtCurrentProcess(),?&BaseAddress,?0,?1000,?0,?&size,?(SECTION_INHERIT)1,?MEM_TOP_DOWN,?PAGE_READWRITE);?
????
????ZwClose(hFile);
????
????hMod?=?BaseAddress;
????
????dosheader?=?(IMAGE_DOS_HEADER?*)hMod;
????
????opthdr?=(IMAGE_OPTIONAL_HEADER?*)?((BYTE*)hMod+dosheader->e_lfanew+24);
????pExportTable?=(IMAGE_EXPORT_DIRECTORY*)((BYTE*)?hMod?+?opthdr->DataDirectory[?IMAGE_DIRECTORY_ENTRY_EXPORT].?VirtualAddress);
????//?now?we?can?get?the?exported?functions,?but?note?we?convert?from?RVA?to?address
????arrayOfFunctionAddresses?=?(DWORD*)(?(BYTE*)hMod?+?pExportTable->AddressOfFunctions);
????arrayOfFunctionNames?=?(DWORD*)(?(BYTE*)hMod?+?pExportTable->AddressOfNames);
????arrayOfFunctionOrdinals?=?(WORD*)(?(BYTE*)hMod?+?pExportTable->AddressOfNameOrdinals);
????Base?=?pExportTable->Base;
????RtlInitString(&ntFunctionNameSearch,?lpFunctionName);
????for(x?=?0;?x?<?pExportTable->NumberOfFunctions;?x++)
????{
????????functionName?=?(char*)(?(BYTE*)hMod?+?arrayOfFunctionNames[x]);
????????RtlInitString(&ntFunctionName,?functionName);
????????functionOrdinal?=?arrayOfFunctionOrdinals[x]?+?Base?-?1;?//?always?need?to?add?base,?-1?as?array?counts?from?0
????????//?this?is?the?funny?bit.??you?would?expect?the?function?pointer?to?simply?be?arrayOfFunctionAddresses[x]...
????????//?oh?no...?thats?too?simple.??it?is?actually?arrayOfFunctionAddresses[functionOrdinal]!!
????????functionAddress?=?(DWORD)(?(BYTE*)hMod?+?arrayOfFunctionAddresses[functionOrdinal]);
????????if?(RtlCompareString(&ntFunctionName,?&ntFunctionNameSearch,?TRUE)?==?0)?
????????{
????????????ZwClose(hSection);
????????????return?functionAddress;
????????}
????}
????ZwClose(hSection);
????return?0;
}