您的位置:首页 > 其它

读取其它进程启动参数(综合网上文章)

2009-01-24 17:57 253 查看
方法:

1.先用OpenProcess 打开目标进程的进程空间,得到句柄

2.使用NtQueryInformationProcess这个API去读取进程里面的PE块的基地址也就是:PebBaseAddress

3.继续使用ReadProcessMemory,从这个PebBaseAddress,开始读取PEB(PE Block),这时候可以得到ProcessParameters,进程的参数地址

4.
继续使用ReadProcessMemory,从这个ProcessParameters,开始读取PROCESS_PARAMETERS,这时候可以得
到CommandLine.Length和CommandLine.Buffer,也就是启动参数的长度和启动参数的地址。

5.最后再使
用ReadProcessMemory,根据记动参数的地址和长度去读取启动参数。特别要注意的事情是,如果在unicode的系统中,这时候读到的启动
参数也是unicode的,所以得定义对应的字串类型去读取,不然打印出来的字串只有第一个字母(比如说参数是:abc,如果用ansi的字串,结果就
是:a/0b/0c/0,/0这个就表示字串的结束了)。

最后,如果发现在第2步的时候出现读取错误,这时候应该是程序没有debug的权限了,可以用以下方法来提升程序的权限:

1.先用LookupPrivilegeValue来查看能否拥有:SeDebugPrivilege这个权限

2.如果可以,就用以下代码来提升权限:

Privileges.Privileges[0].Luid:=DebugNameValue;
Privileges.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
Result:=AdjustTokenPrivileges(TokenHandle,False,Privileges,SizeOf(Privileges),nil,RetLen);



以下是一个实际例子。。另外,里面用到的一些结构我发现在winternal.h头文件中!!!

//在测试的时候发现,中文参数用wprintf显示不出来。所以还是用 WideCharToMultiByte换了好

  1、从 fs:0定位PEB
  2、PEB偏移0x10是ProcessParameters
  3、ProcessParameters偏移0x40是CommandLine

注:OS不同,可能偏移不同



  #include <windows.h>
  #include <stdio.h>
  #define ProcessBasicInformation 0
  typedef struct
  {
   USHORT Length;
   USHORT MaximumLength;
   PWSTR Buffer;
  } UNICODE_STRING, *PUNICODE_STRING;
  typedef struct
  {
   ULONG AllocationSize;
   ULONG ActualSize;
   ULONG Flags;
   ULONG Unknown1;
   UNICODE_STRING Unknown2;
   HANDLE InputHandle;
   HANDLE OutputHandle;
   HANDLE ErrorHandle;
   UNICODE_STRING CurrentDirectory;
   HANDLE CurrentDirectoryHandle;
   UNICODE_STRING SearchPaths;
   UNICODE_STRING ApplicationName;
   UNICODE_STRING CommandLine;
   PVOID EnvironmentBlock;
   ULONG Unknown[9];
   UNICODE_STRING Unknown3;
   UNICODE_STRING Unknown4;
   UNICODE_STRING Unknown5;
   UNICODE_STRING Unknown6;
  } PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;
  typedef struct
  {
   ULONG AllocationSize;
   ULONG Unknown1;
   HINSTANCE ProcessHinstance;
   PVOID ListDlls;
   PPROCESS_PARAMETERS ProcessParameters;
   ULONG Unknown2;
   HANDLE Heap;
  } PEB, *PPEB;
  typedef struct
  {
   DWORD ExitStatus;
   PPEB PebBaseAddress;
   DWORD AffinityMask;
   DWORD BasePriority;
   ULONG UniqueProcessId;
   ULONG InheritedFromUniqueProcessId;
  } PROCESS_BASIC_INFORMATION;
  // ntdll!NtQueryInformationProcess (NT specific!)
  //
  // The function copies the process information of the
  // specified type into a buffer
  //
  // NTSYSAPI
  // NTSTATUS
  // NTAPI
  // NtQueryInformationProcess(
  // IN HANDLE ProcessHandle, // handle to process
  // IN PROCESSINFOCLASS InformationClass, // information type
  // OUT PVOID ProcessInformation, // pointer to buffer
  // IN ULONG ProcessInformationLength, // buffer size in bytes
  // OUT PULONG ReturnLength OPTIONAL // pointer to a 32-bit
  // // variable that receives
  // // the number of bytes
  // // written to the buffer
  // );
  typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
  PROCNTQSIP NtQueryInformationProcess;
  BOOL GetProcessCmdLine(DWORD dwId,LPWSTR wBuf,DWORD dwBufLen);
  void main(int argc, char* argv[])
  {
   if (argc<2)
   {
   printf("Usage:/n/ncmdline.exe ProcId/n");
   return;
   }
   NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(
   GetModuleHandle("ntdll"),
   "NtQueryInformationProcess"
   );
   if (!NtQueryInformationProcess)
   return;
   DWORD dwId;
   sscanf(argv[1],"%lu",&dwId);
   WCHAR wstr[255];
   if (GetProcessCmdLine(dwId,wstr,sizeof(wstr)))
 {
	//原文是用wprintf输出的,因为返回的wstr是宽字符,
	 //可是不知道为什么我这没输出,所以我在下面转换了下再输出
	// wprintf(L"Command line for process %lu is:/n%s/n",dwId,wstr);
 char szANSIString [MAX_PATH];   
 memset(szANSIString,0,MAX_PATH);
 WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wstr,-1, szANSIString, sizeof(szANSIString), NULL,NULL );
 printf("%s",szANSIString);
 
 }
   else
   wprintf(L"Could not get command line!");
  }
  BOOL GetProcessCmdLine(DWORD dwId,LPWSTR wBuf,DWORD dwBufLen)
  {
   LONG status;
   HANDLE hProcess;
   PROCESS_BASIC_INFORMATION pbi;
   PEB Peb;
   PROCESS_PARAMETERS ProcParam;
   DWORD dwDummy;
   DWORD dwSize;
   LPVOID lpAddress;
   BOOL bRet = FALSE;
   // Get process handle
   hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,dwId);
   if (!hProcess)
   return FALSE;
   // Retrieve information
   status = NtQueryInformationProcess( hProcess,
   ProcessBasicInformation,
   (PVOID)&pbi,
   sizeof(PROCESS_BASIC_INFORMATION),
   NULL
   );
   if (status)
   goto cleanup;
   if (!ReadProcessMemory( hProcess,
   pbi.PebBaseAddress,
   &Peb,
   sizeof(PEB),
   &dwDummy
   )
   )
   goto cleanup;
   if (!ReadProcessMemory( hProcess,
   Peb.ProcessParameters,
   &ProcParam,
   sizeof(PROCESS_PARAMETERS),
   &dwDummy
   )
   )
   goto cleanup;
   lpAddress = ProcParam.CommandLine.Buffer;
   dwSize = ProcParam.CommandLine.Length;
   if (dwBufLen<dwSize)
   goto cleanup;
   if (!ReadProcessMemory( hProcess,
   lpAddress,
   wBuf,
   dwSize,
   &dwDummy
   )
   )
   goto cleanup;
   bRet = TRUE;
  cleanup:
   CloseHandle (hProcess);
  
   return bRet;
  }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: