网课老师讲到70+课时号被封了,呃。。。就当是复习了一遍OD吧
OD复习
e:模块列表,可以看到调用的所有DLL
t:线程线列:可以看到运行的所有线程
k:堆栈列表:可以看到调用的所有call
b:断点列表:可以看到设置的所有断点
c:CPU窗口/代码窗口
入口:main/启动窗口创建完毕/子程序创建完毕
OD打开主程序入口如下:
00B755E2 >/$ 55 push ebp
按上面的e按钮后找到ELEMENTCLIENT.EXE条目如下:
Executable modules, 条目 32
基址=00400000
大小=00950000 (9764864.)
入口=00B755E2 ELEMENTC.
名称=ELEMENTC
路径=D:\kdxy\setup\口袋西游\element\ELEMENTCLIENT.EXE
我们打开ce附加进程后在00400000到00D50000范围内搜索,全是绿色地址
如果附加进程后运行不了
按上面的t按钮右击重启所有线程即可
按上面的c按钮可以回到主界面
ctrl+g再输入地址可以直接跳到目的地址
输入send可以直接定位到发包函数
如果send定位不到,则输入WS2_32.send再回车
找到没人的地方打断点,保持没有发包
吃药,发包中断,然后ctrl+F9就能跳到send函数最后一条指令
回车就能回到call send的下一条指令0x00666850
00666830 . 53 push ebx
00666831 . 56 push esi
00666832 . 8BF1 mov esi,ecx
00666834 . 57 push edi
00666835 . 6A 00 push 0x0 ; /Flags = 0
00666837 . 8B46 10 mov eax,dword ptr ds:[esi+0x10] ; |
0066683A . 8B48 04 mov ecx,dword ptr ds:[eax+0x4] ; |
0066683D . 8B50 08 mov edx,dword ptr ds:[eax+0x8] ; |
00666840 . 8B46 04 mov eax,dword ptr ds:[esi+0x4] ; |
00666843 . 8BD9 mov ebx,ecx ; |
00666845 . 2BD3 sub edx,ebx ; |
00666847 . 52 push edx ; |DataSize = 856FDDC (139918812.)
00666848 . 51 push ecx ; |Data = 0A29A465
00666849 . 50 push eax ; |Socket = 0x3
0066684A . FF15 B868BE00 call dword ptr ds:[<&WS2_32.#send_19>] ; \send
00666850 . 8BD8 mov ebx,eax
再次ctrl+f9跳到函数末,回车跳到上一层call的下一条指令,按错了可以用-键返回上一条指向的指令(无论是ctrl+f9按错还是enter按错都可以跳回刚指向的指令)
如此循环找到多重call,我们给第一,第二,第三……每重call都打断点,按上面的b按钮可以看所有断点
走路进入的断点撤销,吃药进入的断点就是要找的!只要是只有吃药才进入的断点都可以进行远程注入线程调用!观察前几行的push,用代码注入进行调试!
喊话call找法:同吃药call,就是把吃药换成喊话
快速寻找call:在send函数处断下,喊话,按上面的k按钮,可以分析出所有的call调用
在send函数头处中断,右下角双击栈地址,可以变成 − − > , -->, −−>,+4,$+8这类的地址
观察到传进来的参数有四个:socket,data,datasize,flags,我们如果能分析出每一个参数的地址,就可以实现每一种call了!
在send函数头处的中断改成条件中断,如[ESP+0x0C]==0x0B,逐个值试!
走路断,不动断,点击断,攻击断,吃药断,都有不同的datasize,记下对应断的值即可
eax一般是call的返回值,小部分可能是用ecx
ecx一般用来存对象基地址(像新剑侠情缘中的独孤剑)
ebx与edx就是读写比较快,没什么特别
附加进程后结束调试:右击代码区-strongOD-detach
OD基本功:懂得f7与f8与f9来运行,ctrl+f9与enter与-来跳转,代码段int3与条件来中断,数据段内存(易被检测勿用)与硬件(断在访问内存数据的指令下一行)来中断,上面的按钮看不同窗口界面
汇编基本功:mov(传值)与lea(传址),push x(sub esp,4 + mov [esp],x)与pop x(mov x,[esp] + add esp,4),call x(push eip + jmp x)与retn(pop eip)与retn x(pop eip + add esp,x)
右击代码区,查找,用户定义的注释(即可看到所有代码注释)
右击代码区,查找,所有常量(即可看到所有用到绿址的代码)
在OD看到[ebp+2C]这种,要先判断ebp是本层函数栈底还是偏移!ebp与右下角的堆栈区拉到最靠栈顶的那个有显示返回的地址的那一行(call的push eip)的上一行(函数头push的ebp)相等就是顶底
右下角的堆栈区如果是新跳入的call,栈顶指令右边会是“call返回xxx”然后连同下面几行有个大括号括住传入的参数,之后本函数如果有push,则“call返回xxx”的这个不是栈顶
往上找代码时看到retn,要注意区分retn的下一行代码是不是函数入口,点击分析代码,看上面是否会有jmp箭头指向它,有的话就是同一个函数(一般中间没有int3是同一函数)
往上找代码时看到retn,要注意区分retn的下一行代码是不是函数入口,ctrl+f9-回车-上一行指向call-回车进行函数入口,与刚才retn的下一行比较是否相同(一般上面是int3的是函数头)
在OD看到[esp+10]这种,要意识到要看代码往前找第四个push,(esp是栈顶,右下角堆栈区往下找四个地址(4B为单位)可以看到值)
在OD看到mov edx,[eax+2C]且上一行是call,要小心eax很大可能是call的返回值
远程调用call时,call前的mov寄存器要看函数体内有没有调用到该寄存器的值,有的话也可能是一个参数
远程调用call时,call后对esp的操作要看函数体末有没有自动平栈如retn 10,或者用OD在CALL前后用F8步过看push前与call后的esp是否相等也可以知道是否自动平栈
假设现在的场景如下(所有指令与值都假设为1B)
设10处指令执行时ebp与esp的值都是08
11 push eax
12 push ecx
13 push edx
14 call 0xF4
15 inc a
....
F4 push ebp
F5 mov ebp,esp
....
FE pop ebp
FF retn 3
我们知道call x(push eip + jmp x)
所以在执行F4处的指令前栈顶会有一个大括号括着四行
依次是eip的值即15,edx的值,ecx的值,eax的值
当前栈:(ebp=08,esp=04)
04 15(返回到15)
05 edx
06 ecx
07 eax
08 ...
F4处压入ebp保护起来,此时栈顶的值是08,然后是15
当前栈:(ebp=08,esp=03)
03 08
04 15(返回到15)
05 edx
06 ecx
07 eax
08 ...
我们知道esp永远是指向栈顶的,即此时esp的值是03
F5处把esp赋给ebp,则ebp的值也是03,指向本段函数的栈底
此时就回到了esp与ebp相等的情况(开始时的两个值都是08)
当前栈:(ebp=03,esp=03)
03 08
04 15(返回到15)
05 edx
06 ecx
07 eax
08 ...
假设本段函数没有再调用子函数,没有对栈进行操作,一直到FE处
FE处pop ebp还原ebp的值为08,即上层函数的栈底,esp由于退栈地址增加变成04
当前栈:(ebp=08,esp=04)
04 15(返回到15)
05 edx
06 ecx
07 eax
08 ...
我们知道retn x相当于pop eip + add esp,x
首先eip=15,esp由于退栈地址增加变成05
当前栈:(ebp=08,esp=05)
05 edx
06 ecx
07 eax
08 ...
(补充说明:如果只是retn没有x,则第地址为15处的指令就该是add esp,3)
然后esp再add增加把三个输入的参数退掉
当前栈:(ebp=08,esp=08)
08 ...
假如上面的程序调整为:
F4 push ebp
F5 mov ebp,esp
F6 sub esp,04
....
FD add esp,04
FE pop ebp
FF retn 3
解释:
F6的作用就是给局部变量开辟空间
FD的作用就是给局部变量释放空间
我们要区分出变量与参数,假如在执行到F8处时:
当前栈:(ebp=03,esp=02)
02 DD
03 08
04 15(返回到15)
05 edx
06 ecx
07 eax
08 ...
我们凭借OD右下角栈区中(返回到15)来进行分界
在04处(返回到15)下面的是传入参数,[ebp+08],[ebp+0C],...
在04处(返回到15)上面的是局部变量,[ebp-04],[ebp-08],...
注意如果是用esp来定位栈区地址的话esp只有加没有减的,要小心计算