吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10001|回复: 53
收起左侧

[游戏安全] 给程序加一个按钮

  [复制链接]
钞sir 发表于 2020-7-21 16:49

简介

有时候我们会觉得某个已经编译好了的程序的功能不是那么完美,我们想要再添加一些额外的功能,但是我们又没有源码,不方便直接进行修改重编译打包,这时候我们就可以考虑给程序添加一个新功能的按钮了...

思路

思路很简单,无非就是利用子类化技术,直接编写DLL,然后注入到程序当中去,虽然就一句话但是具体的工作还是比较多,这里我就通过给植物大战僵尸程序为例子仔细说说...

编写DLL

创建按钮

因为我们主要目的是添加一个按钮功能,使用这里主要用到的函数是CreateWindow...

Syntax:

HWND CreateWindow( 
    LPCTSTR lpClassName, 
    LPCTSTR lpWindowName, 
    DWORD dwStyle, 
    int x, 
    int y, 
    int nWidth, 
    int nHeight, 
    HWND hWndParent, 
    HMENU hMenu, 
    HANDLE hInstance, 
    PVOID lpParam 
)

通过这个函数我们可以创建一个按钮,主要的参数是hWndParent,这个参数表示父窗口句柄,我们可以用FindWindow函数来获取,例如:

#define BUTTON_sir_1 3300
HWND hWndParent = FindWindow(NULL,"植物大战僵尸中文版");
CreateWindow(TEXT("BUTTON"),
            TEXT("增加阳光"),
            WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
            600,0,80,30,
            hWndParent,
            (HMENU)BUTTON_sir_1,
            NULL,
            NULL);

子类化

子类化就是用来改变或者扩展一个已存在的窗口的行为、而不用重新开发的有效途径,这是我们添加按钮,给予按钮处理事件的能力的主要方法,主要方法就是通过GetWindowLong()获取窗口旧的消息处理函数(OldWindowProc),然后通过SetWindowLong()设置新的消息处理函数(NewWndProc),进行需要进行的消息处理,其他的交给旧的消息处理函数:

LRESULT CALLBACK NewWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
OldWindowProc = GetWindowLong(hWndParent,GWL_WNDPROC);
SetWindowLong(hWndParent,GWL_WNDPROC,(LONG)NewWndProc);

新的消息处理函数中只需要写我们感兴趣的消息,比如这里我们只关心按键增加阳光的功能,其余我们没有写的消息处理通过CallWindowProc函数交给原来的消息处理函数处理:

LRESULT CALLBACK NewWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    int wmId, wmEvent;
    switch(message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        case BUTTON_sir_1:
            MessageBox(NULL,TEXT("3003"),TEXT("HELLO"),MB_OK);
            break;
        default:
            return  CallWindowProc((WNDPROC)OldWindowProc,hWnd,message,wParam,lParam);
        }
        break;
    default:
        return  CallWindowProc((WNDPROC)OldWindowProc,hWnd,message,wParam,lParam);
    }
    return 0;
}

这样我们的按键就有相应消息的能力了,剩下的就是完善dll,然后编写dll注入代码了;

DLL注入

基本步骤是:

  1. 获取目标进程句柄
  2. 将要注入的dll路径写入目标进程内存
  3. 获取LoadLibraryW()API地址
  4. 在目标进程中运行远程线程

dll注入的代码确实网上确实到处都是,我这里直接贴出参考,用的是CreateRemoteThread的方法;

效果

在这里插入图片描述2

dll代码

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <stdio.h>
#include <psapi.h>
#define BUTTON_sir_1 3300
#define BUTTON_sir_2 3301
#define BUTTON_sir_3 3302
//extern "C" _declspec(dllexport)
LONG OldWindowProc,Button1Proc;
HWND pro_hwnd;               //程序句柄
HANDLE hpro;                //进程句柄
DWORD pro_base = NULL;      //程序基地址
char szBuf[1024] = { 0 };
LRESULT CALLBACK NewWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
int kill(){
    pro_hwnd = FindWindow(NULL,"植物大战僵尸中文版"); //植物大战僵尸中文版
    if (pro_hwnd == NULL){  //如果无法获取句柄则报错
        return -1;
    }

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

    // 获取每一个模块加载基址
    HMODULE hModule[200] = {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);
    pro_base = (DWORD)hModule[0];
    return 0;
}

void sun_add(){
    DWORD sun_addr = pro_base + 0x002A9EC0;
    printf("阳光基址: 0x%p\n",sun_addr);
    DWORD sun_value;
    DWORD new_sun_value;
    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);
    new_sun_value = sun_value + 2000;
    WriteProcessMemory(hpro, (LPVOID)sun_addr, &new_sun_value, 4, 0);   //修改阳光
}

void kill_all(){
    DWORD kill_1 = pro_base + 0x0013130F;   //0x0053130F
    DWORD code_1 = 0x9090ff29;              //0x20247c2b
    WriteProcessMemory(hpro, (LPVOID)kill_1, (LPVOID)&code_1, 4, 0);    //普通僵尸秒杀

    DWORD kill_2 = pro_base + 0x00131044;   //0x00531044
    WORD code_2 = 0xC929;                   //0xc82b
    WriteProcessMemory(hpro, (LPVOID)kill_2, (LPVOID)&code_2, 2, 0);    //帽子僵尸秒杀
}

void no_time(){
    DWORD no_time = pro_base + 0x00087296;  //0x487296
    WORD code_3 = 0x9090;                   //jle 004872AC
    WriteProcessMemory(hpro, (LPVOID)no_time, (LPVOID)&code_3, 2, 0);   //无冷却时间
}

DWORD APIENTRY Msg(LPVOID lpParameter)
{
    char szBuf[1024] = { 0 };
    //hwnd = FindWindow(NULL, TEXT("wintest"));
    CreateWindow(TEXT("BUTTON"),
                    TEXT("增加阳光"),
                    WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
                    600,0,80,30,
                    pro_hwnd,
                    (HMENU)BUTTON_sir_1,
                    NULL, //(HINSTANCE)GetWindowLongPtr((HWND)lpParameter,GWLP_HWNDPARENT)
                    NULL);
    CreateWindow(TEXT("BUTTON"),
                    TEXT("僵尸秒杀"),
                    WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
                    600,40,80,30,
                    pro_hwnd,
                    (HMENU)BUTTON_sir_2,
                    NULL,
                    NULL);
    CreateWindow(TEXT("BUTTON"),
                TEXT("无冷却"),
                WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
                600,80,80,30,
                pro_hwnd,
                (HMENU)BUTTON_sir_3,
                NULL,
                NULL);

    OldWindowProc = GetWindowLong(pro_hwnd,GWL_WNDPROC);
    SetWindowLong(pro_hwnd,GWL_WNDPROC,(LONG)NewWndProc);

    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK NewWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    int wmId, wmEvent;
    switch(message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        case BUTTON_sir_1:
            //MessageBox(NULL,TEXT("3003"),TEXT("HELLO"),MB_OK);
            sun_add();
            break;
        case BUTTON_sir_2:
            kill_all();
            break;
        case BUTTON_sir_3:
            no_time();
            break;
        default:
            return  CallWindowProc((WNDPROC)OldWindowProc,hWnd,message,wParam,lParam);
        }
        break;
    default:
        return  CallWindowProc((WNDPROC)OldWindowProc,hWnd,message,wParam,lParam);
    }
    return 0;
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        kill();
        CreateThread(NULL, 0, Msg, hModule, 0, NULL);
        break;
    }
    case DLL_THREAD_ATTACH:

    case DLL_THREAD_DETACH:

    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Source.def:

LIBRARY "DLL"
EXPORTS
    Msg

免费评分

参与人数 9威望 +1 吾爱币 +26 热心值 +9 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
嗜血的豆腐脑 + 1 + 1 我很赞同!
godlike007 + 1 优秀
tony666 + 1 + 1 谢谢@Thanks!
whg118 + 1 + 1 谢谢@Thanks!
qaz003 + 1 + 1 哈哈想起了当年珊瑚虫流行时,个个玩插入扩展dll
周星驰0o + 1 我很赞同!
chinasmu + 1 + 1 鼓励转贴优秀软件安全工具和文档!
Hsenwle + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 钞sir 发表于 2020-7-22 11:04
如果没有记错的话,植物大战僵尸是在这里下载的:
http://www.lonelystar.org/download.htm#1_other
(大家自行验证哈)
马可solo 发表于 2020-7-25 14:36
本帖最后由 马可solo 于 2020-7-25 14:38 编辑
钞sir 发表于 2020-7-22 11:04
如果没有记错的话,植物大战僵尸是在这里下载的:
http://www.lonelystar.org/download.htm#1_other
(大家 ...

我之前了解的另一个类似的PVZ站点http://lonelystar.org/download.htm
冷杉 发表于 2020-7-21 18:38
毛线阿 发表于 2020-7-21 18:58
我想要你这个植物大战僵尸
时光书窝 发表于 2020-7-21 23:37
前排支持一下大佬
周星驰0o 发表于 2020-7-21 23:45
前排支持一下
alicc 发表于 2020-7-22 00:36
按钮实际是内置了 还是窗口表面覆盖一层
qaz003 发表于 2020-7-22 01:24
谢谢分享。。满满的回忆呀。。。
想起了当年珊瑚虫流行时,个个玩插入扩展dll
白天起不来 发表于 2020-7-22 02:05
看到植物大战僵尸满满的回忆
江城百里浪 发表于 2020-7-22 06:43
那可以给这种老游戏利用dll注入验证机器码机制吗?
Exmachina-V 发表于 2020-7-22 08:02
我就后排吃灰吧
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 11:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表