|
本帖最后由 乔丹二世 于 2010-12-14 16:07 编辑
从某人的内部博客里看到的~发出来~
#include <stdio.h>
#include <ntddk.h>
#ifdef DEBUG
#define DbgMsg DbgPrint
#else
#define DbgMsg
#endif
typedef struct _IMAGE_DOS_HEADER
{ // DOS .EXE header
USHORT e_magic; // Magic number
USHORT e_cblp; // Bytes on last page of file
USHORT e_cp; // Pages in file
USHORT e_crlc; // Relocations
USHORT e_cparhdr; // Size of header in paragraphs
USHORT e_minalloc; // Minimum extra paragraphs needed
USHORT e_maxalloc; // Maximum extra paragraphs needed
USHORT e_ss; // Initial (relative) SS value
USHORT e_sp; // Initial SP value
USHORT e_csum; // Checksum
USHORT e_ip; // Initial IP value
USHORT e_cs; // Initial (relative) CS value
USHORT e_lfarlc; // File address of relocation table
USHORT e_ovno; // Overlay number
USHORT e_res[4]; // Reserved USHORTs
USHORT e_oemid; // OEM identifier (for e_oeminfo)
USHORT e_oeminfo; // OEM information; e_oemid specific
USHORT e_res2[10]; // Reserved USHORTs
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER,
*PIMAGE_DOS_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY
{
ULONG VirtualAddress;
ULONG Size;
} IMAGE_DATA_DIRECTORY,
*PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER
{
//
// Standard fields.
//
USHORT Magic;
UCHAR MajorLinkerVersion;
UCHAR MinorLinkerVersion;
ULONG SizeOfCode;
ULONG SizeOfInitializedData;
ULONG SizeOfUninitializedData;
ULONG AddressOfEntryPoint;
ULONG BaseOfCode;
ULONG BaseOfData;
//
// NT additional fields.
//
ULONG ImageBase;
ULONG SectionAlignment;
ULONG FileAlignment;
USHORT MajorOperatingSystemVersion;
USHORT MinorOperatingSystemVersion;
USHORT MajorImageVersion;
USHORT MinorImageVersion;
USHORT MajorSubsystemVersion;
USHORT MinorSubsystemVersion;
ULONG Win32VersionValue;
ULONG SizeOfImage;
ULONG SizeOfHeaders;
ULONG CheckSum;
USHORT Subsystem;
USHORT DllCharacteristics;
ULONG SizeOfStackReserve;
ULONG SizeOfStackCommit;
ULONG SizeOfHeapReserve;
ULONG SizeOfHeapCommit;
ULONG LoaderFlags;
ULONG NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32,
*PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_FILE_HEADER
{
USHORT Machine;
USHORT NumberOfSections;
ULONG TimeDateStamp;
ULONG PointerToSymbolTable;
ULONG NumberOfSymbols;
USHORT SizeOfOptionalHeader;
USHORT Characteristics;
} IMAGE_FILE_HEADER,
*PIMAGE_FILE_HEADER;
typedef struct _IMAGE_NT_HEADERS
{
ULONG Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS,
*PIMAGE_NT_HEADERS;
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP
#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
typedef struct _IMAGE_BASE_RELOCATION
{
ULONG VirtualAddress;
ULONG SizeOfBlock;
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
typedef struct _IMAGE_IMPORT_DESCRIPTOR
{
union {
ULONG Characteristics; // 0 for terminating null import descriptor
ULONG OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
};
ULONG TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
ULONG ForwarderChain; // -1 if no forwarders
ULONG Name;
ULONG FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_THUNK_DATA32
{
union {
ULONG ForwarderString; // PBYTE
ULONG Function; // PDWORD
ULONG Ordinal;
ULONG AddressOfData; // PIMAGE_IMPORT_BY_NAME
} u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 *PIMAGE_THUNK_DATA32;
typedef struct _IMAGE_IMPORT_BY_NAME
{
USHORT Hint;
UCHAR Name[1];
} IMAGE_IMPORT_BY_NAME,
*PIMAGE_IMPORT_BY_NAME;
typedef struct _IMAGE_EXPORT_DIRECTORY
{
ULONG Characteristics;
ULONG TimeDateStamp;
USHORT MajorVersion;
USHORT MinorVersion;
ULONG Name;
ULONG Base;
ULONG NumberOfFunctions;
ULONG NumberOfNames;
ULONG AddressOfFunctions; // RVA from base of image
ULONG AddressOfNames; // RVA from base of image
ULONG AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY,
*PIMAGE_EXPORT_DIRECTORY;
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
PVOID
RtlImageDirectoryEntryToData(
IN PVOID Base,
IN BOOLEAN MappedAsImage,
IN USHORT DirectoryEntry,
OUT PULONG Size
);
typedef struct _SYSTEM_MODULE
{
ULONG Reserved[2];
ULONG Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE,
*PSYSTEM_MODULE;
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG uCount;
SYSTEM_MODULE aSM[];
} SYSTEM_MODULE_INFORMATION,
*PSYSTEM_MODULE_INFORMATION;
typedef enum _SYSTEMINFOCLASS
{
SystemBasicInformation, // 0x002C
SystemProcessorInformation, // 0x000C
SystemPerformanceInformation, // 0x0138
SystemTimeInformation, // 0x0020
SystemPathInformation, // not implemented
SystemProcessInformation, // 0x00C8+ per process
SystemCallInformation, // 0x0018 + (n * 0x0004)
SystemConfigurationInformation, // 0x0018
SystemProcessorCounters, // 0x0030 per cpu
SystemGlobalFlag, // 0x0004 (fails if size != 4)
SystemCallTimeInformation, // not implemented
SystemModuleInformation, // 0x0004 + (n * 0x011C)
SystemLockInformation, // 0x0004 + (n * 0x0024)
SystemStackTraceInformation, // not implemented
SystemPagedPoolInformation, // checked build only
SystemNonPagedPoolInformation, // checked build only
SystemHandleInformation, // 0x0004 + (n * 0x0010)
SystemObjectTypeInformation, // 0x0038+ + (n * 0x0030+)
SystemPageFileInformation, // 0x0018+ per page file
SystemVdmInstemulInformation, // 0x0088
SystemVdmBopInformation, // invalid info class
SystemCacheInformation, // 0x0024
SystemPoolTagInformation, // 0x0004 + (n * 0x001C)
SystemInterruptInformation, // 0x0000, or 0x0018 per cpu
SystemDpcInformation, // 0x0014
SystemFullMemoryInformation, // checked build only
SystemLoadDriver, // 0x0018, set mode only
SystemUnloadDriver, // 0x0004, set mode only
SystemTimeAdjustmentInformation, // 0x000C, 0x0008 writeable
SystemSummaryMemoryInformation, // checked build only
SystemNextEventIdInformation, // checked build only
SystemEventIdsInformation, // checked build only
SystemCrashDumpInformation, // 0x0004
SystemExceptionInformation, // 0x0010
SystemCrashDumpStateInformation, // 0x0004
SystemDebuggerInformation, // 0x0002
SystemContextSwitchInformation, // 0x0030
SystemRegistryQuotaInformation, // 0x000C
SystemAddDriver, // 0x0008, set mode only
SystemPrioritySeparationInformation,// 0x0004, set mode only
SystemPlugPlayBusInformation, // not implemented
SystemDockInformation, // not implemented
SystemPowerInfo, // 0x0060 (XP only!)
SystemProcessorSpeedInformation, // 0x000C (XP only!)
SystemTimeZoneInformation, // 0x00AC
SystemLookasideInformation, // n * 0x0020
SystemSetTimeSlipEvent,
SystemCreateSession, // set mode only
SystemDeleteSession, // set mode only
SystemInvalidInfoClass1, // invalid info class
SystemRangeStartInformation, // 0x0004 (fails if size != 4)
SystemVerifierInformation,
SystemAddVerifier,
SystemSessionProcessesInformation, // checked build only
MaxSystemInfoClass
} SYSTEMINFOCLASS,
*PSYSTEMINFOCLASS;
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY LoadOrder;
LIST_ENTRY MemoryOrder;
LIST_ENTRY InitOrder;
PVOID ModuleBaseAddress;
PVOID EntryPoint;
ULONG ModuleSize;
UNICODE_STRING FullModuleName;
UNICODE_STRING ModuleName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY Hash;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
ULONG TimeStamp;
} LDR_DATA_TABLE_ENTRY,
*PLDR_DATA_TABLE_ENTRY;
PVOID KernelGetProcAddress(PVOID ModuleBase, char *pFunctionName)
{
PVOID pFunctionAddress = NULL;
PIMAGE_EXPORT_DIRECTORY exports;
ULONG i, addr, ord, size = 0;
PULONG names, functions;
PSHORT ordinals;
if (ModuleBase == NULL)
return NULL;
__try
{
exports = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(ModuleBase,
TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
addr = (ULONG)exports - (ULONG)ModuleBase;
functions = (PULONG)((ULONG)ModuleBase + exports->AddressOfFunctions);
ordinals = (PSHORT)((ULONG)ModuleBase + exports->AddressOfNameOrdinals);
names = (PULONG)((ULONG)ModuleBase + exports->AddressOfNames);
for (i = 0; i < exports->NumberOfNames; i++)
{
ord = ordinals;
if (i >= exports->NumberOfNames || ord >= exports->NumberOfFunctions)
return NULL;
if (functions[ord] < addr || functions[ord] >= addr + size)
{
if (strcmp((char *)((ULONG)ModuleBase + names), pFunctionName) == 0)
{
pFunctionAddress =(PVOID)((ULONG)ModuleBase + functions[ord]);
break;
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgMsg("KernelGetProcAddress() EXEPTION\n");
pFunctionAddress = NULL;
}
return pFunctionAddress;
}
PVOID GetSysInf(SYSTEMINFOCLASS pdData)
{
NTSTATUS ns;
ULONG dSize = 4096;
ULONG dData = 0;
PVOID shi;
do {
shi = ExAllocatePool(NonPagedPool, dSize);
if (shi == NULL) return 0;
ns = ZwQuerySystemInformation(pdData, shi, dSize, &dData);
if (ns == STATUS_INFO_LENGTH_MISMATCH)
{
ExFreePool(shi);
dSize *= 2;
}
} while (ns != 0);
return shi;
}
PVOID KernelGetModuleBase(char *pModuleName)
{
PVOID pModuleBase = NULL;
ULONG i;
PSYSTEM_MODULE_INFORMATION ModulesInfo = (PSYSTEM_MODULE_INFORMATION)GetSysInf(SystemModuleInformation);
if (ModulesInfo == NULL)
return NULL;
if (!strcmp(pModuleName, "ntoskrnl.exe"))
{
pModuleBase = (PVOID)ModulesInfo->aSM[0].Base;
} else {
for (i = 0; i < ModulesInfo->uCount; i++)
{
if (strstr(ModulesInfo->aSM.ImageName, pModuleName))
pModuleBase = (PVOID)ModulesInfo->aSM.Base;
}
}
ExFreePool(ModulesInfo);
return pModuleBase;
}
#define RVATOVA(base,offset)(((ULONG)(base)+(ULONG)(offset)))
BOOLEAN ProcessImports(ULONG ImageBase)
{
IMAGE_THUNK_DATA32 *pThunk;
PVOID LibAddr;
char *LibName, *FuncName;
PIMAGE_IMPORT_BY_NAME pImageImportByName;
ULONG FuncAddr;
__try
{
PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)
(ImageBase + ((PIMAGE_DOS_HEADER)ImageBase)->e_lfanew);
PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(RVATOVA(ImageBase,
pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
while (pImageImportDescriptor->Name != 0)
{
LibName = (char *)RVATOVA(ImageBase, pImageImportDescriptor->Name);
LibAddr = KernelGetModuleBase(LibName);
if (LibAddr == NULL)
return FALSE;
DbgMsg("0x%.8x:%s\n", LibAddr, LibName);
pThunk = (IMAGE_THUNK_DATA32 *)RVATOVA(ImageBase, pImageImportDescriptor->FirstThunk);
while (pThunk->u1.Ordinal != 0)
{
pImageImportByName = (PIMAGE_IMPORT_BY_NAME)RVATOVA(ImageBase, pThunk->u1.AddressOfData);
FuncName = (char *)(&pImageImportByName->Name);
FuncAddr = (ULONG)KernelGetProcAddress(LibAddr, FuncName);
DbgMsg(" 0x%.8x:%s\n", FuncAddr, FuncName);
if (FuncAddr == 0)
return FALSE;
*(PULONG)pThunk = FuncAddr;
pThunk++;
}
pImageImportDescriptor++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgMsg("ProcessImports() EXEPTION\n");
return FALSE;
}
return TRUE;
}
BOOLEAN ProcessRelocs(ULONG ImageBase)
{
__try
{
PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)
(ImageBase + ((PIMAGE_DOS_HEADER)ImageBase)->e_lfanew);
ULONG RellocsSize = pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
PIMAGE_BASE_RELOCATION pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)(RVATOVA(ImageBase,
pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress));
PIMAGE_BASE_RELOCATION pRelocation = pImageBaseRelocation;
ULONG ImageBaseDelta = ImageBase - pImageNtHeaders->OptionalHeader.ImageBase, Number, i, Size = 0;
PUSHORT Rel;
DbgMsg("pImageBaseRelocation: 0x%.8x; Size: %d\n", pImageBaseRelocation, RellocsSize);
while (RellocsSize > Size)
{
Size += pRelocation->SizeOfBlock;
Number = (pRelocation->SizeOfBlock - 8) / 2;
Rel = (PUSHORT)((ULONG)pRelocation + 8);
DbgMsg("VirtualAddress: 0x%.8x; Number of Relocs: %d; Size: %d\n", pRelocation->VirtualAddress,
Number, pRelocation->SizeOfBlock);
for (i = 0; i < Number - 1; i++)
{
DbgMsg(" %d:0x%.8x\n", i, Rel & 0x0FFF);
*(PULONG)(RVATOVA(ImageBase, pRelocation->VirtualAddress + (Rel & 0x0FFF))) += ImageBaseDelta;
}
pRelocation = (PIMAGE_BASE_RELOCATION)((ULONG)pImageBaseRelocation + Size);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgMsg("ProcessRelocs() EXEPTION\n");
return FALSE;
}
return TRUE;
}
void __stdcall MainFunc(PVOID param)
{
//some fuckable thing
return ;
}
PLDR_DATA_TABLE_ENTRY pModuleEntry;
PVOID AllocAndExec(void)
{
PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)((ULONG)pModuleEntry->ModuleBaseAddress +
((PIMAGE_DOS_HEADER)pModuleEntry->ModuleBaseAddress)->e_lfanew);
ULONG ImageSize = pImageNtHeaders->OptionalHeader.SizeOfImage;
NTSTATUS ns;
OBJECT_ATTRIBUTES ObjAttr;
HANDLE hFile, hThread;
IO_STATUS_BLOCK StatusBlock;
PVOID pFunc;
PVOID pMem = (PVOID)ExAllocatePool(NonPagedPool, ImageSize);
if (pMem == NULL)
{
DbgMsg("ExAllocatePool() ERROR\n");
return NULL;
}
DbgMsg("%S Base: 0x%.8x; ImageSize: %d\n", pModuleEntry->FullModuleName.Buffer, pMem, ImageSize);
InitializeObjectAttributes(&ObjAttr, &pModuleEntry->FullModuleName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE , NULL, NULL);
ns = ZwOpenFile(&hFile, FILE_READ_DATA | SYNCHRONIZE, &ObjAttr, &StatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(ns))
{
DbgMsg("ZwOpenFile() FAILS; status: 0x%.8x\n", ns);
return NULL;
}
ns = ZwReadFile(hFile, 0, NULL, NULL, &StatusBlock, pMem, ImageSize, 0, NULL);
if (!NT_SUCCESS(ns))
{
DbgMsg("ZwReadFile() FAILS; status: 0x%.8x\n", ns);
} else {
if (!ProcessImports((ULONG)pMem) || !ProcessRelocs((ULONG)pMem))
{
ZwClose(hFile);
return NULL;
}
}
ZwClose(hFile);
pFunc = (PVOID)((ULONG)&MainFunc - (ULONG)pModuleEntry->ModuleBaseAddress + (ULONG)pMem);
DbgMsg("EP:0x%.8x\n", pFunc);
if (NT_SUCCESS(PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, pFunc, (PVOID)pModuleEntry)))
ZwClose(hThread);
else
DbgMsg("PsCreateSystemThread() FAILS\n");
return pMem;
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
pModuleEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;
AllocAndExec();
return STATUS_UNSUCCESSFUL;
}
|
|