学习记录-用C语言写补丁
// ConsoleApplication_GetBaseAddress.cpp : 定义控制台应用程序的入口点。//
#include "stdafx.h"
#include<stdio.h>
#include<windows.h>
#include<psapi.h>
#include<direct.h>
#include <string.h>
int _tmain(int argc, _TCHAR* argv[])
{
//获取当前目录
char path;
getcwd(path, 100);
//printf("current work path:%s\n", path);
char *zifu = getcwd(path, 100);
//printf("current work path:%s\n", zifu);
char *zifu2 = "\\MindMaster.exe";//修改该值即可
char *zifu3 = strcat(zifu, zifu2);
printf("启动MindMaster:%s\n", zifu3);
//运行外部的程序
WinExec(zifu3, SW_SHOW);
//延时
int a;
a = 15000;
Sleep(a);
//获取窗口句柄
HWND hWnd = FindWindow(NULL, "MindMaster");
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;
DWORD prodll_base = NULL;
HMODULE hModule = { 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;
for (int i = 0; i < num; i++){
GetModuleBaseNameA(hpro, hModule, lpBaseName, sizeof(lpBaseName));
printf("%-2d %-25s基址: 0x%p\n", i, lpBaseName, hModule);
}
pro_base = (DWORD)hModule; prodll_base = (DWORD)hModule;
printf("程序基址: 0x%p\n", pro_base); printf("objectmodule基址: 0x%p\n", prodll_base);
/////////////////////////////////////////////////////////////////////////////
DWORD tounaofenbao = pro_base + 0x78eb95;
printf("头脑风暴基地址: 0x%p\n", tounaofenbao);
//ReadProcessMemory(hpro, (PVOID)tounaofenbao, &tounaofenbao, 4, 0); 为什么注释掉,因为把eb95的值7C 79 FA 83 转换成了地址
//tounaofenbao = tounaofenbao + 0x0;
DWORD Tnfb_value = 2088368771;//OD显示的二进制顺序是 83 FA 79 7C 在换算的时候要倒着念 7C 79 FA 83 把7C 79 FA 83换成十进制就得到2088368771
WriteProcessMemory(hpro, (LPVOID)tounaofenbao, &Tnfb_value, 4, 0);//是修改成功了 但程序确自动退出了 找到原因了 加上7C后就正确了 保持4个字节
//甘特图
DWORD gantetu = pro_base + 0x6122E1;
printf("甘特图基地址: 0x%p\n", gantetu);
//DWORD GTU_value = 2425393296;
char GTU_value = {0x90,0x90,0x90,0x90,0x90,0x90};
WriteProcessMemory(hpro, (LPVOID)gantetu, GTU_value, 6, 0);
DWORD gantetu2 = pro_base + 0x6122E9;
printf("甘特图基地址: 0x%p\n", gantetu2);
char GTU_value2 = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
WriteProcessMemory(hpro, (LPVOID)gantetu2, GTU_value2, 6, 0);
//主题风格
DWORD zhutifengge = pro_base + 0x68C118;
printf("主题风格基地址: 0x%p\n", zhutifengge);
char zhutifengge_value = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
WriteProcessMemory(hpro, (LPVOID)zhutifengge, zhutifengge_value, sizeof(zhutifengge_value), 0);
DWORD zhutifengge2 = pro_base + 0x68C122;
printf("主题风格基地址2: 0x%p\n", zhutifengge2);
char zhutifengge_value2 = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
WriteProcessMemory(hpro, (LPVOID)zhutifengge2, zhutifengge_value2, sizeof(zhutifengge_value2), 0);
//复制图片功能
DWORD tup = prodll_base + 0x127B60;
printf("复制图片功能基地址: 0x%p\n", tup);
char tup_value = { 0xeb, 0x3b};
WriteProcessMemory(hpro, (LPVOID)tup, tup_value, sizeof(tup_value), 0);
//图标功能
DWORD tub = pro_base + 0x706206;
printf("图标功能基地址: 0x%p\n", tub);
char tub_value = { 0x90, 0x90 };
WriteProcessMemory(hpro, (LPVOID)tub, tub_value, sizeof(tub_value), 0);
DWORD tub2 = pro_base + 0x70620C;
printf("图标功能基地址: 0x%p\n", tub2);
char tub2_value = { 0xeb, 0x22 };
WriteProcessMemory(hpro, (LPVOID)tub2, tub2_value, sizeof(tub2_value), 0);
return 0;
}
本帖最后由 爱飞的猫 于 2023-10-12 07:20 编辑
1. 请使用代码框功能格式化代码
2. `prodll_base = (DWORD)hModule;` 请判断 DLL 名称,而非写死。系统更新/旧版本可能偏移就错了
* MSVC 实际上是 C++ 编译器,你可以用 `std::map<std::string, HMODULE>` 来记录模块信息或访问。
3. 使用 `CreateProcess` 并带上 `CREATE_SUSPENDED`,可以已暂停模式启动进程,补丁完后再继续主程序运行。
4. 为什么不直接用字节数组呢?相比你现在的写法并不会带来额外的性能上的开销。
5. 你可以使用数值或表达式,不需要全都先赋值到变量再使用,如 `Sleep(15'000);`。
(4) 直接使用字节数组:
```cpp
char Tnfb_value[] = {0x83, 0xFA, 0x79}; // 如果只需要补 3 个字节,那就写 3 个字节即可。
WriteProcessMemory(hpro, (LPVOID)tounaofenbao, Tnfb_value, sizeof(Tnfb_value), 0);//是修改成功了 但程序确自动退出了 找到原因了 加上7C后就正确了 保持4个字节
```
(2) 使用 `std::map` 储存数据
```cpp
#include <iostream>
#include <string>
#include <map>
int main()
{
std::map<std::string, int> map1{};
map1["abc"] = 123;
map1["def"] = 456;
std::cout << "map1: " << map1["abc"] << std::endl;
std::cout << "map1: " << map1["def"] << std::endl;
std::cout << "map1: " << map1["zzz"] << std::endl;
/*
* 输出:
* map1: 123
* map1: 456
* map1: 0
*/
}
```
感谢教学! 谢谢分享。 感谢分享 非常不错,感谢分享 楼主很强!进来学习 感谢分享,学习了。 爱飞的猫 发表于 2023-10-12 07:16
1. 请使用代码框功能格式化代码
2. `prodll_base = (DWORD)hModule;` 请判断 DLL 名称,而非写死 ...
大佬牛批
页:
[1]
2