C语言获取任意Windows程序模块基地址

我已无力接住你,再也不能抗风雨

函数

这里主要用到的函数是EnumProcessModulesEx:

BOOL EnumProcessModulesEx(
  HANDLE  hProcess,
  HMODULE *lphModule,
  DWORD   cb,
  LPDWORD lpcbNeeded,
  DWORD   dwFilterFlag
);

hProcess表示处理的句柄;
lphModule表示接收模块句柄列表的数组;
cb表示lphModule数组的大小,以字节为单位;
lpcbNeeded表示在lphModule数组中存储所有模块句柄所需的字节数;
dwFilterFlag表示过滤条件,下列值之一:

含义
LIST_MODULES_32BIT
0x01
列出32位模块
LLIST_MODULES_64BIT
0x02
列出64位模块
LIST_MODULES_ALL
0x03
列出所有模块
LIST_MODULES_DEFAULT
0x00
使用默认行为

所以我们在用这个函数时需要先利用函数FindWindow()找到程序的窗口句柄,然后利用函数GetWindowThreadProcessId()找到程序的进程ID,最后调用函数OpenProcess()找到程序进程的打开句柄,最后可以调用EnumProcessModulesEx()函数获取模块的基地址;

实例

这里直接以获取植物大战僵尸的基地址来演示:

#include<stdio.h>
#include<windows.h>
#include<psapi.h>
int main(){
	HWND hWnd = FindWindow(NULL,"植物大战僵尸中文版");
	if (hWnd == NULL){	//如果无法获取句柄则报错
		printf("无法获取窗口句柄,请检查进程是否存在!\n");
		system("pause");
		return -1;
	}

	DWORD pro_id;
	GetWindowThreadProcessId(hWnd, &pro_id);	//获取进程ID  
	if(pro_id == 0){
		printf("无法获取进程ID\n");
		system("pause");
		return 0;
	}
	printf("进程id: %d\n",pro_id);
	//打开进程对象,并获取进程句柄
	HANDLE hpro = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pro_id);
	if (hpro == 0){
		printf("无法获取进程句柄");
	}
	printf("进程句柄id: %d\n",hpro);

	// 获取每一个模块加载基址
	DWORD pro_base = NULL;
	HMODULE hModule[100] = {0};
    DWORD dwRet = 0;
	int num = 0;
    int bRet = EnumProcessModulesEx(hpro, (HMODULE *)(hModule), sizeof(hModule),&dwRet,NULL);
    if (bRet == 0){
        printf("EnumProcessModules");
    }
	// 总模块个数
	num = dwRet/sizeof(HMODULE);
	printf("总模块个数: %d\n",num);
	// 打印每一个模块加载基址
	char lpBaseName[100];
	for(int i = 0;i<num;i++){
		GetModuleBaseNameA(hpro,hModule[i],lpBaseName,sizeof(lpBaseName));
		printf("%-2d %-25s基址: 0x%p\n",i,lpBaseName,hModule[i]);
	}

    pro_base = (DWORD)hModule[0];
	printf("程序基址: 0x%p\n",pro_base);
	
	DWORD sun_addr = pro_base + 0x002A9EC0;
	printf("阳光基址: 0x%p\n",sun_addr);
	DWORD sun_value;
	DWORD new_sun_value = 2000;
	DWORD kill_1 = pro_base + 0x0013130F; //0x0053130F
	DWORD code_1 = 0x9090ff29; //0x20247c2b
	DWORD kill_2 = pro_base + 0x00131044; //0x00531044
	WORD code_2 = 0xC929;	//0xc82b
	// 0x0048728C
	ReadProcessMemory(hpro,(PVOID)sun_addr,&sun_addr,4,0);
	sun_addr = sun_addr + 0x768;
	ReadProcessMemory(hpro,(PVOID)sun_addr,&sun_addr,4,0);
	sun_addr = sun_addr + 0x5560;
	ReadProcessMemory(hpro,(PVOID)sun_addr,&sun_value,4,0);
	printf("阳光地址: %p\n当前阳光值: %d\n",sun_addr,sun_value);
	printf("修改的阳光值: 2000\n");
	//scanf("%d",&new_sun_value);
	WriteProcessMemory(hpro, (LPVOID)sun_addr, &new_sun_value, 4, 0); //修改阳光
	WriteProcessMemory(hpro, (LPVOID)kill_1, (LPVOID)&code_1, 4, 0); //普通僵尸秒杀
	WriteProcessMemory(hpro, (LPVOID)kill_2, (LPVOID)&code_2, 2, 0); //帽子僵尸秒杀
	system("pause");
	return 0;
}

可以通过CE进行查看对比:
dump

  • 11
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Windows平台上,C语言可以通过Winsock API的getAdaptersInfo函数来获取MAC地址。首先,需要引入Windows的头文件Winsock2.h,并链接ws2_32.lib库。然后,通过调用getAdaptersInfo函数可以获取到网卡的各项信息,其包括MAC地址。接着,可以通过遍历获取到的信息结构体来找到所需网卡的MAC地址,并将其打印或保存下来。 具体步骤如下: 1. 引入头文件 ```c #include <Winsock2.h> #include <iphlpapi.h> ``` 2. 链接库 ```c #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "IPHLPAPI.lib") ``` 3. 获取MAC地址 ```c PIP_ADAPTER_INFO pAdapterInfo; DWORD dwBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = (IP_ADAPTER_INFO *)malloc(dwBufLen); if (pAdapterInfo == NULL) { printf("Error in allocating memory for adapter info\n"); } else { if (GetAdaptersInfo(pAdapterInfo, &dwBufLen) == ERROR_BUFFER_OVERFLOW) { free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO *)malloc(dwBufLen); } if (pAdapterInfo == NULL) { printf("Error in allocating memory for adapter info\n"); } else { if (GetAdaptersInfo(pAdapterInfo, &dwBufLen) == NO_ERROR) { PIP_ADAPTER_INFO pAdapter = pAdapterInfo; do { printf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", pAdapter->Address[0], pAdapter->Address[1], pAdapter->Address[2], pAdapter->Address[3], pAdapter->Address[4], pAdapter->Address[5]); pAdapter = pAdapter->Next; } while (pAdapter); } free(pAdapterInfo); } } ``` 通过以上步骤,就可以在Windows平台上使用C语言获取到网卡的MAC地址了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值