打印程序目标地址附近内存
#include <stdio.h> // printf、scanf 所需头文件
#include <sys/ptrace.h> // ptrace 系统调用头文件
#include <sys/types.h> // 部分系统下 ptrace 依赖的类型定义int main(void)
{printf("Ptrace\n");// 输入目标进程 PIDint pid;printf("please input pid:");scanf("%d", &pid);// 输入要读取的内存地址(十六进制)long address;printf("please input address:");scanf("%lX", &address); // %lX 匹配 long 类型的十六进制输入// 附加到目标进程long ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL);printf("PTRACE_ATTACH:%d\n", ret);// 读取目标进程内存数据print("%X",address)int num = 40;for(int i = 0; i < num; i++){ret = ptrace(PTRACE_PEEKDATA, pid, address, NULL);printf("%d\t", ret); // 输出读取的内存值(十进制)address += 0x4;if((i+1)%4==0){//每输出4个地址,便输出一个换行。print("\n");if(i != (num-1)){print("%X",address);}}}// 与目标进程分离ret = ptrace(PTRACE_DETACH, pid, NULL, NULL);printf("PTRACE_DETACH:%d\n", ret); // 补充原代码遗漏的分离结果打印return 0;
}
常用函数
ptrace()函数
ptrace(PTRACE_POKEDATA,pid,address,data);//写入数据
proc函数
int main(void)
{char * mem_path = "/proc/30044/mem";int fd = open(mem_path,O_RDWR);long int address = 0xBCF5D83C;//读取地址int res = 0;lseek(fd,address,SEEK_SET);read(fd,&res,sizeof(int));print("lX read int %d\n",address,res);close(fd);return 0;
}
Leek函数
lseek(mem_file, addr, SEEK_SET)
mem_file对应一个 /proc/[pid]/mem
调用 lseek(mem_file, addr, SEEK_SET) 后:
后续 read(mem_file, ...) 会读取进程虚拟地址 addr 处的数据。
后续 write(mem_file, ...) 会修改进程虚拟地址 addr 处的内容(需权限)。
proc读取libc相关地址
软件加载libc时,libc存放的位置/proc/pid/maps,里面有libc加载到的地址。
addrBegin-addrEnd 读写权限 地址信息使用指令筛选
grep target_libc_name /proc/pid/maps

int main(){mem_file = open ("/proc/6312/mem",O_WORD);FILE *libnative = popen("grep libnative.so /proc/6312/maps","r");char temp[10];int i = 0;int ch = fgetc("libnative");while(ch != '-'){temp[i] = ch;ch = fgetc("libnative");i+=1;}temp[i]='\0';unintptr_t addr;sscanf(tmp,"%lx",&addr); // 将char类型转换为16进制}
process_vm
syscall(__NR_process_vm_readv,30044);//参数:系统调用函数名,被调函数参数(pid)
MFC界面辅助编写
MFC编写注意事项
- 窗口句柄注意不要和已知软件名称重复。
调试信息
弹窗提示
CString msg; // 定义字符串变量
msg.Format(_T("成功获取PID:%d"), pid);
AfxMessageBox(msg);
AfxMessageBox(_T("获取 进程句柄 失败"));
C++编写代码读取内存地址
项目创建
使用VS Studio:创建新项目-> c++ ->MFC项目
VS安装MFC

弹出来的选项:
应用程序类型:基于对话框
使用MFC:在静态库文中使用MFC
项目创建完成后,主对话框位置:资源文件->MFCApplication1.rc,双击,MFCApplication1->Dialog->IDD_MFCAPPLICATION1_DIALOG。
添加选择框和编辑框和按钮
使用static Text,和Edit Control,Button

设置窗口标题
右键窗口空白部分,选择属性。选择外观->描述文字
编辑框添加变量
右键编辑框->添加变量->输入变量名称,类型默认即可。 // 后续用这个名字来操纵编辑框
给按钮添加事件
双击按钮
void CMFCApplication1Dlg::OnBnClickedButton1()
{HWND 窗口句柄 = ::FindWindow(NULL, L"诛仙"); //找窗口句柄if (窗口句柄 == NULL){// 未找到窗口:输出调试信息AfxMessageBox(_T("未找到标题为“诛仙”的窗口!")); // 弹窗提示OutputDebugString(_T("FindWindow 失败:未找到“诛仙”窗口\n")); // 输出到调试窗口return; // 若未找到,可提前退出函数,避免后续无效操作}else{// 找到窗口:输出成功信息(可选)AfxMessageBox(_T("成功找到“诛仙”窗口!"));OutputDebugString(_T("FindWindow 成功:已找到“诛仙”窗口\n"));}DWORD pid;GetWindowThreadProcessId(窗口句柄, &pid);if (pid == 0){AfxMessageBox(_T("pid未找到"));return;}else{CString msg; // 定义字符串变量msg.Format(_T("成功获取PID:%d"), pid);AfxMessageBox(msg);}HANDLE 进程句柄 = OpenProcess(PROCESS_VM_READ, FALSE, pid);if (进程句柄 == NULL){AfxMessageBox(_T("获取 进程句柄 失败"));return;}QWORD 当前气血;ReadProcessMemory(进程句柄, (LPCVOID)0x14176E868, &当前气血, sizeof(当前气血), NULL); //目标进程的基址。ReadProcessMemory(进程句柄, (LPCVOID)(当前气血 + 0x60), &当前气血, sizeof(当前气血), NULL);//偏移ReadProcessMemory(进程句柄, (LPCVOID)(当前气血 + 0x558), &当前气血, sizeof(当前气血), NULL);//二级偏移//wchar_t juseming[30]; //读取字符串,读取角色名。//ReadProcessMemory(进程句柄, (LPCVOID)0x14135D8A8, &角色名, sizeof(角色名), NULL);//基址//ReadProcessMemory(进程句柄, (LPCVOID)(角色名 + 0x40), &角色名, sizeof(角色名), NULL);////ReadProcessMemory(进程句柄, (LPCVOID)(角色名 + 0x80), &角色名, sizeof(角色名), NULL);//将角色名+0x80指向的地址赋值给角色名//ReadProcessMemory(进程句柄, (LPCVOID)(角色名 + 0), juseming, sizeof(juseming), NULL);CString str;str.Format(L"%d", 当前气血);edit当前气血.SetWindowTextW(str);
}
生成软件
选择realse->生成解决方案,在命令输出框中找到输出路径

注意用管理员启动

MFC的DLL注入技及C语言指针读取
项目创建选择MFC动态连接库,静态链接到MFC的常规DLL。
选择资源文件->xxxx.rc双击打开资源视图。

右键图示文件,添加资源,Dialog。
右键新建的Dialog窗口,添加类,类名不要取中文。
然后切换到解决方案,源文件->MFCLibrary1.cpp,添加头文件#include "mydialog.h"
打开MFCLibrary1.cpp

myDialog* mywindow;//定义全局指针
DWORD WINAPI 显示窗口(LPARAM lpDate)
{mywindow = new myDialog;//创建对象mywindow->DoModal();delete mywindow;//释放内存FreeLibraryAndExitThread(theApp.m_hInstance,1);//释放DLLreturn TRUE;}// CMFCLibrary1App 初始化BOOL CMFCLibrary1App::InitInstance()
{CWinApp::InitInstance();::CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)显示窗口,NULL,NULL,NULL);return TRUE;
}
生成文件
记住MFCLibrary1.dll的位置,打开游戏和CE
CE选择游戏后打开查看内存->工具->注入DLL
然后成功注入并且游戏和CE也都蹦掉了。
指针读取
void myDialog::OnBnClickedButton2()
{//ReadProcessMemory(进程句柄, (LPCVOID)0x14176E868, &当前气血, sizeof(当前气血), NULL); //目标进程的基址。//ReadProcessMemory(进程句柄, (LPCVOID)(当前气血 + 0x60), &当前气血, sizeof(当前气血), NULL);//偏移//ReadProcessMemory(进程句柄, (LPCVOID)(当前气血 + 0x558), &当前气血, sizeof(当前气血), NULL);//二级偏移/*0x14176E868+60+558*/QWORD 当前气血 = *(QWORD*)0x14176E868; // 注意如果访问了错误的指针,指针的值不存在会导致游戏崩溃。当前气血 = *(QWORD*)(当前气血 + 0x60);当前气血 = *(QWORD*)(当前气血 + 0x558);CString str;str.Format(L"%d", 当前气血);edit当前气血.SetWindowTextW(str);}
使用后闪退不清楚原因。
DLL注入功能代码实现
创建项目->MFC应用->应用程序类型:基于对话框->使用MFC:在静态库中使用MFC
BOOL DLL注入(HANDLE 进程句柄,const char*DLL完整路径)
{LPVOID 地址 = VirtualAllocEx(进程句柄,NULL,256,MEM_COMMIT,PAGE_READWRITE);//成功返回申请空间的地址if (地址 == NULL){AfxMessageBox(_T("地址失败"));return FALSE;}BOOL ret =WriteProcessMemory(进程句柄, 地址, DLL完整路径, strlen(DLL完整路径) + 1, NULL);if (ret = NULL) {return FALSE;}HANDLE 线程句柄 = CreateRemoteThread(进程句柄, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryA, 地址, NULL, NULL);//Load参数加载DLL完整路径if (线程句柄 == NULL) {VirtualFreeEx(进程句柄, 地址, 0, MEM_RELEASE);AfxMessageBox(_T("获取 线程句柄 失败"));return FALSE;}AfxMessageBox(_T("运行到这里成功"));WaitForSingleObject(线程句柄, INFINITE);CloseHandle(线程句柄);VirtualFreeEx(进程句柄, 地址, 0, MEM_RELEASE);return TRUE;
}
void CMFCApplication1Dlg::OnBnClickedButton2()
{HWND 窗口句柄 = ::FindWindow(NULL, L"诛仙");DWORD pid;GetWindowThreadProcessId(窗口句柄, &pid);if (pid == NULL){AfxMessageBox(_T("获取 pid 失败"));return;}else{CString msg; // 定义字符串变量msg.Format(_T("成功获取PID:%d"), pid);AfxMessageBox(msg);}HANDLE 进程句柄 = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD,FALSE ,pid);//注意需要权限CString msg; // 定义字符串变量msg.Format(_T("成功获取进程句柄:%d"), 进程句柄);AfxMessageBox(msg);DLL注入(进程句柄, "D:\\project\\vstudio\\C++\\MFCLibrary1\\x64\\Release\\MFCLibrary1.dll");CloseHandle(进程句柄);
}
参考链接
BV184AMeMELE?spm_id_from=333.788.player.switch&vd_source=d24c2772c59c9d862438971bcb05f991&p=6
