DLL注入器编写

前段时间一直学习逆向工程核心原理,由于缺少WINAPI只是,后面的

内容学起来有些抽象,于是反回去大致扫了一下《Windows核心编程》

花了些时间写了个DLL注入器。

    基本原理

                  进程对象在windows中,地址空间基本都是相对独立的,一

个进程无法操作其他进程的空间,但是通过创建远程进程的线程,在原

来进程的主线程之上添加一个线程,该线程属于远程进程,却又是我们

的代码,所以可以在远程进程中实现我们的代码。

DLL注入利用了这个特点,目的是在运行的进程强制调用为WINAPI函数

LoadLibrary()载入我们自己编写的dll,dll会被插入进程的内存空间中,由

于dll第一次被载入地址空间,会调用其自身给DllMain函数,以初始化,利

用这个特性,我们可以做到,在目标进程中调用我们的代码。

#include "stdafx.h"
#include<Windows.h>
#include<iostream>

using namespace std;
DWORD WINAPI myfunc(PVOID);
/*PROCESS_ALL_ACCESS  全部进程权限   PVOID VirtualAllocEx(handle,pvoid,size_y,dword,dword)在指定进程分配地址。
		_CREATE_PROCESS 创建进程的权限 注意在本函数内创建的函数地址,作为远程线程传入地址,结果不可知!!!违规访问。
		_CREATE_THREAD 创建线程的权限
		_DUP_HANDLE  
		_VM_OPERATION 操作进程内存空间
		_VM_READ 读取进程内存空间
		_VM_WRITE写入进程内存空间 
		*/
//bin...进程句柄是否可被继承TRUE / FALSE
//dwprocessid被打开的进程
int _tmain(int argc, _TCHAR* getid[])
{
	if(getid[1] == NULL)
	{
		cout<<"make sure you send the right pid or dll!!!"<<endl;
		return 0;
	}

	DWORD pid = atoi(getid[1]);  //权限+句柄继承性+pid
	HANDLE victim = OpenProcess(
		PROCESS_CREATE_THREAD|
		PROCESS_VM_OPERATION|
		PROCESS_VM_WRITE,
		FALSE,
		pid);
	if(victim == NULL)
	{
		cout<<"cant open the process!!!"<<endl;
		return 0;
	}
	else
		cout<<"open successed!!!"<<endl;
	HANDLE MYTHREAD;
	int prama;
	PTHREAD_START_ROUTINE pfnthread = (PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryA");
	//virtualfreeex可以释放内存。第一个进程句柄,表示在哪个进程句柄中执行该操作。
	/* BOOL WriteProcessMemory(handle,pvoid,lpcvoid,size_t,size_T*)读写目标进程空间地址,目标句柄,进程中的地址,本地内存地址,传输的弟子结束。
	实际传输字节数*/
	char buf[50] = {0};
	cout<<"entel the dll name"<<endl;
	gets(buf); //buf保存dll路径
	printf("\ntry %s \n",buf);
	int cnt = 0;
	while(buf[cnt] != '\0')
	{
		cnt++;
	}
	cnt++;
	cout<<cnt<<endl;
	SIZE_T words;
	PVOID pos = VirtualAllocEx(victim,NULL,0x1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);//立即申请,即可读,也可写。
		if(pos != NULL)
		cout<<"success alloc"<<endl;
	else
	{
		cout<<"failed ALLoc"<<endl;
			return 0;
	}
	BOOL state = WriteProcessMemory(victim,pos,buf,cnt*sizeof(char),&words);
	cout<<words<<endl;
	if(state == TRUE)
		cout<<"success write"<<endl;
	else
	{
		cout<<"failed write"<<endl;
			return 0;
	}
	MYTHREAD = CreateRemoteThread(victim,NULL,0,pfnthread,pos,0,NULL); //传入正确的loadlibray函数,并且传入正确的vitrual创建的
	//内存
	if(MYTHREAD != NULL)
	{
		cout<<"thread created!!"<<endl; //注意直接加载函数时,需要确定位置,编译链接时有宏,否则分清楚unicode和ansc版本!!!1
	}
	else
	{
		cout<<"thread failed!!"<<endl;
		return 0;
	}


	return 0;
}

本例在VS 2010编译器,ascii字符下编译通过,供参考。

重点在于,虚拟地址的分配,必须在对象进程中开辟内

存,否则访问地址结果将是不可知的!!!!!

测试用的是逆向工程核心原理中的dll,在后台下载一个index.html

注入目标

开始注入

成功下载index.html

 


版权声明:本文为jazrynwong原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。