担心此帖又是无人问津,浪费宝贵kx,剩余90分以追加形式给出,说话算话
借鉴http://bbs.pediy.com/showthread.php?t=60778的思路,自己重写了个,
xxx.exe映象文件IAT中的GetProcAddress已经被我修改成 7ffe05f0,
7ffe05f0:jmp _kernel32!GetProcAddress
运行起来有问题,dll.exe全部加载失败,火候不够,暂时查不出问题所在,帮忙看看
#include "iathook.h"
NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegisterPath)
{
int i;
NTSTATUS status = STATUS_SUCCESS;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++)
{
DriverObject->MajorFunction[i] = DispatchRoutine;
}
DriverObject->DriverUnload = UnloadRoutine;
_asm int 3
PsSetLoadImageNotifyRoutine ((PLOAD_IMAGE_NOTIFY_ROUTINE) LoadImageNotifyRoutine);
return status;
}
void LoadImageNotifyRoutine (
IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId,
IN PIMAGE_INFO ImageInfo
)
{
UNICODE_STRING TargetImage;
ANSI_STRING TargetFunction;
RtlInitAnsiString (&TargetFunction, "GetProcAddress");
RtlInitUnicodeString (&TargetImage, L"\\Windows\\system32\\user32.dll");
if (!RtlCompareUnicodeString (&TargetImage, FullImageName, TRUE))
{
HookIAT (ProcessId, &TargetFunction);
}
return;
}
void HookIAT (HANDLE ProcessId, PVOID HookFunction)
{
PEPROCESS pEprocess;
ULONG pPeb,Ldr,pdte;
KAPC_STATE ApcState;
PVOID hModule = NULL;
PLIST_ENTRY list;
PsLookupProcessByProcessId (ProcessId, &pEprocess);
pPeb =*(PULONG)((ULONG)pEprocess + 0x1b0);//_EPROCESS.Peb
if (pPeb != NULL)
{
KeStackAttachProcess (pEprocess, &ApcState);
//此部分各个版本有差异,此处适用于xp sp3
Ldr = *(PULONG)(pPeb + 0xc);//_PEB.Ldr
list = (PLIST_ENTRY)(Ldr +0xc);//_PEB_LDR_DATA.InLoadOrderModuleList
pdte = list->Flink;
do
{
if (wcsstr((*(PUNICODE_STRING)(pdte+0x2c)).Buffer,L".exe") != NULL ||
wcsstr((*(PUNICODE_STRING)(pdte+0x2c)).Buffer,L".EXE") != NULL )
{
hModule = *(PULONG)(pdte+0x18);
HookImageImportTable (hModule, HookFunction);
break;
}
pdte = *(PULONG)pdte;//_LDR_DATA_TABLE_ENTRY.InLoadOrderLinks
}while (pdte != list->Flink);
KeUnstackDetachProcess (&ApcState);
}
return;
}
void HookImageImportTable (PVOID hModule, PVOID HookFunction)
{
ULONG Base,NameAddr, Flag;
PULONG MapIATAddress;
PIMAGE_DOS_HEADER DosHead = NULL;
PIMAGE_NT_HEADERS NtHeads = NULL;
PIMAGE_IMPORT_DESCRIPTOR ImportDes = NULL;
PULONG ThunkDataO, ThunkDataF;
PUCHAR NameIF;
PMDL pMdl;
ANSI_STRING DllName,TempName;
RtlInitAnsiString (&DllName, "kernel32.dll");
Base = (ULONG)hModule;
DosHead = (PIMAGE_DOS_HEADER)Base;
NtHeads = (PIMAGE_NT_HEADERS)((PUCHAR)DosHead + DosHead->e_lfanew);
ImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((PUCHAR)Base + NtHeads->OptionalHeader.DataDirectory[1].VirtualAddress);
Flag = 0;
while (ImportDes->Name != 0 && ImportDes->FirstThunk != 0)
{
RtlInitAnsiString (&TempName, ImportDes->Name + Base);
if (!RtlCompareString (&TempName, &DllName, TRUE))
{
ThunkDataO = ImportDes->OriginalFirstThunk + Base;
ThunkDataF = ImportDes->FirstThunk + Base;
while (*ThunkDataO != 0)
{
if (!(*ThunkDataO & 0x80000000))
{
NameIF = ((PIMAGE_IMPORT_BY_NAME)(*ThunkDataO + Base))->Name;
RtlInitAnsiString (&TempName, NameIF);
if (!RtlCompareString (&TempName, HookFunction, TRUE))
{
Flag = 1;
goto breakop;
}
}
ThunkDataO ++;
ThunkDataF ++;
}
}
ImportDes ++;
}
breakop:
if (Flag == 0) return;
OldIATAddress = *ThunkDataF;
if (flags == 0)
{
MyGetProcAddressBorn ();
}
pMdl = MmCreateMdl (NULL, ThunkDataF, 4);
if (!pMdl) return;
MmBuildMdlForNonPagedPool (pMdl);
pMdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
MapIATAddress = MmMapLockedPagesSpecifyCache (pMdl, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority);
if (MapIATAddress != NULL)
{
*MapIATAddress = MM_SHARED_USER_DATA_VA + sizeof (KUSER_SHARED_DATA);
}
MmUnmapLockedPages (MapIATAddress, pMdl);
IoFreeMdl (pMdl);
return;
}
void MyGetProcAddressBorn ()
{
PUCHAR Temp;
flags = 1;
Temp = USER_SHARED_DATA + sizeof (KUSER_SHARED_DATA);
*Temp++ = 0xe9;
*(PULONG)Temp = OldIATAddress - (MM_SHARED_USER_DATA_VA + sizeof (KUSER_SHARED_DATA) + 5);
return;
}
[课程]Linux pwn 探索篇!