一.ITA 导入地址表
00401000-004010cc:ITA 导入地址表
**内存地址 函数的入口地址 函数名称**
401034 7344CF7E rtcMsgBox
4010A0 733735A4 ThunRTMain
二.调用
- 间接调用(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函数的代码
触发事件找到对应的用户代码
- 用字符串检索法找到对应错误语句,设置断点运行程序
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结束
得到序列号的过程通过注册机写成代码,可以运行。