动态链接库基础与远程线程注入

目录

动态链接库的基本调用

 MessageBox不直接调用

远程线程注入

DLL写法


动态链接库的基本调用

#include<stdio.h>
#include<Windows.h>
#include<Psapi.h>
//有头文件的话可以直接调用头文件
//没有的话就用函数指针
typedef int (*fnrkadd)(int numberA, int numberB);

int main()
{
	//这个函数是有操作系统提供给我们的SDK
	//SDK软件开发工具包
	//API 开放的函数接口 windows给我们写好的代码
	//动态链接库里提供的
	//系统调用
	//开发过程中dll放在代码目录下 编好的话放在exe目录下
	MessageBoxA(NULL,"Msg","Msg",MB_OK);

	HMODULE hDll = LoadLibraryA("Dll2.dll");//(显示)加载动态链接库 返回动态链接库的句柄也可以说是动态链接库的加载基址
	//参数是动态链接库的名字或者说路径
	fnrkadd func = (fnrkadd)GetProcAddress(hDll,"rkadd");//返回值返回函数类型
	int nRes = func(1, 2);
	printf("%d\r\n",nRes);

	system("pause");
	return 0;
}

 MessageBox不直接调用

#include<stdio.h>
#include<Windows.h>
#include<Psapi.h>
//有头文件的话可以直接调用头文件
//没有的话就用函数指针
typedef int (*fnrkadd)(int numberA, int numberB);
typedef int(WINAPI *FnMessageBoxA)(
	_In_opt_ HWND hWnd,
	_In_opt_ LPCSTR lpText,
	_In_opt_ LPCSTR lpCaption,
	_In_ UINT uType);

int main()
{
	//这个函数是有操作系统提供给我们的SDK
	//SDK软件开发工具包
	//API 开放的函数接口 windows给我们写好的代码
	//动态链接库里提供的
	//系统调用
	//开发过程中dll放在代码目录下 编好的话放在exe目录下
	/*MessageBoxA(NULL, "Msg", "Msg", MB_OK);

	HMODULE hDll = LoadLibraryA("Dll2.dll");//(显示)加载动态链接库 返回动态链接库的句柄也可以说是动态链接库的加载基址
	//参数是动态链接库的名字或者说路径
	fnrkadd func = (fnrkadd)GetProcAddress(hDll,"rkadd");//返回值返回函数类型
	int nRes = func(1, 2);
	printf("%d\r\n",nRes);*/
	

	HMODULE hUser32 = LoadLibraryA("user32.dll");
	
	FnMessageBoxA Msg= (FnMessageBoxA)GetProcAddress(hUser32, "MessageBoxA");
	Msg(NULL,"Msg","Msg",MB_OK);

	printf("Msg:%X\r\n",Msg);
	printf("MessageBoxA:%X\r\n", MessageBoxA);

	system("pause");
	return 0;
}

 

远程线程注入

#include<stdio.h>
#include<Windows.h>

/*
typedef DWORD ThreadCallBack(
	LPVOID lpThreadParameter
	);
//------------------------------------两者几乎一样 几乎是可以通用的
//-----------------------------------完全可以把LoadLibrary当成CreateThread的回调函数来使用
//四字节的整数(x86)
HMODULE
WINAPI
LoadLibraryW(
	_In_ LPCWSTR lpLibFileName
);
*/


BOOL Inject(DWORD dwProcessID, const WCHAR* szPath)//进程ID  路径
{
	//LoadLibrary
	//CreateRemoteThread
	//1.打开目标进程获取句柄
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwProcessID);
	//2.在目标进程体内申请空间
	//VirtualAlloc() 在本进程中申请空间 Ex是在目标进程内申请空间 区别为第一个参数是否为进程句柄
	LPVOID lpAddress = VirtualAllocEx(hProcess,NULL,0x100,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);//不指定地址随机分配
	//函数返回一个地址空间(一个指针)
	//3.写入DLL路径
	SIZE_T sWriteLength = 0;
	BOOL bRet = WriteProcessMemory(hProcess, lpAddress, szPath,((wcslen(szPath)+1)*2),&sWriteLength);
	if (bRet == FALSE)
	{
		MessageBoxA(NULL, "WriteProcessMemory Failed!", "Error", MB_OK);
		return FALSE;
	}
	/*把路径写入目标体内再调用远程线程创建的时候调用LoadLibrary就可以在目标体内的内存内找到字符串了
	写到自己的空间内是没有用的 因为有一个内存隔离不能互相搞 所以需要写到目标的体内*/
	//4.创建远程线程,执行LoadLibrary回调
	HANDLE hThread = CreateRemoteThread(hProcess,NULL,NULL,(LPTHREAD_START_ROUTINE)LoadLibraryW, lpAddress,NULL,NULL);
	//5.等待远程线程执行结束(LoadLibrary返回了)
	WaitForSingleObject(hThread,INFINITE);
	//6.释放空间
	VirtualFreeEx(hProcess,lpAddress,0,MEM_RELEASE);
	//7.释放句柄
	CloseHandle(hProcess);
	CloseHandle(hThread);
	//8.返回结果
	return TRUE;
}

int main()
{
	Inject(10648, L"C:\\Users\\wakappxc\\Desktop\\Dll2.dll");
	system("pause");
	return 0;
}

DLL写法

 dllmain.cpp

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"

//DllMain 动态链接库的入口
//真正的API的东西不是在这里面处理的而是一种导出函数的东西
//PE文件(windows可执行文件的一个格式 exe dll sys)
//PE文件中的导出表
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH://附加到进程的时候
        MessageBox(NULL,L"Msg",L"Msg",MB_OK);
        break;
    case DLL_THREAD_ATTACH://附加到线程的时候
        break;
    case DLL_THREAD_DETACH://线程剥离的时候
        break;
    case DLL_PROCESS_DETACH://进程剥离的时候
        break;
    }
    return TRUE;
}

myfunc.h

#pragma once
//名称粉碎机制
//如果不声明extern "C"的导出方式的情况下,在导出表我们看到的名字就是一个碎片化的一个东西
//这个时候就没有办法去利用了
extern "C" __declspec(dllexport) int rkadd(int numberA, int numberB);

myfunc.cpp

 

#include "pch.h"
#include "myfunc.h"

int rkadd(int numberA, int numberB)
{
    return numberA + numberB;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 示例代码:#include <windows.h> #include <stdio.h> #include <tlhelp32.h> // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName); int main(int argc, char *argv[]) { printf("远程线程注入dll演示程序\n"); if (argc == 3) { DWORD dwPID = atoi(argv[1]); char *szDLLName = argv[2]; InjectDLL(dwPID, szDLLName); } else { printf("用法:InjectDLL.exe <PID> <DLLName>\n"); } return 0; } // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName) { HANDLE hProcess, hThread; LPVOID lpBaseAddress; LPTHREAD_START_ROUTINE lpStartAddress; DWORD dwSize, dwThreadId; char szPath[256]; char szBuffer[1024]; // 打开进程 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); if (hProcess == NULL) { printf("OpenProcess() Error: %d\n", GetLastError()); return FALSE; } // 获取DLL的完整路径 GetFullPathName(szDLLName, 256, szPath, NULL); // 在进程中申请虚拟内存 dwSize = strlen(szPath) + 1; lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if (lpBaseAddress == NULL) { printf("VirtualAllocEx() Error: %d\n", GetLastError()); return FALSE; } // 将DLL路径写入到虚拟内存 int nBytesWritten; WriteProcessMemory(hProcess, lpBaseAddress, szPath, dwSize, &nBytesWritten); if (nBytesWritten != dwSize) { printf("WriteProcessMemory() Error: %d\n", GetLastError()); return FALSE; } // 加载Kernel32.dll HMODULE hKernel32 = GetModuleHandle("Kernel32"); if (hKernel32 == NULL) { printf("GetModuleHandle() Error: %d\n", GetLastError()); return FALSE; } // 获取LoadLibraryA函数地址 lpStartAddress = GetProcAddress(hKernel32, "LoadLibraryA"); if (lpStartAddress == NULL) { printf("GetProcAddress() Error: %d\n", GetLastError()); return FALSE; } // 创建远程线程 hThread = CreateRemoteThread(hProcess, NULL, 0, lpStartAddress, lpBaseAddress, 0, &dwThreadId); if (hThread == NULL) { printf("CreateRemoteThread() Error: %d\n", GetLastError()); return FALSE; } // 等待远程线程结束 WaitForSingleObject(hThread, INFINITE); // 读取线程退出码 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode == 0) { printf("LoadLibrary() Error: %d\n", GetLastError()); return FALSE; } // 关闭句柄 CloseHandle(hProcess); CloseHandle(hThread); return TRUE; }我不能帮助你编写代码,但是我可以提供一些参考资料,帮助你编写远程线程注入dll代码。 ### 回答2: 远程线程注入DLL是一种技术,用于在目标进程中注入自定义的动态链接库(DLL)并执行其中的代码。以下是一个使用C语言编写的远程线程注入DLL的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { // 目标进程的进程ID DWORD pid = 1234; // 加载要注入的DLL路径 char dllPath[] = "C:\\path_to_dll\\mydll.dll"; // 获取目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (hProcess == NULL) { printf("无法打开目标进程"); return -1; } // 在目标进程中为DLL路径分配内存 LPVOID dllPathAddr = VirtualAllocEx(hProcess, NULL, sizeof(dllPath), MEM_COMMIT, PAGE_READWRITE); if (dllPathAddr == NULL) { printf("无法在目标进程中分配内存"); CloseHandle(hProcess); return -1; } // 在目标进程中写入DLL路径 if (!WriteProcessMemory(hProcess, dllPathAddr, dllPath, sizeof(dllPath), NULL)) { printf("无法写入DLL路径到目标进程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 获取Kernel32.dll中LoadLibrary函数的地址 HMODULE kernel32 = GetModuleHandle("kernel32.dll"); FARPROC loadLibrary = GetProcAddress(kernel32, "LoadLibraryA"); // 创建远程线程在目标进程中执行LoadLibrary函数,将DLL路径作为参数 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibrary, dllPathAddr, 0, NULL); if (hThread == NULL) { printf("无法在目标进程中创建远程线程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 等待远程线程执行结束 WaitForSingleObject(hThread, INFINITE); // 清理资源 VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess); printf("远程线程注入DLL成功"); return 0; } ``` 这段代码首先通过`OpenProcess`函数打开目标进程,然后使用`VirtualAllocEx`在目标进程中为DLL路径分配内存,并使用`WriteProcessMemory`将DLL路径写入目标进程内存。接着,使用`GetModuleHandle`和`GetProcAddress`获取`LoadLibrary`函数的地址,然后使用`CreateRemoteThread`在目标进程中创建一个远程线程,让其执行`LoadLibrary`函数,将DLL路径作为参数传递给它。最后,使用`WaitForSingleObject`等待远程线程执行完毕,并释放之前分配的资源。 ### 回答3: 使用C语言编写远程线程注入DLL的代码可以通过以下步骤实现: 1. 首先,需要创建一个目标进程的句柄。可以使用`OpenProcess`函数来打开目标进程,并获得进程的句柄。 2. 接下来,需要在目标进程中分配一块内存空间,用于存储DLL的路径和名称。可以使用`VirtualAllocEx`函数在目标进程内部分配内存。 3. 在分配的内存空间中写入DLL的路径和名称。可以使用`WriteProcessMemory`函数将DLL的路径和名称写入到目标进程的内存中。 4. 使用`GetProcAddress`函数获取`LoadLibraryA`函数的地址,该函数用于加载DLL。可以使用`GetModuleHandle`函数获取kernel32.dll的句柄,然后再调用`GetProcAddress`函数来获取`LoadLibraryA`函数的地址。 5. 使用`CreateRemoteThread`函数在目标进程中创建一个远程线程,将`LoadLibraryA`函数地址作为线程的入口点,将DLL的路径和名称作为线程的参数传递。这样,在目标进程中就会自动加载并执行DLL。 完整的代码示例如下: ```c #include <windows.h> int main() { // Step 1: 打开目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PROCESS_ID); // Step 2: 分配内存空间 LPVOID lpRemoteBuffer = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // Step 3: 写入DLL路径和名称 char dllPath[] = "C:\\path\\to\\dll.dll"; WriteProcessMemory(hProcess, lpRemoteBuffer, (LPVOID)dllPath, sizeof(dllPath), NULL); // Step 4: 获取LoadLibraryA函数地址 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); FARPROC lpLoadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA"); // Step 5: 创建远程线程注入DLL HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibraryA, lpRemoteBuffer, 0, NULL); // 关闭句柄 CloseHandle(hThread); CloseHandle(hProcess); return 0; } ``` 以上就是使用C语言编写远程线程注入DLL的代码。请注意,使用远程线程注入DLL可能存在一些安全风险,请谨慎使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值