一.xdb基础篇

1.逆向准备

1.1 xdb简单使用

image-20240630201904347

点击左上角

image-20240630202702886

点击附加

image-20240630202831498

将要的文件附加进去

image-20240703151750213

1.2.实现用x32dbg分析阳光

  • 只是用(杂交版)学习动态调试

  • 先用ce将阳光的基址找出

    image-20240703134446355

1
2
3
4
5
6
7
阳光基址:[PlantsVsZombies-nosig+vmem+vard.exe"+2A9EC0]+768]+5560]

种植卡片时访问的地址:008AF806 - 89 B7 60550000 - mov [edi+00005560],esi
(在Xdbg有两种方式寻找地址
1:用ctrl+G寻找008AF806
2.直接寻找断点,上次作业保留的)
减号可以返回上一页
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
0041BA60 | 56                       | push esi                                            |
0041BA61 | 8BB7 60550000 | mov esi,dword ptr ds:[edi+5560] | esi=阳光值
0041BA67 | 8BD7 | mov edx,edi | edx:&"p咢", edi:&"p咢"
0041BA69 | E8 12FFFFFF | call plantsvszombies-nosig+vmem+vard.41B980 |
0041BA6E | 03C6 | add eax,esi |
0041BA70 | 3BD8 | cmp ebx,eax |
0041BA72 | 7F 0C | jg plantsvszombies-nosig+vmem+vard.41BA80 |
0041BA74 | 2BF3 | sub esi,ebx | ebx=种植卡片所需的阳光
0041BA76 | E9 853D4900 | jmp <plantsvszombies-nosig+vmem+vard.sub_8AF800> |
0041BA7B | 90 | nop |
0041BA7C | B0 01 | mov al,1 |
0041BA7E | 5E | pop esi |
0041BA7F | C3 | ret |
0041BA80 | 8B8F 8C000000 | mov ecx,dword ptr ds:[edi+8C] | [edi+8C]:"爗f"
0041BA86 | 8B01 | mov eax,dword ptr ds:[ecx] |
0041BA88 | 8B15 607B6A00 | mov edx,dword ptr ds:[6A7B60] | edx:&"p咢"
0041BA8E | 8B80 D8000000 | mov eax,dword ptr ds:[eax+D8] |
0041BA94 | 52 | push edx | edx:&"p咢"
0041BA95 | FFD0 | call eax |
0041BA97 | C787 78550000 46000000 | mov dword ptr ds:[edi+5578],46 | 46:'F'
0041BAA1 | 32C0 | xor al,al |
0041BAA3 | 5E | pop esi |
0041BAA4 | C3 | ret |
1
2
3
008AF800 | 019F CC570000            | add dword ptr ds:[edi+57CC],ebx                     |
008AF806 | 89B7 60550000 | mov dword ptr ds:[edi+5560],esi | 种植阳光时访问的
008AF80C | E9 6BC2B6FF | jmp plantsvszombies-nosig+vmem+vard.41BA7C |
1
2
3
通过分析,我们可以发现,mov dword ptr ds:[edi+5560],esi,要把esi给这个值,同时看见esi的值就是当前剩余阳光数值
再看代码sub esi,ebx,发现esi在这里进行了改变,通关减去edx的值吧esi减少,ebx即卡片所需阳光
因此,我们将sub改成add即可将阳光不减反增

image-20240703142101374

通过在内存窗口中转到地址,我们能够更清晰的分析阳光的变化,要记得将内存中的值改为32位有符号位

1.3 实现永久自动增加阳光

1
由于每次关闭都会重置,要想永久自动我们需要打补丁

image-20240703142903032

1
图片最上方那个向创口贴一样的就是补丁

image-20240703143210349

点击修补文件,保存下来即可

2.逆向基础知识

2.1 访问目标地址常用方法

  1. 使用ctrl+G
  2. 设置断点
  3. 注释(补丁右边一个)
  4. 标签(按冒号能够添加标签)

2.1.1 代码执行法

  • 直接执行文件,一直按步过(F8)直到执行找到代码位置

image-20240707184144474

2.1.2 字符串检索法

image-20240707185127747

打开就能找到字符串,进行查找要的数据

2.1.3 API检索法

程序放进去弹出的黑色框是messageboxw

image-20240707185538137

image-20240707185602972

找到这条,点击进去就能找到

2.1.4 API检索法2

image-20240707190735562

ctrl+G直接搜索MessageBoxA,MessageBoxW

设置断点,进入访问

2.2 使用打补丁方式修改helloworld

image-20240707191334957

目标是把上下英文修改掉

  1. 先找到具体的位置

image-20240707191455618

  1. 修改有两种方法:

    • 一是直接修改缓冲区,
    1
    在内存中找到,全部选中,这里注意字符串末尾是以00结尾的,因此需要把00也包括进去,然后点击编辑,就可以直接修改了

    image-20240707191834378

    image-20240707192044627

    image-20240707192149942

    image-20240707192217206

    • 二是在其他内存区域生成新字符串并传递给消息函数

      1
      怕有其他数据占用了要修改的后面的位置,造成把后面的数据破坏掉,因此一般用这种方式

      我们先找到内存,往下拉,找到空的位置

      image-20240707192713552

      直接将想要的数据填入,复制该数据的地址

      image-20240707192950925

      image-20240707193607032

      最后点击补丁,修补保存就可以了

2.3 小端序知识

大部分汇编已经介绍

在x96dbg中注意这两个

image-20240707195046107

2.4 实现永久不减阳光

  • 打开ce进行操作

    1
    2
    3
    4
    1.增加阳光的地址
    00430A11 - 01 88 60550000 - add [eax+00005560],ecx
    2.减少阳光的地址
    008AF806 - 89 B7 60550000 - mov [edi+00005560],esi

2.4.1 第一种方法

image-20240711214540981

查找地址

image-20240711214832086

1
发现这个给阳光赋值的地址,我们直接把他nop掉,那么种植时就不会减少阳光了

2.4.2 第二种方法

1
分析代码

image-20240711215934949

1
我们想着,能不能通过跳过这个函数来实现目的

image-20240711220848195

1
在函数开头设置断点

image-20240711220924224

1
看到栈窗口的返回地址

image-20240711221038398

1
双击进入找到阳光赋值口,我们往上看

image-20240711221229903

1
找到当al!=0是要跳过这个函数,我们直接把他改成无条件跳过,进入游戏发现阳光不减少

2.5 修改cd

1
同理用ce 找到是什么改写了这个地址,00488E73放入x32dbg

2C0MS_GA5{P9QFL%~CSQ6{X

1
意外之喜,全改了

2.6 修改攻速

1
2
3
4
5
6
用ce找到
0045F8A9 - 83 46 58 FF - add dword ptr [esi+58],-01

0045F8CA - 89 4E 58 - mov [esi+58],ecx

然后再x32dbg中将-1进行更改即可,太快会只动嘴不射豆,改ecx也可以,但是改了会一直把下面的覆盖了,所以在下面一块空的区域写入想要的代码然后jmp过去,还不够的话再转一点代码过去就行了,似乎全植物同样攻速了,再快现在也不去深究了

3.栈

1
首先简单来说三种方式有一个目的,就是清理栈,cdecl是在调用函数时解决(add esp,值),stdcall是在被调用函数中解决(ret 值),而fastcall是传递少量参数,并且多用寄存器

3.1 stdcall与cdecl

image-20240714221502270

eg(以下都在x32dbg进行)

1
像这种一般都是stdcall

image-20240714221829684

1
2
像这种底下跟着add esp,多少的一般都是cdecl
平衡栈

image-20240714222047142

1
tip:汇编里学习的是8086系统,是16位的微处理器,因此在8086中压栈是esp-2
  • call:

    1
    2
    3
    汇编里已经学习:
    1:esp-4
    2:把下一行的地址压栈
  • ret

    1
    2
    esp+4
    EIP 指向前面call时候压入的地址
  • ret 4

    1
    esp+8

3.2 fastcall

多用寄存器进行传参

3.3 植物大战僵尸弹出检测框修改

1
先通过字符串寻找:游戏暂停,然后在内存地址转到

image-20240714233301776

1
32是空格的ascii码,转为16进制也就是20

image-20240714233549893

1
字符串以00结尾,我们改掉这里的内容,就可以把游戏暂停这几个字改了,返现就是这里,然后我们需要判断弹出窗口是否就在这个函数,这里不能直接把开头改成ret,因为里面可能调用参数,我们要看他是怎么返回的,把他复制到开头

image-20240714234208767

1
这样子改完,发现确实成功了,点旁边不会暂停,空格也不暂停了

3.4 逆向程序注册码

3.4.1 消灭弹窗

image-20240726185913752

1
2
现在有这么一个程序,我需要做到干掉弹窗和找到注册码
首先,弹窗有很明显的字符串提示,直接进行搜索

image-20240726190055041

1
2
3
4
通过一步步进行发现弹窗位如下
00402CFE | E8 1DE4FFFF | call <JMP.&rtcMsgBox>
把此处nop了它直接崩溃了
原因可能是我们把它平衡栈的地方也nop了,因此我们需要帮他平衡一下栈

image-20240726190947317

1
再通过一系列寻找,找到ret 14,记住这个14是16进制的,也就是20,就是5个参数,所以最原始平栈要5个参数,然后在最开始补上add esp,0x14  欸发现还是崩溃

image-20240726191911885

1
然后我们思考是不是返回值漏了导致程序崩溃,再次查看,下断点,运行,步过,查看寄存器变化

image-20240726192508303

image-20240726192606198

1
发现eax变成1了,我们试试再把eax改了,发现字节长度不够,我们再去看包括这个弹窗的这整个函数,把这整个函数改成ret 多少了,就成功把弹窗干掉了

3.4.2 注册码

1
还是一样通过字符串找到位置,发现了这个判断函数,两种方法,一种nop掉,一种改zf,可以直接跳过注册码,实现yep

image-20240726195147699

1
在附近也发现了注册码,就是I'mlena151,修改直接修改即可

image-20240726195840219

4.各类语句(debug)

4.1 if

1
2
3
eg:if (a==0)
cmp a,0
jne 地址 ;不等于不执行
1
2
3
eg:if(a>0)
cmp a,0
jle 地址 ;小于等于不执行

注:release版很多都没有push ebp

1
2
3
cmp a,b
setne al
不相等 al=1, 相等 al=0
1
2
3
4
5
6
7
8
9
CMOVNE 是 x86 汇编语言中的一条指令,它表示 "Conditional Move if Not Equal",即在不等条件下进行条件移动。这条指令的作用是根据先前的比较结果来选择是否将一个值移动到目标寄存器中,它是根据 ZF(零标志位)来决定的:

如果 ZF 为 0(表示两个操作数不相等),则执行移动操作。
如果 ZF 为 1(表示两个操作数相等),则不执行移动操作,目标寄存器保持不变。
这种指令在处理条件逻辑时非常有用,可以根据前面的比较结果直接进行条件赋值操作,而不需要使用分支语句来实现。

cmp a,b
cmovne c,d
ab不相等把d赋值给c