#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
#include <stdlib.h>
DWORD RVAtoFileOffset(DWORD RVA, PIMAGE_NT_HEADERS pNtHeader, PIMAGE_SECTION_HEADER pSec);
LPVOID GetProcAddrByName(LPVOID lpRemoteLibraryBuffer, const char* funcName, LPVOID pBuf);
int main() {
//先定义需要注入的dll与目标进程的名字
char Dllname[MAX_PATH] = "D:\\C#project\\反射DLL\\x64\\Debug\\反射DLL.dll";
//查找获得目标进程的id
DWORD dwPid = 41424;
//与普通dll注入一样,首先要做的是获取句柄
HANDLE hProc = NULL;
// 打开DLL文件
HANDLE hFile = CreateFileA(Dllname, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("\n[-] CreateFileA failed.");
return FALSE;
}
// 获取DLL的大小
DWORD FileSize = GetFileSize(hFile, NULL);
LPDWORD SizeToRead = 0;
// 创建本地堆空间
LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, FileSize);
if (!lpBuffer) {
printf("\n[-] 创建本地堆空间失败");
}
// 读取文件内容到本地堆空间
DWORD dwBytesRead = 0;
int result = ReadFile(hFile, lpBuffer, FileSize, &dwBytesRead, NULL);
if (result == 0)
{
printf("\n[-] 文件读取失败");
return FALSE;
}
// 对接下来开辟的空间进行计算大小
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBuffer;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((BYTE*)lpBuffer + pDosHeader->e_lfanew);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((LPBYTE)pNtHeader + sizeof(IMAGE_NT_HEADERS));
DWORD ImageSize = pNtHeader->OptionalHeader.SizeOfImage;
// 打开目标进程,获得其句柄
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (!hProc)
{
DWORD dwError = GetLastError();
printf("\n[-] OpenProcess failed. Error code: %d\n", dwError);
return FALSE;
}
// 申请一块保护属性为PAGE_EXECUTE_READWRITE的内存空间
LPVOID lpRemoteLibraryBuffer = VirtualAllocEx(hProc, NULL, ImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpRemoteLibraryBuffer == NULL) {
printf("\n[-] 内存分配失败, 错误代码: %d", GetLastError());
return FALSE;
}
//将dll文件写入进去
if (!WriteProcessMemory(hProc, lpRemoteLibraryBuffer, lpBuffer, FileSize, NULL)) {
printf("\n[-] 写入失败,错误代码: %d", GetLastError());
return FALSE;
}
// 假设 ReflectLoader 是目标函数名
const char* ReflectiveLoaderName = "ReflectiveLoader";
// 获取 ReflectLoader 在目标进程内存中的地址
LPVOID pReflectLoader = GetProcAddrByName(lpRemoteLibraryBuffer, ReflectiveLoaderName, lpBuffer);
if (!pReflectLoader) {
printf("[-] Failed to find ReflectLoader.\n");
VirtualFreeEx(hProc, lpRemoteLibraryBuffer, 0, MEM_RELEASE);
return FALSE;
}
// 调用 ReflectLoader 函数
HANDLE hThread = CreateRemoteThread(hProc,NULL,0, (LPTHREAD_START_ROUTINE)pReflectLoader, NULL,0,NULL);
if (!hThread) {
printf("\n[-] CreateRemoteThread failed: %d", GetLastError());
VirtualFreeEx(hProc, lpRemoteLibraryBuffer, 0, MEM_RELEASE);
return FALSE;
}
printf("\n[+] ReflectLoader executed successfully.");
// 等待线程执行完成
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
VirtualFreeEx(hProc, lpRemoteLibraryBuffer, 0, MEM_RELEASE);
return TRUE;
}
//作用:RVA->文件偏移地址
//公式:文件偏移 = 节区文件起始地址(PointerToRawData) + (RVA - 节区虚拟起始地址(VirtualAddress))
DWORD RVAtoFileOffset(DWORD RVA, PIMAGE_NT_HEADERS pNtHeader, PIMAGE_SECTION_HEADER pSec) {
// 遍历节区表
DWORD SectionNumber = pNtHeader->FileHeader.NumberOfSections;
for (int i = 0; i < SectionNumber; i++) {
// 检查RVA是否在当前节区的范围内
if (RVA >= pSec[i].VirtualAddress && RVA < pSec[i].VirtualAddress + pSec[i].SizeOfRawData) {
// 转换RVA到文件偏移地址
return pSec[i].PointerToRawData + (RVA - pSec[i].VirtualAddress);
}
}
// 如果未找到对应的节区,返回无效值
return 0xFFFFFFFF;
}
//作用:该函数通过导出表获得指定函数的地址
LPVOID GetProcAddrByName(LPVOID lpRemoteLibraryBuffer, const char* funcName, LPVOID pBuf){
//定位一些相关文件头
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((BYTE*)pBuf + pDosHeader->e_lfanew);
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((LPBYTE)pNtHeader + sizeof(IMAGE_NT_HEADERS));
//获取导出表地址及大小,注意这里是RVA
DWORD exportDirRVA = pNtHeader->OptionalHeader.DataDirectory[0].VirtualAddress;
DWORD exportDirSize = pNtHeader->OptionalHeader.DataDirectory[0].Size;
//定位导出表
//得到的偏移地址是RVA,但是咱们的文件现在只是磁盘文件,所以需要转换为文件偏移
DWORD exportDirFileOffset = RVAtoFileOffset((DWORD)exportDirRVA, pNtHeader, pSec);
//转换之后RVA就变成了文件偏移,然后再定位
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)pBuf + exportDirFileOffset);
//解析导出表,这里同理都是RVA
DWORD pRNames = pExportDir->AddressOfNames;
DWORD pFNames = RVAtoFileOffset(pRNames, pNtHeader, pSec);
DWORD* pNames = (DWORD*)((PBYTE)pBuf + pFNames);
DWORD pRFunctions = pExportDir->AddressOfFunctions;
DWORD pFFunctions = RVAtoFileOffset(pRFunctions, pNtHeader, pSec);
DWORD* pFunctions = (DWORD*)((PBYTE)pBuf + pFFunctions);
WORD pRNameOrdinals = pExportDir->AddressOfNameOrdinals;
WORD pFNameOrdinals = RVAtoFileOffset(pRNameOrdinals, pNtHeader, pSec);
WORD* pNameOrdinals = (WORD*)((PBYTE)pBuf + pFFunctions);
// 遍历查找目标函数
DWORD funcRVA = 0;
for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {
DWORD functionNameRVA = pNames[i];
DWORD functionNameFileOffset = RVAtoFileOffset(functionNameRVA, pNtHeader, pSec);
const char* pName = (char*)((PBYTE)pBuf + functionNameFileOffset);
if (strcmp(pName, funcName) == 0) {
funcRVA = pFunctions[i];
break;
}
}
if (funcRVA == 0) {
printf("\n[-] Function %s not found.", funcName);
return NULL;
}
DWORD fileOffset = RVAtoFileOffset(funcRVA, pNtHeader, pSec);;
DWORD* pfileOffset = (DWORD*)((PBYTE)pBuf + fileOffset);
if (fileOffset == 0) {
printf("\n[-] Failed to convert RVA to file offset.");
return NULL;
}
// 返回函数的地址
LPVOID remoteFuncAddr = (LPBYTE)lpRemoteLibraryBuffer + fileOffset;
return remoteFuncAddr;
}严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 LNK2019 无法解析的外部符号 __imp___acrt_iob_func,函数 printf 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\源.obj 1
错误 LNK2019 无法解析的外部符号 __imp___stdio_common_vfprintf,函数 _vfprintf_l 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\源.obj 1
错误 LNK2019 无法解析的外部符号 strcmp,函数 "void * __cdecl GetProcAddrByName(void *,char const *,void *)" (?GetProcAddrByName@@YAPEAXPEAXPEBD0@Z) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\源.obj 1
错误 LNK2019 无法解析的外部符号 _CrtDbgReport,函数 _CRT_RTC_INIT 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(init.obj) 1
错误 LNK2019 无法解析的外部符号 _CrtDbgReportW,函数 _CRT_RTC_INITW 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(init.obj) 1
错误 LNK2019 无法解析的外部符号 strcpy_s,函数 "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPEAXPEBD@Z) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(error.obj) 1
错误 LNK2019 无法解析的外部符号 strcat_s,函数 "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPEAXPEBD@Z) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(error.obj) 1
错误 LNK2019 无法解析的外部符号 __stdio_common_vsprintf_s,函数 _vsprintf_s_l 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(error.obj) 1
错误 LNK2001 无法解析的外部符号 __C_specific_handler_noexcept Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(error.obj) 1
错误 LNK2019 无法解析的外部符号 _wmakepath_s,函数 "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(pdblkup.obj) 1
错误 LNK2019 无法解析的外部符号 _wsplitpath_s,函数 "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(pdblkup.obj) 1
错误 LNK2019 无法解析的外部符号 wcscpy_s,函数 "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(pdblkup.obj) 1
错误 LNK2019 无法解析的外部符号 __vcrt_GetModuleFileNameW,函数 "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE__@@XZ) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(pdblkup.obj) 1
错误 LNK2019 无法解析的外部符号 __vcrt_GetModuleHandleW,函数 "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE__@@XZ) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(pdblkup.obj) 1
错误 LNK2019 无法解析的外部符号 __vcrt_LoadLibraryExW,函数 "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE__@@XZ) 中引用了该符号 Project5 C:\Users\17116\source\repos\Project5\Project5\MSVCRTD.lib(pdblkup.obj) 1
错误 LNK1120 15 个无法解析的外部命令 Project5 C:\Users\17116\source\repos\Project5\x64\Debug\Project5.exe 1
最新发布