收藏本站 收藏本站
积木网首页 - 软件测试 - 常用手册 - 站长工具 - 技术社区
积木学院 > 黑客技术 > 黑客编程 > 正文

修改目标进程的父进程

来源:互联摘选 日期:2008-09-19 01:11

windows下的父进程并不是指创建目标的源进程,而是指将被子进程所“继承”的对象,子进程的很多重要域,像QuotaBlock、DeviceMap、SessionId、Token、process address space之类都从父进程继承而来。父进程是怎么指定的呢?不论是NtCreateProcess还是NtCreateProcessEx参数中都有一个ParentProcess的handle指明了父进程是谁,它并不要求父进程是当前进程,虽然CreateProcessW总是这样做。所以说前面有了“源进程和父进程”之分。
    那么具体怎样实现父进程不是当前进程呢?Gary Nebbett在n年前给出了一种代码,修改一下贴出来:

以下内容为程序代码:


#define _WIN32_
#include <stdio.h>
#include <windows.h>

extern "C" {
#define NTAPI __stdcall
typedef struct _PEB *PPEB;
#define PAGE_SIZE 0x1000
typedef LONG NTSTATUS;
#define DECLSPEC_IMPORT     __declspec(dllimport)
#define NTSYSAPI     DECLSPEC_IMPORT
typedef struct _CLIENT_ID {
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct _PORT_MESSAGE {
    USHORT DataSize;
    USHORT MessageSize;
    USHORT MessageType;
    USHORT VirtualRangesOffset;
    CLIENT_ID ClientId;
    ULONG MessageId;
    ULONG SectionSize;
    // UCHAR Data[];
} PORT_MESSAGE, *PPORT_MESSAGE;
typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
#ifdef MIDL_PASS
    [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
    PWSTR  Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef struct _PROCESS_PARAMETERS {
    ULONG AllocationSize;
    ULONG Size;
    ULONG Flags;
    ULONG Zero;
    LONG Console;
    ULONG ProcessGroup;
    HANDLE hStdInput;
    HANDLE hStdOutput;
    HANDLE hStdError;
    UNICODE_STRING CurrentDirectoryName;
    HANDLE CurrentDirectoryHandle;
    UNICODE_STRING DllPath;
    UNICODE_STRING ImageFile;
    UNICODE_STRING CommandLine;
    PWSTR Environment;
    ULONG dwX;
    ULONG dwY;
    ULONG dwXSize;
    ULONG dwYSize;
    ULONG dwXCountChars;
    ULONG dwYCountChars;
    ULONG dwFillAttribute;
    ULONG dwFlags;
    ULONG wShowWindow;
    UNICODE_STRING WindowTitle;
    UNICODE_STRING Desktop;
    UNICODE_STRING Reserved;
    UNICODE_STRING Reserved2;
} PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;
#define OBJ_INHERIT             0x00000002L
#define OBJ_PERMANENT           0x00000010L
#define OBJ_EXCLUSIVE           0x00000020L
#define OBJ_CASE_INSENSITIVE    0x00000040L
#define OBJ_OPENIF              0x00000080L
#define OBJ_OPENLINK            0x00000100L
#define OBJ_KERNEL_HANDLE       0x00000200L
#define OBJ_VALID_ATTRIBUTES    0x000003F2L
typedef struct _OBJECT_ATTRIBUTES {
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR
    PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef unsigned long ULONG_PTR, *PULONG_PTR;
typedef struct _IO_STATUS_BLOCK {
    union {
        NTSTATUS Status;
        PVOID Pointer;
    };
    ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020
typedef struct _SECTION_IMAGE_INFORMATION { // Information Class 1
    PVOID EntryPoint;
    ULONG Unknown1;
    ULONG StackReserve;
    ULONG StackCommit;
    ULONG Subsystem;
    USHORT MinorSubsystemVersion;
    USHORT MajorSubsystemVersion;
    ULONG Unknown2;
    ULONG Characteristics;
    USHORT ImageNumber;
    BOOLEAN Executable;
    UCHAR Unknown3;
    ULONG Unknown4[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
typedef enum _SECTION_INFORMATION_CLASS {
    SectionBasicInformation,
    SectionImageInformation
} SECTION_INFORMATION_CLASS;
typedef struct _USER_STACK {
    PVOID FixedStackBase;
    PVOID FixedStackLimit;
    PVOID ExpandableStackBase;
    PVOID ExpandableStackLimit;
    PVOID ExpandableStackBottom;
} USER_STACK, *PUSER_STACK;
typedef LONG KPRIORITY;
typedef struct _PROCESS_BASIC_INFORMATION {
    NTSTATUS ExitStatus;
    PPEB PebBaseAddress;
    ULONG_PTR AffinityMask;
    KPRIORITY BasePriority;
    ULONG_PTR UniqueProcessId;
    ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
typedef enum _PROCESSINFOCLASS {
    ProcessBasicInformation,
    ProcessQuotaLimits,
    ProcessIoCounters,
    ProcessVmCounters,
    ProcessTimes,
    ProcessBasePriority,
    ProcessRaisePriority,
    ProcessDebugPort,
    ProcessExceptionPort,
    ProcessAccessToken,
    ProcessLdtInformation,
    ProcessLdtSize,
    ProcessDefaultHardErrorMode,
    ProcessIoPortHandlers,          // Note: this is kernel mode only
    ProcessPooledUsageAndLimits,
    ProcessWorkingSetWatch,
    ProcessUserModeIOPL,
    ProcessEnableAlignmentFaultFixup,
    ProcessPriorityClass,
    ProcessWx86Information,
    ProcessHandleCount,
    ProcessAffinityMask,
    ProcessPriorityBoost,
    ProcessDeviceMap,
    ProcessSessionInformation,
    ProcessForegroundInformation,
    ProcessWow64Information,
    MaxProcessInfoClass
    } PROCESSINFOCLASS;
#define InitializeObjectAttributes(p, n, a, r, s){      \
    (p)->Length = sizeof(OBJECT_ATTRIBUTES) ;           \
    (p)->RootDirectory = r;                             \
    (p)->Attributes = a;                                \
    (p)->ObjectName = n;                                \
    (p)->SecurityDescriptor = s;                        \
    (p)->SecurityQualityOfService = NULL;               \
    }
#define FILE_OPEN                       0x00000001
#define DIRECTORY_QUERY                 (0x0001)
NTSTATUS
NTAPI
CsrClientCallServer(
    IN PVOID Message,
    IN PVOID,
    IN ULONG Opcode,
    IN ULONG Size) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwAllocateVirtualMemory(
    IN HANDLE ProcessHandle,
    IN OUT PVOID *BaseAddress,
    IN ULONG ZeroBits,
    IN OUT PULONG AllocationSize,
    IN ULONG AllocationType,
    IN ULONG Protect) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwWriteVirtualMemory(
    IN HANDLE ProcessHandle,
    IN PVOID BaseAddress,
    IN PVOID Buffer,
    IN ULONG BufferLength,
    OUT PULONG ReturnLength OPTIONAL) ;
NTSTATUS
NTAPI
RtlCreateProcessParameters(
    OUT PPROCESS_PARAMETERS *ProcessParameters,
    IN PUNICODE_STRING ImageFile,
    IN PUNICODE_STRING DllPath OPTIONAL,
    IN PUNICODE_STRING CurrentDirectory OPTIONAL,
    IN PUNICODE_STRING CommandLine OPTIONAL,
    IN ULONG CreationFlags,
    IN PUNICODE_STRING WindowTitle OPTIONAL,
    IN PUNICODE_STRING Desktop OPTIONAL,
    IN PUNICODE_STRING Reserved OPTIONAL,
    IN PUNICODE_STRING Reserved2 OPTIONAL) ;
NTSTATUS
NTAPI
RtlDestroyProcessParameters(
    IN PPROCESS_PARAMETERS ProcessParameters) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenFile(
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG ShareAccess,
    IN ULONG OpenOptions) ;

NTSYSAPI
NTSTATUS
NTAPI
ZwDeleteFile(
    IN POBJECT_ATTRIBUTES ObjectAttributes) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateSection(
    OUT PHANDLE SectionHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN PLARGE_INTEGER SectionSize OPTIONAL,
    IN ULONG Protect,
    IN ULONG Attributes,
    IN HANDLE FileHandle) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
    IN HANDLE Handle) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateProcess(
    OUT PHANDLE ProcessHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN HANDLE InheritFromProcessHandle,
    IN BOOLEAN InheritHandles,
    IN HANDLE SectionHandle OPTIONAL,
    IN HANDLE DebugPort OPTIONAL,
    IN HANDLE ExceptionPort OPTIONAL) ;
#define NtCurrentProcess() ((HANDLE)-1)
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySection(
    IN HANDLE SectionHandle,
    IN SECTION_INFORMATION_CLASS SectionInformationClass,
    OUT PVOID SectionInformation,
    IN ULONG SectionInformationLength,
    OUT PULONG ResultLength OPTIONAL) ;
NTSYSAPI
NTSTATUS
NTAPI
ZwProtectVirtualMemory(
    IN HANDLE ProcessHandle,
    IN OUT PVOID *BaseAddress,
    IN OUT PULONG ProtectSize,
    IN ULONG NewProtect,
    OUT PULONG OldProtect) ; 
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateThread(
    OUT PHANDLE ThreadHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN HANDLE ProcessHandle,
    OUT PCLIENT_ID ClientId,
    IN PCONTEXT ThreadContext,
    IN PUSER_STACK UserStack,
    IN BOOLEAN CreateSuspended) ; 
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryInformationProcess(
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID ProcessInformation,
    IN ULONG ProcessInformationLength,
    OUT PULONG ReturnLength OPTIONAL) ; 
NTSYSAPI
NTSTATUS
NTAPI
ZwResumeThread(
    IN HANDLE ThreadHandle,
    OUT PULONG PreviousSuspendCount OPTIONAL) ; 
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
    PUNICODE_STRING DestinationString,
    PCWSTR SourceString) ; 
NTSYSAPI
NTSTATUS
NTAPI
ZwCreateFile(
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PLARGE_INTEGER AllocationSize OPTIONAL,
    IN ULONG FileAttributes,
    IN ULONG ShareAccess,
    IN ULONG CreateDisposition,
    IN ULONG CreateOptions,
    IN PVOID EaBuffer OPTIONAL,
    IN ULONG EaLength) ; 
}

VOID InformCsrss(HANDLE hProcess, HANDLE hThread, ULONG pid, ULONG tid)
{
    struct CSRSS_MESSAGE {
        ULONG Unknown1;
        ULONG Opcode;
        ULONG Status;
        ULONG Unknown2;
    };

    struct {
        PORT_MESSAGE PortMessage;
        CSRSS_MESSAGE CsrssMessage;
        PROCESS_INFORMATION ProcessInformation;
        CLIENT_ID Debugger;
        ULONG CreationFlags;
        ULONG VdmInfo[2];
    } csrmsg = {{0}, {0}, {hProcess, hThread, pid, tid}, {0}, 0, {0}};

    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;
    ZwAllocateVirtualMemory(hProcess, &p, 0, &m, MEM_COMMIT, PAGE_READWRITE);

    ZwWriteVirtualMemory(hProcess, p, env, n, 0);

    return PWSTR(p);
}

VOID CreateProcessParameters(HANDLE hProcess, PPEB Peb, PUNICODE_STRING ImageFile)
{
    PPROCESS_PARAMETERS pp;

    RtlCreateProcessParameters(&pp, ImageFile, 0, 0, 0, 0, 0, 0, 0, 0);

    pp->Environment = CopyEnvironment(hProcess);

    ULONG n = pp->Size;
    PVOID p = 0;
    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);
}

int exec(PUNICODE_STRING name, PWSTR param)
{
PWSTR tmp;
    HANDLE hProcess, hThread, hSection, hFile;
OBJECT_ATTRIBUTES oa;
RtlZeroMemory(&oa, sizeof(OBJECT_ATTRIBUTES)) ; 
InitializeObjectAttributes( &oa,name, OBJ_CASE_INSENSITIVE, 0, NULL);
IO_STATUS_BLOCK iosb;
    ZwOpenFile(&hFile,FILE_READ_DATA|FILE_EXECUTE|SYNCHRONIZE, &oa, &iosb,
                   FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);

    oa.ObjectName = 0;

    ZwCreateSection(&hSection, SECTION_ALL_ACCESS, 0, 0, PAGE_EXECUTE, SEC_IMAGE, hFile);

    ZwClose(hFile);

HANDLE hep = OpenProcess(PROCESS_ALL_ACCESS, 0, wcstol(param, &tmp, 10));

    ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, 0,
                        hep, TRUE, hSection, 0, 0);

CloseHandle(hep);

    SECTION_IMAGE_INFORMATION sii;
    ZwQuerySection(hSection, SectionImageInformation, &sii, sizeof sii, 0);

    ZwClose(hSection);

    USER_STACK stack = {0};

    ULONG n = sii.StackReserve;
    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;
    ZwAllocateVirtualMemory(hProcess, &p, 0, &n, MEM_COMMIT, PAGE_READWRITE);

    ULONG x; n = PAGE_SIZE;
    ZwProtectVirtualMemory(hProcess, &p, &n, PAGE_READWRITE | PAGE_GUARD, &x);

    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);

    CLIENT_ID cid;

    ZwCreateThread(&hThread, THREAD_ALL_ACCESS, 0, hProcess, &cid, &context, &stack, TRUE);

    PROCESS_BASIC_INFORMATION pbi;
    ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof pbi, 0);

    CreateProcessParameters(hProcess, pbi.PebBaseAddress, name);

    InformCsrss(hProcess, hThread, ULONG(cid.UniqueProcess), ULONG(cid.UniqueThread));

    ZwResumeThread(hThread, 0);

    ZwClose(hProcess);
    ZwClose(hThread);

    return int(cid.UniqueProcess);
}

extern "C"
int wmain(int argc, wchar_t *argv[])
{
    UNICODE_STRING ImageFile;
    RtlInitUnicodeString(&ImageFile, argv[1]);

    exec(&ImageFile, argv[2]);

    return 0;
}

使用:比如编译后为ppp.exe,要用ppp运行c:根目录上qqq.exe,欲设定其父进程为explorer.exe,explorer.exe的pid为***。在控制台输入:
    ppp.exe \??\c:\qqq.exe ***
    回车后用别的工具看看qqq.exe的父进程,不是ppp而是explorer。因为创建时qqq.exe的EPROCESS中的InheritedFromUniqueProcessId已被设置为了explorer的pid,而通过ZwQuery***查询就是返回InheritedFromUniqueProcessId。
    并不是所有PE格式应用程序都可以用上面程序加载,按需要修改吧。

    有什么用呢,主要是演示,有一些小用,比如说调试别的进程时修改父进程为explorer而不是自己可以防父进程查询的手段(最简单可通过hook来改掉ZwCreateProcess的参数)等等。

推荐阅读

 

热点信息

 
强悍的草根IT技术社区,这里应该有您想要的! 友情链接:b2b电子商务
Copyright © 2010 Gimoo.Net. All Rights Rreserved  京ICP备05050695号