windows黑客编程系列(三):启动技术

文章目录

    • 启动技术
      • 创建进程API
        • Winexec
          • 参数说明:
          • 返回值
          • 示例程序
        • ShellExecute
          • 参数
          • 返回值
          • 示例程序
        • CreateProcess
          • 参数
          • 返回值
          • 示例程序
      • 小结

启动技术

病毒木马植入模块成功植入计算机之后,便会启动攻击模块来对用户计算机数据实施窃取和回传等操作。通常植入和攻击是分开在不同的模块之中的,这里的模块指的是DLL、exe或者其他加密的PE文件。只有当前植入模块成功运行后,方可继续执行攻击模块,同时会删除植入模块的数据和文件。模块化开发的好处不单单是便于开发管理,同时也可以减小因某一模块失败而造成整个程序暴露的风险。

创建进程API

创建进程API主要有三个:

  • WinExec
  • ShellExecute
  • CreateProcess

除了可以创建进程外,还能执行CMD命令;

Winexec

运行指定的程序

UINT WINAPI WinExec(
_In_ LPCTSTR lpCmdLine,
_In_ UINT uCmdShow)
参数说明:
  • lpCmdLine:要执行应用程序的命令行,如果在该参数中的可执行文件不包括目录路径,则系统将按照以下顺序搜索可执行文件:
    1. 应用程序目录
    2. 当前目录
    3. windows系统目录
    4. windows目录
    5. path环境变量列出的目录
  • uCmdShow:显示选项
    1. SW_HIDE表示隐藏窗口并激活其他窗口
    2. SW_SHOWNORMAL表示激活并显示另一个窗口
返回值
  • 如果函数成功,则返回值大于31
  • 如果函数失败,则返回值是以下错误值之一
含义
0 系统内存或资源不足
ERROR_BAD_FORMAT exe文件无效
ERROR_FILE_NOT_FOUND 找不到指定文件
ERROR_PATH_NOT_FOUND 找不到指定目录
示例程序

通过winExec API启动计算器窗口;

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#undef UNICODE
#include 
#include 
#include "resource.h"

BOOL WinExec_Test(char* pszExePath, UINT uiCmdShow)
{
	UINT uiRet = 0;
	uiRet = WinExec(pszExePath, uiCmdShow);
	if (uiRet > 31)
	{
		return TRUE;
	}
	return FALSE;
}

int main()
{
	char pszExePath[40] = "C:\\Windows\\System32\\calc.exe";
	BOOL flag = WinExec_Test(pszExePath, SW_SHOWNORMAL);
	if (flag == TRUE)
	{
		printf("success\n");
	}
	return 0;
}

可见,已经把计算器窗口打开了。

windows黑客编程系列(三):启动技术_第1张图片

不加绝对路径,直接启动也是可以的。

int main()
{
	char pszExePath[40] = "calc.exe";
	BOOL flag = WinExec_Test(pszExePath, SW_HIDE);
	if (flag == TRUE)
	{
		printf("success\n");
	}
	return 0;
}

ShellExecute

运行一个外部程序(或者打开一个已注册的文件、目录,或打印一个文件等),对外部程序进行一定程度的控制。

HINSTANCE ShellExecute(
_In_opt_ HWND hwnd,
_In_opt_ LPCTSTR lpOperation,
_In_ LPCTSTR lpFile,
_In_opt_ LPCTSTR lpParameters,
_In_opt_ LPCTSTR lpDirectory,
_In_ INT nShowCmd)
参数
  • hwnd:用于显示UI或错误消息的父窗口句柄。如果操作不与窗口关联,此值可以为NULL。
  • lpOperation:指向以空字符结尾的字符串的指针,在本例中称为动词,用于指定要执行的操作。常使用的动词有:
    1. edit:启动编辑器并打开文档进行编辑,如果文件不是文档文件,则失败。
    2. explore:探索由lpFile指定的文件夹。
    3. find:在由lpDirectory指定的目录中启动搜索
    4. open:打开由lpFile参数指定的项目,可以是文件也可以是文件夹
    5. print:打印lpFIle参数指定的文件,如果不是文档则失败。
    6. NULL:如果可用使用默认动词,不过不可用使用打开动词,如果都不可用,则使用注册表中列出的第一个动词
  • lpFIle:指向以空字符结尾的字符串的指针,该字符串要在其上执行指定谓词的文件或对象。要指定一个shell名称空间对象,传递完全限定的解析名称,如果lpDirectory使用相对路径,那么lpFIle就不要用绝对路径。
  • lpParameters:如果lpFIle指定一个可执行文件,则此参数是一个指向以空字符结尾的字符串的指针,该字符串指定要传递给应用程序的参数。如果lpFIle是一个文档文件,则该参数为NULL。
  • lpDirectory:指向以空字符终止的字符串的指针,该字符串指定操作的默认目录。如果此值为NULL,则使用当前的工作目录。
  • nShowCmd:与WinExec API中该参数一致。
返回值

如果函数成功,则返回值大于32,否则将返回错误值,指示失败原因。

示例程序
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#undef UNICODE
#include 
#include 
#include "resource.h"
#include "ConsoleApplication1.h"



BOOL ShellExecute_Test(char* pszExePath, char* lpDIrec, UINT uiCmdShow)
{
	HINSTANCE hinstance = 0;
	hinstance = ShellExecute(NULL, "open", pszExePath, NULL, lpDIrec, uiCmdShow);
	if ((DWORD)hinstance > 32)
	{
		return TRUE;
	}
	return FALSE;
}

int main()
{
	char pszExePath[40] = "calc.exe";
	char lpDIrec[40] = "C:\\Windows\\System32";
	BOOL flag = ShellExecute_Test(pszExePath, lpDIrec, SW_HIDE);
	if (flag == TRUE)
	{
		printf("success\n");
	}
	return 0;
}

运行窗口:

windows黑客编程系列(三):启动技术_第2张图片

CreateProcess

创建一个新进程及主线程,新进程在调用进程的安全的上下文中运行。

BOOL WINAPI CreateProcess(
10个参数)
参数

与WinExec以及ShellExecute函数相比较而言,CreateProcess函数的参数更多,使用起来更复杂。我们着重关注以下5个参数:

  • 执行模块名称lpApplicationName
  • 执行命令行的参数 lpCommandLine
  • 控制进程优先级和创建进程标志的参数 dwCreationFlags
  • 指向STARTUPINFO信息结构的参数lpStartupInfo
  • 指向PROCESS_INFORMATION信息结构的参数lpProcessInformation
返回值
  • 如果函数成功,返回值非0
  • 如果函数失败,返回值为0
示例程序
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#include 
#include "resource.h"
#include "ConsoleApplication1.h"

BOOL CreateProcess_Test(LPWSTR pszExePath, UINT uiCmdShow)
{
	STARTUPINFO si = { 0 };
	PROCESS_INFORMATION pi;
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = uiCmdShow;
	BOOL bRet = CreateProcess(NULL, pszExePath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
	if (bRet)
	{
		CloseHandle(pi.hThread);
		CloseHandle(pi.hProcess);
		return TRUE;
	}
	return FALSE;
}


int main()
{
	wchar_t pszExePath[20] = L"calc.exe";
	BOOL flag = CreateProcess_Test(pszExePath, SW_HIDE);
	if (flag == TRUE)
	{
		printf("success\n");
	}
	return 0;
}

windows黑客编程系列(三):启动技术_第3张图片

小结

  • SW_HIDE的隐藏窗口只能隐藏CMD命令行窗口,对于其他程序窗口不能成功隐藏。
  • 在用户层上,通常利用WMI或者通过HOOK API来监控进程的创建
  • EnumWindows函数可以枚举所有屏幕上的顶层窗口,包括隐藏窗口

你可能感兴趣的:(windows编程)