Go to Google Groups Home  
Web    Images    Groups    News    FroogleNew!    more »
  Advanced Groups Search
  Preferences    
 Groups Search result 4 for zwcreateprocess zwcreatethread 

Search Result 4
From: Lev Fireworker (firew0rker@nteam.ru)
Subject: Перенаправление в/в для процесса, запущенного из драйвера
This is the only article in this thread
View: Original Format
Newsgroups: fido7.su.windows.nt.prog
Date: 2003-06-13 19:41:40 PST
Сравнительно недавно я тут спрашивал, как запустить 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 работает !


Google Home - Advertising Programs - Business Solutions - About Google

©2004 Google
Hosted by uCoz