获取,修改进程命令行

摘要:
XDebug源代码学习中看到的命令行操作提取主源代码,并进行Demo以获取和更改进程命令行0x01。命令行不是通过调用GetCommandLine函数获得的。在获得进程的PEB地址之后,通过PEB地址获得ProcessParameter字段的地址。最后,通过ProcessParameter字段获得ProcessParameter的CommandLine字段,并获得命令行的存储地址。主要源代码:void*GetPEBLocation{ULONGRequiredLen=0;void*PebAddress=0;PROCESS_BASIC_INFORMATION myProcessBasicInformation[5]={0};如果{PebAddress=myProcessBasicInformation-˃PebBaseAddress;}否则{如果{PebAddress=myProcessBasicInformation-˃PebBaseAddress;}}returnPebAddress;}BOOLGET命令行地址{duintPEBAddress;duintprocess_parameters;duintProcessParametersAddress;duintReturnLength;PEBAddress=GetPEBLocation;ProcessParametersAddress=&;ReadProcessMemory;*CommandLineAddressdr=&;returnTRUE;}0x02修改命令行的关键是操作内存。XDebug首先获取GetCommandLineA或GetCommandLineW函数的地址。

在XDebug的源码学习中看到的命令行操作,将主要源码摘录出来做了个获取和更改进程命令行的Demo.

0x01  获取命令行

     这里获取命令行的方式并不是通过调用GetCommandLine函数。

   而是借由ntdll中的NtQueryInformationProcess函数查询ProcessBasicInformation,得到ProcessBasicInformation中的PebBaseAddress字段。得到进程PEB地址后,再通过PEB地址的获取ProcessParameter字段地址,

获取,修改进程命令行第1张

     最后通过ProcessParameter字段获取到ProcessParameter的 CommandLine  字段,得到了命令行的存储地址。

获取,修改进程命令行第2张

主要源码:

void* GetPEBLocation(HANDLE hProcess)
{
	ULONG RequiredLen = 0;
	void* PebAddress = 0;
	PROCESS_BASIC_INFORMATION myProcessBasicInformation[5] = { 0 };

	if (NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof(PROCESS_BASIC_INFORMATION), &RequiredLen) == STATUS_SUCCESS)
	{
		PebAddress = (void*)myProcessBasicInformation->PebBaseAddress;
	}
	else
	{
		if (NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == STATUS_SUCCESS)
		{
			PebAddress = (void*)myProcessBasicInformation->PebBaseAddress;
		}
	}

	return PebAddress;
}


BOOL Getcommandlineaddr(duint *CommandLineAddressdr)
{
	duint PEBAddress;
	duint pprocess_parameters;
	duint ProcessParametersAddress;
	duint ReturnLength;
	PEBAddress = (duint)GetPEBLocation(__ProcessHandle);
	ProcessParametersAddress = (duint) & (((PPEB)PEBAddress)->ProcessParameters);



	ReadProcessMemory(__ProcessHandle, reinterpret_cast<LPVOID>(ProcessParametersAddress), &pprocess_parameters,
		sizeof(pprocess_parameters), reinterpret_cast<SIZE_T*>(&ReturnLength));

	*CommandLineAddressdr = (duint) & (((RTL_USER_PROCESS_PARAMETERS*)pprocess_parameters)->CommandLine);

	return TRUE;
}

  

0x02  修改命令行

    修改命令行的关键就是操作内存。

    XDebug首先获取GetCommandLineA或GetCommandLineW函数的地址。

    

if (!valfromstring("kernelBase:GetCommandLineA", &getcommandline))
	{
		if (!valfromstring("kernel32:GetCommandLineA", &getcommandline))
		{
			
			return FALSE;
		}
	}


bool valfromstring(const char* string, duint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly, bool allowassign)
{
	duint result;
	if (!Calculate(string, result, false /*valuesignedcalc()*/, allowassign, silent, baseonly, value_size, isvar, hexonly))
		return false;
	*value = result;
	return true;
}

bool Calculate(const char* string, duint & value, bool signedcalc, bool allowassign, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly)
{
	
	return DoEvaluate(string, value, silent, baseonly, value_size, isvar, hexonly);
}
bool DoEvaluate(const char* string, duint & result, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly)
{
	return valfromstring_noexpr(string, (duint*)&result, silent, baseonly, value_size, isvar, hexonly);
}
bool valfromstring_noexpr(const char* string, duint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly)
{
	if (!value || !string || !*string)
		return false;

	if (valapifromstring(string, value, value_size, true, silent, hexonly)) //then come APIs
		return true;
	return false;
}
bool valapifromstring(const char* name, duint* value, int* value_size, bool printall, bool silent, bool* hexonly)
{
	//explicit API handling
	const char* apiname = strchr(name, ':'); //the ':' character cannot be in a path: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#naming_conventions
	bool noexports = false;
	if (!apiname) //not found
	{
		apiname = strstr(name, "..") ? strchr(name, '.') : strrchr(name, '.'); //kernel32.GetProcAddress support
		if (!apiname) //not found
		{
			apiname = strchr(name, '?'); //the '?' character cannot be in a path either
			noexports = true;
		}
	}
	if (apiname)
	{
		char modname[MAX_MODULE_SIZE] = "";
		strncpy_s(modname, name, _TRUNCATE);
		modname[apiname - name] = 0;
		apiname++;
		if (!strlen(apiname))
			return false;
		duint modbase = 0;//ModBaseFromName(modname);从MAP表里查基地址
		char szModPath[MAX_PATH] = "kernel32.dll";
		if (!1/*ModPathFromAddr(modbase, szModPath, _countof(szModPath))*/)//查表得到完整路径
		{
			//if (!silent)
				//dprintf(QT_TRANSLATE_NOOP("DBG", "Could not get filename of module %p
"), modbase);
		}
		else
		{
			HMODULE mod = LoadLibraryExW(Utf8ToUtf16(szModPath).c_str(), 0, DONT_RESOLVE_DLL_REFERENCES);
			if (!mod)
			{
				//if (!silent)
				//	dprintf(QT_TRANSLATE_NOOP("DBG", "Unable to load library %s
"), szModPath);
			}
			else
			{
				duint addr = noexports ? 0 : SafeGetProcAddress(mod, apiname);
				//if (addr) //found exported function
				//	addr = modbase + (addr - (duint)mod); //correct for loaded base
				//else //not found
				{
				}
				FreeLibrary(mod);
				if (addr) //found!
				{
					if (value_size)
						*value_size = sizeof(duint);
					if (hexonly)
						*hexonly = true;
					*value = addr;
					return true;
				}
			}
		}
		return false;
	}
	return true;
}

  获取到这个所谓的“函数地址后并没有结束,这里需要设计到重定向表的重定向问题,在这个地址的基础上还需要两次跳转才能得到真正的功能函数地址。这个地址上的第一次跳转,是跳向重定向表,然后重定向表再给出地址,跳向库中真正的功能函数地址。

  对应的源码操作(图中getcommandline即为前文valfromstring函数获取的GetCommandLineA或GetCommandLineW函数的地址。)

获取,修改进程命令行第3张

调试反汇编查看获取到的getcommandline地址:

获取,修改进程命令行第4张

越过FF 25两字节,获取到跳转地址76b311fch:

ReadProcessMemory(__ProcessHandle, reinterpret_cast<LPVOID>(getcommandline + 2), data, 100, reinterpret_cast<SIZE_T*>(&ReturnLength));

  

内存窗口查看76b311fch:处内容,得到重定向表给出的功能函数地址:0x7406e210

 获取,修改进程命令行第5张

    ReadProcessMemory(__ProcessHandle, reinterpret_cast<LPVOID>(*(int*)data), data, 100, reinterpret_cast<SIZE_T*>(&ReturnLength));

  

反汇编窗口中查看0x7406e210中的内容:

 获取,修改进程命令行第6张

现在就可以通过字符串匹配来得到命令行的存储地址:

 

/*

    750FE9CA | A1 CC DB 1A 75           | mov eax,dword ptr ds:[751ADBCC]         |

    750FE9CF | C3                       | ret                                     |

    */

    if (data[0] != 0xA1 || data[5] != 0xC3)

    {

         return FALSE;

    }

    command_line_stored = *((duint*)& data[1]);

  

找到地址后最后一步写入地址:

WriteProcessMemory(__ProcessHandle, reinterpret_cast<LPVOID>(command_line_stored), &new_command_line, sizeof(new_command_line), reinterpret_cast<SIZE_T*>(&ReturnLength));

    //update the pointer in the debuggee

  

免责声明:文章转载自《获取,修改进程命令行》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Delphi中ClientDataSet的用法小结python下安装 setuptools 和pip(python环境刚部署好)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Spring Boot源码(一)Spring Boot源码环境搭建

一、前言   既然要分析源码,那就直接下载源码来本地运行分析,是最有效的方案,但是在开始看这篇博客之前,希望小伙伴们有个心理准备...   源码编译是比较麻烦的一件事,我大概整了一天才基本整好源码环境,期间可能遇到各种奇奇怪怪的问题上网找答案,这里把流程记录一下,需要的小伙伴可以直接跟着步骤走,还是可以顺利编译通过的,亲测可行。 二、源码环境搭建 下载源码...

linux-网络管理-6

Hub 集线器 物理层设备 多端口中继器,不记忆MAC地址 以太网桥 OSI第二层数据链路层 扩展了网络带宽 分割了网络冲突域,使网络冲突被限制在最小的范围内 交换机作为更加智能的交换设备,能够提供更多用户所要求的功能:优先级、虚拟网、远程检测 • 学习MAC地址,并记忆,端口转发, • 当网桥接到广播帧时候,它立即转发到除接收端口之外的所有其他端口...

Linux用户空间与内核地址空间

Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。 Linux内核地址映射模型 x86 CPU采用了段页式地址映射模型。进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内...

linux命令行下修改系统时间、时区

date查看时间以及时区 图a是est时区,和HONGkong时间查了一个小时。 # 保存设置$ sudo mv /etc/localtime /etc/localtime.old # 设置时区 $ sudo ln -sf /usr/share/zoneinfo/Asia/Hong_Kong /etc/localtime # 这里已经改完了 # 更新...

命令行方式实现QQ自动登录

      上一次写过一篇VB制作QQ自动登录器的日志,介绍用得是模拟键盘输入的方式实现QQ的自动登录。这种方式有一种缺陷,就是必须保持输入焦点的正确,否则很容易就打乱了程序的执行过程,造成无法登录。特别是一开机就运行该程序,然后该程序去调用QQ的时候,Win API Winexec执行特慢,导致程序跟不上QQ,输入焦点也错了。后来在网上又发现了一种用QQ...

mysql-5.6.27源码安装及错误解决办法

环境:centos6.5.x86_64 wgethttp://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.27.tar.gz yum install -y cmake 当然也可以自己下载源码包安装,为方便就Yum安装了 useradd -s /sbin/nologin mysql tar zxvf mysql-...