登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

修改目标进程的父进程  

2010-02-15 13:10:56|  分类: Delphi |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
pjf(jfpan20000@sina.com) http://pjf.blogone.net

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的参数)等等。
  评论这张
 
阅读(1803)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018