Dll:
// dllmain.cpp : Defines the entry point for the DLL application. #include "pch.h" #include <sstream> std::wstringstream wss; std::wstring str; char buf[256] = ""; DWORD rlen = 0; extern "C" DWORD fun(LPVOID) { MessageBox(NULL, L"This is Fun", L" ", MB_OK); return 0; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { void* p = fun; wss << p; wss >> str; LPCWSTR result = str.c_str(); HANDLE hPipe = CreateNamedPipe( TEXT("\\.\Pipe\mypipe"), //管道名 PIPE_ACCESS_DUPLEX, //管道类型 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, //管道参数 PIPE_UNLIMITED_INSTANCES, //管道能创建的最大实例数量 0, //输出缓冲区长度 0表示默认 0, //输入缓冲区长度 0表示默认 NMPWAIT_WAIT_FOREVER, //超时时间 NULL); //指定一个SECURITY_ATTRIBUTES结构,或者传递零值. ConnectNamedPipe(hPipe, NULL); DWORD wlen = 0; MessageBox(NULL, result, L" ", MB_OK); WriteFile(hPipe, &p, sizeof(p), &wlen, 0); //向客户端发送内容 CloseHandle(hPipe);//关闭管道 } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
main.cpp
#include <Windows.h> #include <stdio.h> #include <iostream> #include <TlHelp32.h> #include <tchar.h> #pragma warning(disable:4996) DWORD wlen = 0; WCHAR rbuf[256] = L" ";
bool Inject(DWORD pId, const char* dllName) { HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, pId); if (h) { LPVOID LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); LPVOID dereercomp = VirtualAllocEx(h, NULL, strlen(dllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); WriteProcessMemory(h, dereercomp, dllName, strlen(dllName), NULL); HANDLE asdc = CreateRemoteThread(h, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, dereercomp, 0, NULL); int err = GetLastError(); if (asdc == NULL) { printf("Error: the remote thread could not be created. "); } else { printf("Success: the remote thread was successfully created. "); } BOOL bRet = WaitNamedPipe(TEXT("\\.\Pipe\mypipe"), NMPWAIT_WAIT_FOREVER); if (!bRet) { printf("connect the namedPipe failed! "); return 0; } HANDLE hPipe = CreateFile( //管道属于一种特殊的文件 TEXT("\\.\Pipe\mypipe"), //创建的文件名 GENERIC_READ | GENERIC_WRITE, //文件模式 0, //是否共享 NULL, //指向一个SECURITY_ATTRIBUTES结构的指针 OPEN_EXISTING, //创建参数 FILE_ATTRIBUTE_NORMAL, //文件属性(隐藏,只读)NORMAL为默认属性 NULL); //模板创建文件的句柄 if (INVALID_HANDLE_VALUE == hPipe) { printf("open the exit pipe failed! "); } else { while (true) { DWORD rlen = 0; LONG_PTR addr; ReadFile(hPipe, &addr, sizeof(PVOID), &rlen, 0); //接受服务发送过来的内容 printf("From Server: data = 0x%p, size = %d ", addr, rlen); CreateRemoteThread(h, 0, 0, (LPTHREAD_START_ROUTINE)addr, NULL, 0, 0); Sleep(1000); } } CloseHandle(hPipe);//关闭管道 WaitForSingleObject(asdc, INFINITE); VirtualFreeEx(h, dereercomp, strlen(dllName), MEM_RELEASE); CloseHandle(asdc); CloseHandle(h); return true; } return false; } int _tmain(int argc, _TCHAR* argv[]) { const char* buffer = "D:\Dll.dll"; int procID = 4524; //任意app的PID Inject(procID, buffer); getchar(); return 0; }
注意:如果需要uninstall dll的话,需要调用FreeLibraryAndExitThread,用法类似于:
HINSTANCE hThisInst; BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { hThisInst = hinstDLL; ... return 1; } void __stdcall InlineUnhook() { FreeLibraryAndExitThread(hThisInst, 0); }
在需要uninstall的时候,获取dll的加载地址,再调用InlineUnhook函数。
参考: Freelibrary...