首页 > 编程语言 >植物大战僵尸,用QT注入代码,AT&T汇编语法

植物大战僵尸,用QT注入代码,AT&T汇编语法

时间:2024-03-08 15:45:14浏览次数:32  
标签:__ 汇编 QT mov volatile push AT&T ebx asm

遇到了硬茬子,找了半天资料才找到,因为这个QT是mingw编译的,好像编译器是gcc吧,我也不太懂,但是查了半天知道他的语法是AT&T,而我在学汇编的时候学的是8086,好像叫intel语法。所以开头就碰壁到崩溃。。但是又不想放弃换MFC框架 。。也不想用QT5.0+的版本。因为毕竟以后还是高版本好用吗。。不能碰到个岔子,就降低要求了是吧。。所以查了好几天才解决了问题。AT&T语法教程太少了 ,基本上都是零零碎碎的一些回答,和一些其他的文章。

而且我遇到的问题并不能完全复制,因为我这个QT的编译器是mingw 64位的,但是碰上的这个植物大战僵尸是32位的。。所以遇到了很多困难。。在64位的编译器上写32位的代码还要考虑到兼容问题。实在令我头大,又不想放弃。因为一旦放弃意味着我要去学习MFC了。而且。我不可能以后做辅助碰到32位的用32位编译器,注入64位的用64位编译器吧。。那是不可能的,既然他们64位可以兼容32位的,那他一定就可以找到解决办法所以查了半天以自己的理解,才搞定了这几行简单的代码。虽然说就几行代码,但是我查了很多天才组织出这几行代码。

// 这是在MFC也就是,视频老师教的是这样写的,因为我学的也是intel语法所以,会汇编的都可以看的懂这些代码。我就不讲解我的思路了
__declspec(naked) void putPlant(){
    __asm
    {
        pushad
        mov ebx , [006A9EC0]
        mov ebx ,[ebx+768]
        push -1
        push 2
        mov eax,2
        push 6
        push ebx
        call 40D120
        popad
        ret
    }
}

而以下是AT&T语法,也是我找半天,才捣鼓出来的。

// 这些代码需要逐行分析
__declspec(naked) void putPlant()
{

    // 还是那个原因因为用的是64位编译器,所以pushad不可以用了。只能手动堆栈平衡
    __asm volatile("push %rbx");                    // -> pushad
    __asm volatile("push %rax");


    // 语法不同,没有需要讲解的
    __asm volatile("mov (0x6A9EC0),%ebx");          // -> mov ebx , [006A9EC0]

    // 尤其是这段代码。因为此编译器是mingw64位的所以编译器的寄存器是rbx,但是呢,我要注入软件的这个软件是32位的所以他的寄存器最大的就是ebx。
    // 我当时试过这么写的 mov 0x768(%ebx) ,%ebx  但是编译后的代码确是
    // mov ebx, dword ptr ss:[bp+di+0x768] 和 add byte ptr ds:[eax], al
    // 他们甚至不在同一个内存单元里。此时我的代码绝对会崩溃。在网上查了半天也没有解决的方法。
    // 最后我试了试如下代码。竟然可以了。。
    // 其实按照逻辑来说的话 我真的不懂他是怎么回事。因为在8086里 他可能是这样的 mov al ,[ ax + 768 ];
    // 应该就是ax的低八位给了al 所以这里就是 rbx的低八位给了%ebx
    // 因为需要注入的软件是32位的所以他不可能超字节,所以不需要担心。
    __asm volatile("mov 0x768(%rbx) ,%ebx");        // -> mov ebx ,[ebx+768]


    // START:以下没有什么可以需要讲解的。百度上都可以查得到。
    __asm volatile("push $-1");                     // -> push -1
    __asm volatile("push $2");                      // -> push 2
    __asm volatile("mov $2 ,%eax");                 // -> mov eax,2
    __asm volatile("push $6");                      // -> push 6
    // END

    // 这块也一样,push %ebx不好使,构建后直接报错,但是push %rbx就可以。不知道为啥可能是兼容后自动就变成ebx了把。
    // 这里报错会出现 Error: operand type mismatch for `push' ,网上查了原因是:重定位文件是32位,机器是64位,不兼容出现的问题
    __asm volatile("push %rbx");                    // -> push ebx

    // 这块出现的问题就很大了,我先开始写的是 call $0x40D120 不行他会报:Error: unsupported syntax for `call',查都没地方查去
    // 因为我需要 0x40D120是个立即数,根据上边的写法call $0x40D120就应该是立即数但是不行
    // 然后我去查了半天发现查出来的语法是这样的 call *0x40D120 这时候编译器总算是没有报错了。但是我运行的时候竟然报错了。调试后发现注入后的代码:
    // call *0x40D120 变成了 call dword ptr ds:[0x0040D120] 所以我程序直接崩溃了。。那么反向思考。所以我最终的代码就变成了如下:
    __asm volatile("mov $0x40D120 ,%ebx");          // -> call 40D120
    __asm volatile("call *%rbx");


    // 堆栈平衡
    __asm volatile("pop %rax");                     // -> popad
    __asm volatile("pop %rbx");

    // 这代码也很重要,是返回函数的。所有老师基本都有讲
    __asm volatile("ret");
}

正确注入的代码图:

错误注入的代码图:

完整的代码如下

#include "widget.h"
#include "ui_widget.h"
#include <windows.h>
#include <QMessageBox>


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

/* 
 * 这中间穿插这上一节的代码,重复的就不添加了
 */

__declspec(naked) void putPlant()
{
    __asm volatile("push %rbx");                    // -> pushad
    __asm volatile("push %rax");
    __asm volatile("mov (0x6A9EC0),%ebx");          // -> mov ebx , [006A9EC0]
    __asm volatile("mov 0x768(%rbx) ,%ebx");        // -> mov ebx ,[ebx+768]
    __asm volatile("push $-1");                     // -> push -1
    __asm volatile("push $2");                      // -> push 2
    __asm volatile("mov $2 ,%eax");                 // -> mov eax,2
    __asm volatile("push $6");                      // -> push 6
    __asm volatile("push %rbx");                    // -> push ebx
    __asm volatile("mov $0x40D120 ,%ebx");          // -> call 40D120
    __asm volatile("call *%rbx");
    __asm volatile("pop %rax");                     // -> popad
    __asm volatile("pop %rbx");
    __asm volatile("ret");
}

// 秒杀的点击事件
void Widget::on_injectButton_clicked()
{
    // 获取进程ID
    DWORD pid = findGameProcessByWndTitle("植物大战僵尸汉化版");
    // 获取进程句柄
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
    // 在目标进程中申请虚拟内存
    PVOID ThreadFunAdd = VirtualAllocEx(hProcess,NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    // 往指定内存中写入代码
    WriteProcessMemory(hProcess,ThreadFunAdd,LPCVOID(putPlant),4096,NULL);
    // 执行目标进程中的指定代码
    CreateRemoteThread(hProcess,NULL,NULL,(LPTHREAD_START_ROUTINE)ThreadFunAdd,NULL,NULL,NULL);
    // 关闭句柄
    CloseHandle(hProcess);
}

后边的点击事件不是我遇到的困难,这些照着API去看就好了,和老师教的没啥区别。

主要是AT&T的汇编,主要我是小白啥也看不懂,也没有相对应的问题,真的我哭死,不过慢慢试可算是试出来了

最后的功能小弹框,很简单:

 

标签:__,汇编,QT,mov,volatile,push,AT&T,ebx,asm
From: https://www.cnblogs.com/dandingjun/p/18061130

相关文章

  • Qt中关于setGeometry()函数的问题
    setGeometry是相对于父窗体来说的一种对子窗体进行位置设置的方法。当我用在不同的窗体的时候发现有不同的形式QMainWindow和QWidget都是相对父窗体来说的,可是QDialog用上这个设置位置的函数,却是相对于桌面而言的。但是按照道理,他们都是继承的QWidget,setGeometry这个函数的功能......
  • C++ Qt开发:QFileSystemModel文件管理组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QFileSystemModel组件实现文件管理器功能。QFileSystemModel是Qt框架中的一个关键类,用于......
  • Qt开发,报错:Error while building/deploying project untitled (kit: ....)
    1、问题描述 Qt开发,编译时,报错如下:1Cannotfindfile:F:\linux\...\Console.pro.213:49:47:进程"D:\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin\qmake.exe"退出,退出代码2。3Errorwhilebuilding/deployingprojectConsole(kit:DesktopQt5.14.2MSVC201764bit)4......
  • Qt - 坐标系及转换
    屏幕与窗口****屏幕坐标(绝对坐标)窗口坐标(相对坐标)****pos():描述:本控件到父控件的相对坐标窗口的屏幕坐标(上图黑线)描述:窗口左上角-屏幕原点QPoint=this->pos()centerWidet到pushbutton的距离(上图蓝线)描述:button的父控件-centerWidetui->button->pos()描述:button认一......
  • qt输入控件限制输入类型
    限制输入类型有两个控件,根据第一个控件的类型,限制第二个控件可以输入的值代码QComboBoxcomboBox;comboBox.addItem("字符串");comboBox.addItem("数字");layout.addWidget(&comboBox);//连接信号与槽QObject::connect(&comboBox,QOverload<int>::of(&QComboBox::curre......
  • MQTT over WSS
    什么是MQTT?-MQTT协议简介-AWShttps://aws.amazon.com/cn/what-is/mqtt/什么是MQTToverWSS?MQTToverWebSockets(WSS)是一种MQTT实施,用于将数据直接接收到Web浏览器中。MQTT协议定义了一个JavaScript客户端来为浏览器提供WSS支持。在这种情况下,该协议照常工......
  • Qt/C++音视频开发68-检查是否含有B帧/转码推流/拉流显示/监控拉流推流/海康大华宇视监
    一、前言为什么需要判断视频文件是否含有B帧,这个在推流的时候很容易遇到这个问题,一般来说,没有B帧的视频文件,解码后的数据帧pts和dts都是顺序递增的,而有B帧的则未必,可能有些需要先解码后面显示,B帧也是双向预测图像B,对它的编码,即是对它前后帧的像素值之差进行编码,B帧是双向差别帧,也......
  • Qt QMessageBox::information 自定义按钮
    一.基本简介在使用QT的弹窗提示时,习惯使用QMessageBox::informationQMessageBox::questionQMessageBox::warningQMessageBox::critical一般对于按钮,是使用系统提供的默认按钮例如:QMessageBox::Ok|QMessageBox::Cancel等二.如果要自己定义按钮,使用自定义的按钮文字,该怎么......
  • C++ Qt开发:运用QThread多线程组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QThread组件实现多线程功能。多线程技术在程序开发中尤为常用,Qt框架中提供了QThread库来......
  • Qt QMessageBox的简单用法
    效果思路1//创建一个question弹出对话框,添加两个按钮:Yes和No2QMessageBox*box=newQMessageBox(QMessageBox::Question,"提示","确认删除''的信息吗?",QMessageBox::Yes|QMessageBox::No,this);3box->button(QMessageBox::Yes)->se......