Groups | Search result 4 for zwcreateprocess zwcreatethread |
Сравнительно недавно я тут спрашивал, как запустить win32-процесс из
драйвера. Это я смог. Оказалось, что win32-процессы, порождённые от
процесса system, неработоспособны, но проблема решаема запуском процесса
из контекста нормального win32-процесса с помощью kernel-mode APC.
Теперь я пытаюсь перенаправить в/в запускаемого процесса на named pipe и
терплю неудачу (то BSOD, то зависание, то молчаливое завершение процесса
сразу после запуска, то то же с кодом STATUS_BRAEKPOINT). Но из UserMode
это работает нормально! Вот 2 куска кода:
--- 1) UserMode ---
VOID InformCsrss(HANDLE hProcess, HANDLE hThread, ULONG pid, ULONG tid)
{
struct CSRSS_MESSAGE {
ULONG Unknown1;
ULONG Opcode;
ULONG Status;
ULONG Unknown2;
};
struct {
NT::PORT_MESSAGE PortMessage;
CSRSS_MESSAGE CsrssMessage;
PROCESS_INFORMATION ProcessInformation;
NT::CLIENT_ID Debugger;
ULONG CreationFlags;
ULONG VdmInfo[2];
} csrmsg = {{0}, {0}, {hProcess, hThread, pid, tid}, {0},
STARTF_USESTDHANDLES, {0}};
NT::CsrClientCallServer(&csrmsg, 0, 0x10000, 0x24);
}
PWSTR CopyEnvironment(HANDLE hProcess)
{
PWSTR env = GetEnvironmentStringsW();
ULONG n;
for (n = 0; env[n] != 0; n += wcslen(env + n) + 1) ; n *= sizeof
*env;
ULONG m = n;
PVOID p = 0;
NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &m,
MEM_COMMIT, PAGE_READWRITE);
NT::ZwWriteVirtualMemory(hProcess, p, env, n, 0);
return PWSTR(p);
}
VOID CreateProcessParameters(HANDLE hProcess, NT::PPEB Peb,
NT::PUNICODE_STRING ImageFile, HANDLE rr,
HANDLE rw)
{
NT::PPROCESS_PARAMETERS pp;
NT::RtlCreateProcessParameters(&pp, ImageFile, 0, 0, 0,
STARTF_USESTDHANDLES, 0, 0, 0, 0);
pp->hStdInput=rr;
pp->hStdOutput=rw;
pp->hStdError=rw;
pp->dwFlags=STARTF_USESTDHANDLES;
pp->Environment = CopyEnvironment(hProcess);
ULONG n = pp->Size;
PVOID p = 0;
NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &n,
MEM_COMMIT, PAGE_READWRITE);
NT::ZwWriteVirtualMemory(hProcess, p, pp, pp->Size, 0);
NT::ZwWriteVirtualMemory(hProcess, PCHAR(Peb) + 0x10, &p, sizeof p,
0);
NT::RtlDestroyProcessParameters(pp);
}
int exec(NT::PUNICODE_STRING name, HANDLE rr, HANDLE rw)
{
HANDLE hProcess, hThread, hSection, hFile;
NT::OBJECT_ATTRIBUTES oa = {sizeof oa, 0, name,
OBJ_CASE_INSENSITIVE};
NT::IO_STATUS_BLOCK iosb;
NT::ZwOpenFile(&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);
NT::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;
n = sii.StackCommit + PAGE_SIZE;
PVOID p = PCHAR(stack.ExpandableStackBase) - n;
NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &n,
MEM_COMMIT, PAGE_READWRITE);
ULONG x; n = PAGE_SIZE;
NT::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;
NT::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);
CreateProcessParameters(hProcess, pbi.PebBaseAddress, name, rr, rw);
InformCsrss(hProcess, hThread,
ULONG(cid.UniqueProcess), ULONG(cid.UniqueThread));
NT::ZwResumeThread(hThread, 0);
NT::ZwClose(hProcess);
NT::ZwClose(hThread);
return int(cid.UniqueProcess);
}
NTSTATUS OpenPipe(NT::PHANDLE phPipe, NT::PUNICODE_STRING PipeName,
ACCESS_MASK DesiredAccess)
{
NT::IO_STATUS_BLOCK iosb;
NT::OBJECT_ATTRIBUTES attr = {sizeof attr, 0, PipeName,
OBJ_INHERIT};
NTSTATUS status = NT::ZwOpenFile(phPipe, DesiredAccess |
SYNCHRONIZE,
&attr, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
printf("ZwOpenFile:%08X\n",status);
return status;
}
NTSTATUS myCreatePipe(PHANDLE phPipe, NT::PUNICODE_STRING PipeName, IN
ACCESS_MASK DesiredAccess)
{
NT::IO_STATUS_BLOCK iosb;
NT::OBJECT_ATTRIBUTES attr = {sizeof attr, 0, PipeName,
OBJ_INHERIT};
NT::LARGE_INTEGER nTimeOut;
nTimeOut.QuadPart = (__int64)-1E7;
NTSTATUS status = NT::ZwCreateNamedPipeFile(phPipe,
DesiredAccess |
SYNCHRONIZE | FILE_ATTRIBUTE_TEMPORARY, &attr, &iosb, FILE_SHARE_READ |
FILE_SHARE_WRITE,
FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, FALSE, FALSE,
FALSE, 1,
0x1000, 0x1000, &nTimeOut);
printf("ZwCreateNamedPipeFile:%08X\n",status);
return status;
}
void MakePipeName(NT::PUNICODE_STRING PipeName)
{
NT::ANSI_STRING aPipeName;
static unsigned long PipeIdx;
char buf[47];
_snprintf(buf, sizeof buf,
"\\Device\\NamedPipe\\Win32Pipes.%08x.%08x",
PipeIdx++, 0);
NT::RtlInitAnsiString(&aPipeName, buf);
NT::RtlAnsiStringToUnicodeString(PipeName,&aPipeName,TRUE);
}
#pragma comment(linker, "-entry:wmainCRTStartup")
extern "C"
int wmain(int argc, wchar_t *argv[])
{
NT::UNICODE_STRING ImageFile;
NT::RtlInitUnicodeString(&ImageFile,
L"\\SystemRoot\\System32\\ping.exe");
HANDLE rr, rw, lr, lw;
NT::UNICODE_STRING RPipeName, WPipeName;
MakePipeName(&RPipeName);
MakePipeName(&WPipeName);
if (myCreatePipe(&lr, &RPipeName, GENERIC_READ)) return 0;
if (myCreatePipe(&lw, &WPipeName, GENERIC_WRITE)) return 0;
if (OpenPipe(&rr, &WPipeName, GENERIC_READ)) return 0;
if (OpenPipe(&rw, &RPipeName, GENERIC_WRITE)) return 0;
exec(&ImageFile,rr,rw);
CloseHandle(rr);
CloseHandle(rw);
--- 2) kernel-mode ---
PWSTR InitEnvironment(HANDLE hProcess)
{
PVOID p=0;
DWORD dummy=0;
DWORD n=sizeof(dummy);
DWORD m;
m=n;
NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &m,
MEM_COMMIT, PAGE_READWRITE);
ZwWriteVirtualMemory(hProcess, p, &dummy, n, 0);
return PWSTR(p);
}
// Clone of Ntdll::RtlCreateProcessParameters...
VOID RtlCreateProcessParameters(NT::PPROCESS_PARAMETERS* pp,
NT::PUNICODE_STRING ImageFile,
NT::PUNICODE_STRING DllPath,
NT::PUNICODE_STRING CurrentDirectory,
NT::PUNICODE_STRING CommandLine,
ULONG
CreationFlag,
NT::PUNICODE_STRING WindowTitle,
NT::PUNICODE_STRING Desktop,
NT::PUNICODE_STRING Reserved,
NT::PUNICODE_STRING Reserved2){
NT::PROCESS_PARAMETERS* lpp;
ULONG Size=sizeof(NT::PROCESS_PARAMETERS);
if(ImageFile) Size+=ImageFile->MaximumLength;
if(DllPath) Size+=DllPath->MaximumLength;
if(CurrentDirectory) Size+=CurrentDirectory->MaximumLength;
if(CommandLine) Size+=CommandLine->MaximumLength;
if(WindowTitle) Size+=WindowTitle->MaximumLength;
if(Desktop) Size+=Desktop->MaximumLength;
if(Reserved) Size+=Reserved->MaximumLength;
if(Reserved2) Size+=Reserved2->MaximumLength;
//Allocate the buffer..
*pp=(NT::PPROCESS_PARAMETERS)NT::ExAllocatePool(NT::NonPagedPool,Size);
lpp=*pp;
RtlZeroMemory(lpp,Size);
lpp->AllocationSize=PAGE_SIZE;
lpp->Size=sizeof(NT::PROCESS_PARAMETERS); // Unicode size will
be added
(if any)
lpp->hStdInput=0;
lpp->hStdOutput=0;
lpp->hStdError=0;
if(CurrentDirectory){
lpp->CurrentDirectoryName.Length=CurrentDirectory->Length;
lpp->CurrentDirectoryName.MaximumLength=CurrentDirectory->MaximumLength;
RtlCopyMemory((PCHAR)(lpp)+lpp->Size,CurrentDirectory->Buffer,CurrentDirectory->Length);
lpp->CurrentDirectoryName.Buffer=(PWCHAR)lpp->Size;
lpp->Size+=CurrentDirectory->MaximumLength;
}
if(DllPath){
lpp->DllPath.Length=DllPath->Length;
lpp->DllPath.MaximumLength=DllPath->MaximumLength;
RtlCopyMemory((PCHAR)(lpp)+lpp->Size,DllPath->Buffer,DllPath->Length);
lpp->DllPath.Buffer=(PWCHAR)lpp->Size;
lpp->Size+=DllPath->MaximumLength;
}
if(ImageFile){
lpp->ImageFile.Length=ImageFile->Length;
lpp->ImageFile.MaximumLength=ImageFile->MaximumLength;
RtlCopyMemory((PCHAR)(lpp)+lpp->Size,ImageFile->Buffer,ImageFile->Length);
lpp->ImageFile.Buffer=(PWCHAR)lpp->Size;
lpp->Size+=ImageFile->MaximumLength;
}
if(CommandLine){
lpp->CommandLine.Length=CommandLine->Length;
lpp->CommandLine.MaximumLength=CommandLine->MaximumLength;
RtlCopyMemory((PCHAR)(lpp)+lpp->Size,CommandLine->Buffer,CommandLine->Length);
lpp->CommandLine.Buffer=(PWCHAR)lpp->Size;
lpp->Size+=CommandLine->MaximumLength;
}
if(WindowTitle){
lpp->WindowTitle.Length=WindowTitle->Length;
lpp->WindowTitle.MaximumLength=WindowTitle->MaximumLength;
RtlCopyMemory((PCHAR)(lpp)+lpp->Size,WindowTitle->Buffer,WindowTitle->Length);
lpp->WindowTitle.Buffer=(PWCHAR)lpp->Size;
lpp->Size+=WindowTitle->MaximumLength;
}
if(Desktop){
lpp->Desktop.Length=Desktop->Length;
lpp->Desktop.MaximumLength=Desktop->MaximumLength;
RtlCopyMemory((PCHAR)(lpp)+lpp->Size,Desktop->Buffer,Desktop->Length);
lpp->Desktop.Buffer=(PWCHAR)lpp->Size;
lpp->Size+=Desktop->MaximumLength;
}
if(Reserved){
lpp->Reserved2.Length=Reserved->Length;
lpp->Reserved2.MaximumLength=Reserved->MaximumLength;
RtlCopyMemory((PCHAR)(lpp)+lpp->Size,Reserved->Buffer,Reserved->Length);
lpp->Reserved2.Buffer=(PWCHAR)lpp->Size;
lpp->Size+=Reserved->MaximumLength;
}
/* if(Reserved2){
lpp->Reserved3.Length=Reserved2->Length;
lpp->Reserved3.MaximumLength=Reserved2->MaximumLength;
RtlCopyMemory((PCHAR)(lpp)+lpp->Size,Reserved2->Buffer,Reserved2->Length);
lpp->Reserved3.Buffer=(PWCHAR)lpp->Size;
lpp->Size+=Reserved2->MaximumLength;
}*/
}
VOID CreateProcessParameters(HANDLE hProcess, NT::PPEB Peb,
NT::PUNICODE_STRING ImageFile, HANDLE
hStdInPipe, HANDLE hStdOutPipe)
{
NT::PPROCESS_PARAMETERS pp;
NT::UNICODE_STRING CurrentDirectory;
NT::UNICODE_STRING
DllPath;
NT::RtlInitUnicodeString(&CurrentDirectory,L"C:\\WINNT\\SYSTEM32\\");
NT::RtlInitUnicodeString(&DllPath,L"C:\\;C:\\WINNT\\;C:\\WINNT\\SYSTEM32\\");
RtlCreateProcessParameters(&pp, ImageFile,
&DllPath,&CurrentDirectory, ImageFile, 0, 0, 0, 0, 0);
pp->hStdInput=hStdInPipe;
pp->hStdOutput=hStdOutPipe;
pp->hStdError=hStdOutPipe;
pp->dwFlags=STARTF_USESTDHANDLES;
pp->Environment = InitEnvironment(hProcess);
ULONG n = pp->Size;
PVOID p = 0;
NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &n,
MEM_COMMIT, PAGE_READWRITE);
ZwWriteVirtualMemory(hProcess, p, pp, pp->Size, 0);
ZwWriteVirtualMemory(hProcess, PCHAR(Peb) + 0x10, &p, sizeof p, 0);
RtlDestroyProcessParameters(pp);
}
NTSTATUS myCreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe /*IN
ACCESS_MASK DesiredAccess*/)
{
NT::IO_STATUS_BLOCK iosb;
NT::ANSI_STRING aPipeName;
static unsigned long PipeIdx;
NT::UNICODE_STRING PipeName;
char buf[47];
_snprintf(buf, sizeof buf,
"\\Device\\NamedPipe\\Win32Pipes.%08x.%08x",
PipeIdx++, NT::KeTickCount.LowPart);
NT::RtlInitAnsiString(&aPipeName, buf);
NT::RtlAnsiStringToUnicodeString(&PipeName,&aPipeName,TRUE);
NT::OBJECT_ATTRIBUTES attr = {sizeof attr, 0, &PipeName,
OBJ_INHERIT};
NT::LARGE_INTEGER nTimeOut;
nTimeOut.QuadPart = (__int64)-1E7;
NTSTATUS status = ZwCreateNamedPipeFile(hReadPipe, GENERIC_READ
|
SYNCHRONIZE | FILE_ATTRIBUTE_TEMPORARY, &attr, &iosb, FILE_SHARE_READ |
FILE_SHARE_WRITE,
FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, FALSE, FALSE,
FALSE, 1,
0x1000, 0x1000, &nTimeOut);
status = NT::ZwOpenFile(hWritePipe, GENERIC_WRITE | SYNCHRONIZE,
&attr,
&iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE); return status;
}
int exec_piped(NT::PUNICODE_STRING name, PHANDLE phRPipe, PHANDLE
phWPipe, HANDLE ParentPID)
{
HANDLE hProcess, hThread, hSection, hFile;
_asm int 3;
NT::OBJECT_ATTRIBUTES oa = {sizeof oa, 0, name,
OBJ_CASE_INSENSITIVE};
NT::IO_STATUS_BLOCK iosb;
NT::ZwOpenFile(&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);
NT::CLIENT_ID clid;
HANDLE hParentProcess;
clid.UniqueThread=0;
clid.UniqueProcess=ParentPID;
NT::ZwOpenProcess(&hParentProcess, PROCESS_ALL_ACCESS, &oa,
&clid);
ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, &oa,
hParentProcess/*NtCurrentProcess()*/, TRUE,
hSection, 0, 0);
NT::ZwClose(hParentProcess);
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;
n = sii.StackCommit + PAGE_SIZE;
PVOID p = PCHAR(stack.ExpandableStackBase) - n;
NT::ZwAllocateVirtualMemory(hProcess, &p, 0, &n,
MEM_COMMIT, PAGE_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 hStdInPipe;
HANDLE hStdOutPipe;
if (myCreatePipe(&hStdInPipe, phWPipe)) return 0;
if (myCreatePipe(phRPipe, &hStdOutPipe)) return 0;
CreateProcessParameters(hProcess, pbi.PebBaseAddress, name,
hStdInPipe,
hStdOutPipe);
InformCsrss(hProcess, hThread,
ULONG(cid.UniqueProcess), ULONG(cid.UniqueThread));
ZwResumeThread(hThread, 0);
NT::ZwClose(hProcess);
NT::ZwClose(hThread);
NT::ZwClose(hStdInPipe);
NT::ZwClose(hStdOutPipe);
return int(cid.UniqueProcess);
}
Второй кусок без STARTF_USESTDHANDLES работает !
©2004 Google