使用LoadLibrary加载某个DLL时,该DLL中的DllMain函数就会被调用执行。
1.创建远程线程(CreateRemoteThread)
使用InjectDll.exe在notepad.exe中注入Myhack.dll(winxp提权后测试成功)
// 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.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
}
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows下AppInit_DLLs的值改为myhack2.dll的路径。LoadAppInit_DLLs的值改为1.
重启计算机。然后打开notepad.exe
// 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)