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

目录

动态链接库的基本调用

 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;
}

 

posted @ 2023-11-15 21:58  wakappxc  阅读(19)  评论(0编辑  收藏  举报  来源