【逆向工程核心原理】第八章笔记——abex‘crackme #2原理分析及如何计算序列号

一.ITA 导入地址表

00401000-004010cc:ITA 导入地址表

**内存地址 函数的入口地址 函数名称**
401034   7344CF7E  rtcMsgBox
4010A0   733735A4  ThunRTMain

在这里插入图片描述

二.调用

  1. 间接调用(windows常用)
CALL DWORD PTR DS:[401034]
JMP DWORD PTR DS:[4010A0] 
(内存地址固定的,需要两次缓存)

2.直接调用

CALL 函数的入口地址

3.为什么不用直接调用

开发者的运行环境和使用者的运行环境不同,函数的入口地址不一样。
是变动的,程序运行时,会根据当前的运行环境实时获取。

三.调用IAT里的函数

00401100-00401232:调用IAT里的函数
00401238:push 401E14  

dump输入.401E14,得到下图。
RT_MainStruct结构体,作为下面那个函数的参数。
在这里插入图片描述

四.简单介绍

F9:断点之间的运行,F8:逐步调试

0040123D:入口点的指令

733735A4属于WindowsAPI函数的代码

在这里插入图片描述

触发事件找到对应的用户代码

  1. 用字符串检索法找到对应错误语句,设置断点运行程序
    在这里插入图片描述
LEA :LoadEffectiveAddress载入有效地址,把后面值的地址传到前面。

猜测可能比较EDX,EAX。

在00403321,右边框中EAX可跟踪dump。Dump-右击-long
在这里插入图片描述

Long-address with ascii dump
 命令:显示数据为32位地址和十六进制的数值,并尝试将十六进制的数值当作地址进行解析

在这里插入图片描述

可变长字符串:拿到了这个地址0019F288 ,还要再访存一次才能看到字符串unicode
Unicode:“B6C9DAC9” 它的空间需要是在堆区分配的。

00403329:

为0:表示不等,
表示不等,Test:将两个操作数相与,Ax相与为0,ZF为1,则转至3408

在这里插入图片描述

五.程序里的空间

栈区
局部变量
函数形参

堆区
动态内存分配:

静态区
全局变量
静态变量

六.怎么算出序列号? 找到指令所处函数的开始代码(位置)?

1.根据栈帧结构进行跟踪
2.通用前两条和后三条代码

PUSH EBP
MOV EBP,ESP
...
...
MOV ESP,EBP
POP EBP
RETN

3.猜测:先将用户名字读取进去内存,进行一定的运算,特别关注【BP-一定值】
4.关注到402F8E,调出相对BP,滚动至EBP-88,为00000000
在这里插入图片描述
在这里插入图片描述
接着,执行到2F9E:再观察EBP-88,发现已经将名字读取进去.
在这里插入图片描述

在这里插入图片描述
5.测试数据:ABex1234
*

Vb程序循环:
vbaVarForInit初始化
循环体
vbaVarForNext进入下一趟循环

设置好断点:
在这里插入图片描述

31F0:读取对应字符——跟踪A寄存器
31F7:将字符转化为ascii码
3243:做加法,前面有3个push,
3249:看到A5
运行到3261: A5---“A5”
329A:进入下一轮循环
32A0:跳转到前面3197,循环体开始位置
EAX自己相与,非0,不会达到跳转走,继续
31F0,读取字符
31F6:dump:读到B字符,ASCII:41H
03233:64H
B :42H +64H-----A6
3278连接的地方,变成了“A5A6”()
3281:运行到这里
329A:进入下一轮循环

327B:

在这里插入图片描述
3281:
在这里插入图片描述

31f0:读取字符,再看dump,看看读的时什么字符
3243 :与64H(密钥)相加,得到数值,再F9跳入下一个
3258将值转为字符串
3278连接
329A跳入下一个循环

共循环4次。
最后一次的329A:

最后一次:EAX变为 0
跳到3197:zf为1.
跳到32A5结束

得到序列号的过程通过注册机写成代码,可以运行。

猜你喜欢

转载自blog.csdn.net/wuwuhe99/article/details/130139644