三种方法:具体详见《逆向工程核心原理》。

1、创建远程线程CreateRemoteThread()

2、使用注册表AppInit_DLLs

3、消息钩取SetWindowsHookEx()

一、远程线程(注意将szPATH数组建在函数中会出现栈溢出,需要建立全局变量)

#include "windows.h"
#include "tchar.h" #pragma comment(lib, "urlmon.lib") HMODULE g_hMod = NULL;
TCHAR szPath[MAX_PATH] = { , };
DWORD WINAPI ThreadProc(LPVOID lParam) { if (!GetModuleFileName(g_hMod, szPath, MAX_PATH))
return FALSE; TCHAR *p = _tcsrchr(szPath, '\\');
if (!p)
return FALSE; _tcscpy_s(p + , MAX_PATH, L"index.html"); URLDownloadToFile(NULL, L"http://www.xidian.edu.cn", szPath, , NULL); return ;
} BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
HANDLE hThread = NULL; g_hMod = (HMODULE)hinstDLL; switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
hThread = CreateThread(NULL, , ThreadProc, NULL, , NULL);
CloseHandle(hThread);
break;
} return TRUE;
}

myhack.cpp

#include "windows.h"
#include "tchar.h" 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 = ;
tp.Privileges[].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[].Attributes = ; // 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 InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
HANDLE hProcess = NULL, hThread = NULL;
HMODULE hMod = NULL;
LPVOID pRemoteBuf = NULL;
DWORD dwBufSize = (DWORD)(lstrlen(szDllPath) + ) * sizeof(TCHAR);
LPTHREAD_START_ROUTINE pThreadProc; // 获得dwPID进程ID对应的目标进程句柄
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
return FALSE; // 在目标进程地址空间中为DLL路径名szDllPath开辟一块存储空间,将szDllPath路径字符串写入该空间
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL); // 获取当前进程地址空间中LoadLibraryW()函数的地址,该函数由kernel32.dll导入
hMod = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW"); // 在目标进程中运行线程,该线程执行LoadLibraryW()函数并传入被注入DLL路径作为参数
hThread = CreateRemoteThread(hProcess, NULL, , pThreadProc, pRemoteBuf, , NULL);
WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread);
CloseHandle(hProcess); return TRUE;
} int _tmain(int argc, TCHAR *argv[])
{
if (argc != ) {
_tprintf(L"USAGE : %s <pid> <dll_path>\n", argv[]);
return ;
}
if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
return ; // inject dll
if (InjectDll((DWORD)_tstol(argv[]), argv[]))
_tprintf(L"InjectDll(\"%s\") success.\n", argv[]);
else
_tprintf(L"InjectDll(\"%s\") failed.\n", argv[]); return ;
}

inject.cpp

卸载:

// EjectDll.exe

#include "windows.h"
#include "tlhelp32.h"
#include "tchar.h" //由进程名找到进程id号
DWORD FindProcessID(LPCTSTR szProcessName) {
DWORD dwPID = 0xFFFFFFFF;
HANDLE hSnapShot = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe; // 获得系统进程的快照
pe.dwSize = sizeof(PROCESSENTRY32);
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL); Process32First(hSnapShot, &pe);
do {
if (!_tcsicmp(szProcessName, (LPCTSTR)pe.szExeFile)) {
dwPID = pe.th32ProcessID;
break;
}
} while (Process32Next(hSnapShot, &pe)); CloseHandle(hSnapShot);
return dwPID;
} BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid; if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE; if (!LookupPrivilegeValue(NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
return FALSE; tp.PrivilegeCount = ;
tp.Privileges[].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[].Attributes = ; // Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(hToken, FALSE, &tp,
sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
return FALSE; if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
return FALSE; return TRUE;
} BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName) {
BOOL bMore = FALSE, bFound = FALSE;
HANDLE hSnapshot, hProcess, hThread;
HMODULE hModule = NULL;
MODULEENTRY32 me = { sizeof(me) };
LPTHREAD_START_ROUTINE pThreadProc; // dwPID = notepad进程的id号
// 使用TH32CS_SNAPMODULE参数,获得加载到notepad进程地址空间的DLL信息
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); bMore = Module32First(hSnapshot, &me);
for (; bMore; bMore = Module32Next(hSnapshot, &me)) {
if (!_tcsicmp((LPCTSTR)me.szModule, szDllName) ||
!_tcsicmp((LPCTSTR)me.szExePath, szDllName)) {
bFound = TRUE;
break;
}
} if (!bFound) {
CloseHandle(hSnapshot);
return FALSE;
} if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
return FALSE; hModule = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
hThread = CreateRemoteThread(hProcess, NULL, ,
pThreadProc, me.modBaseAddr,
, NULL);
WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread);
CloseHandle(hProcess);
CloseHandle(hSnapshot); return TRUE;
} int _tmain(int argc, TCHAR* argv[]) {
DWORD dwPID = 0xFFFFFFFF; dwPID = FindProcessID(L"notepad.exe");
if (dwPID == 0xFFFFFFFF) //没有找到notepad进程
return ; // 更改特权
if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
return ; // 卸载DLL
if (EjectDll(dwPID, L"myhack.dll"))
_tprintf(L"EjectDll(%d, \"%s\") success!!!\n", dwPID, L"myhack.dll");
else
_tprintf(L"EjectDll(%d, \"%s\") failed!!!\n", dwPID, L"myhack.dll"); return ;
}

eject.cpp

二、使用注册表(调用进程执行程序)

修改AppInit_DLLs和LoadAppInit_DLLs,路径名使用单右斜杠

#include "windows.h"
#include "tchar.h" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
TCHAR szCmd[MAX_PATH] = { , };
TCHAR szPath[MAX_PATH] = { , };
TCHAR *p = NULL;
STARTUPINFO si = { , };
PROCESS_INFORMATION pi = { , }; si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; switch (fdwReason) {
case DLL_PROCESS_ATTACH:
//获得当前DLL被装载到的进程的可执行文件的路径到szPath中
if (!GetModuleFileName(NULL, szPath, MAX_PATH))
break;
if (!(p = _tcsrchr(szPath, '\\')))
break;
if (lstrcmpi(p + , _T("notepad.exe")))
break;
//当前DLL被加载到的进程的可执行文件为notepad.exe,调用IE访问www.xidian.edu.cn
wsprintf(szCmd, _T("%s %s"), _T("C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe"), _T("http://www.xidian.edu.cn"));
if (!CreateProcess(NULL, (LPTSTR)(LPCTSTR)szCmd,
NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
break;
if (pi.hProcess != NULL)
CloseHandle(pi.hProcess);
break;
}
return TRUE;
}

myhack2.cpp

三、消息钩取

详见12.24逆向工程上机作业

dll注入及卸载实践的更多相关文章

  1. 《逆向工程核心原理》——DLL注入与卸载

    利用CreateRemoteThread #include <iostream> #include <tchar.h> #include <Windows.h> # ...

  2. DLL注入实践

    Windows系统大量使用dll作为组件复用,应用程序也会通过dll实现功能模块的拆分.DLL注入技术是向一个正在运行的进程插入自有DLL的过程. Window下的代码注入 常见的Windows代码注 ...

  3. DLL远程注入与卸载

    以下提供两个函数,分别用于向其它进程注入和卸载指定DLL模块.支持Unicode编码. #include <windows.h>#include <tchar.h>#inclu ...

  4. DLL远程注入及卸载实现

    实现win7 64位系统下dll的远程注入及卸载,尚未再其他系统测试 源码地址:https://github.com/ndhisrfzs/InjectDll

  5. DLL注入

    最近的项目涉及了软件破解方面的知识,记录一下. 将dll注入另一个进程. // Inject.cpp : Defines the exported functions for the DLL appl ...

  6. [转]Dll注入经典方法完整版

    Pnig0s1992:算是复习了,最经典的教科书式的Dll注入. 总结一下基本的注入过程,分注入和卸载 注入Dll: 1,OpenProcess获得要注入进程的句柄 2,VirtualAllocEx在 ...

  7. 第22章 DLL注入和API拦截(2)

    22.4 使用远程线程来注入DLL 22.4.1 概述 (1)远程线程注入是指一个进程在另一个进程中创建线程,然后载入我们编写的DLL,并执行该DLL代码的技术.其基本思路是通过CreateRemot ...

  8. 第22章 DLL注入和API拦截(1)

    22.1 注入的一个例子(跨进程子类化窗口) ①子类化窗口可以改变窗口的行为,让发往该窗口的消息重新发到我们指定的过程来处理.但这种行为只能在本进程中(如A),对于从一个进程(如B)去子类化另一个进程 ...

  9. c++实现dll注入其它进程

    DLL注入技术才具有强大的功能和使用性,同时简单易用,因为DLL中可以实现复杂的功能和很多的技术. 技术要点: 1.宿主进程调用LoadLibrary,就可以完成DLL的远程注入.可以通过Create ...

随机推荐

  1. EF-局部更新

    // ////1 public Task ReservedQuantity(long productId, long skuId, int reservedQuantity, long userId) ...

  2. poj3189二分图多重匹配

    题意:有一些牛和牛棚(有容量),每头牛对牛棚有喜好程度,要求每头牛都有一个棚子的情况下,找最小的喜好程度之差 题解:题意是真的恶心,wa了好久才发现没读懂,一直以为输入 的是排名,其实是牛棚标号,从1 ...

  3. The RK3066/RK30SDK Android 4.2 audio codec has a bug!

    在文件kernel/sound/soc/soc-core.c中,函数soc_bind_dai_link引入了一个新定义的宏CODEC_NAME_CMP,这个新玩意导致了后面的strcpy(p_code ...

  4. SQLyog中的计算适合的数据类型

    可能使用的数据库工作比较杂吧(机器上有toad.PLSQL Developer.Navicat.SQLyog等).并非是觉得那种都不好用,而是觉得有适合大部分需求的,但也有工具在某一方面特别方便的. ...

  5. linux下配置cvs服务器以及cvs常用命令

    .查看系统是否安装有cvs #cat /etc/services | grep cvspserver 看看是否有: cvspserver /tcp #CVS client/server operati ...

  6. nginx配置允许指定域名下所有二级域名跨域请求

    核心原理是根据请求域名匹配是否是某域名的二级域名判断是否添加允许跨越头. #畅游www server { listen 8015; server_name test-tl.changyou.com; ...

  7. 机器学习敲门砖:任何人都能看懂的TensorFlow介绍

    机器学习敲门砖:任何人都能看懂的TensorFlow介绍 http://www.jiqizhixin.com/article/1440

  8. Android 禁止屏幕旋转、避免转屏时重启Activity

    一.禁止屏幕旋转 在AndroidManifest.xml的每一个需要禁止转向的Activity配置中加入android:screenOrientation属性: 可选项: landscape = 横 ...

  9. Brackets (区间DP)

    个人心得:今天就做了这些区间DP,这一题开始想用最长子序列那些套路的,后面发现不满足无后效性的问题,即(,)的配对 对结果有一定的影响,后面想着就用上一题的思想就慢慢的从小一步一步递增,后面想着越来越 ...

  10. LeetCode K-diff Pairs in an Array

    原题链接在这里:https://leetcode.com/problems/k-diff-pairs-in-an-array/#/description 题目: Given an array of i ...