首页
社区
课程
招聘
我的学习日记贴
发表于: 2007-1-24 17:59 10315

我的学习日记贴

2007-1-24 17:59
10315
收藏
免费 7
支持
分享
最新回复 (18)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习了,竟然是传说中的沙发。。
2007-1-24 18:03
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
由于无发再次发贴,因此我只好在自已的贴里编辑贴,以使能有更多的信息可见.更有可能得到各位大大的回复.

独占模式程序调试

学习对象:
StarCraft 1.08 (以下简称SC)

学习目标:
将其由全屏独占模式更改为窗口模式

工具:
OllyDBG(下载中心当的OllyICE).



另:跟踪过程中发现SC还加载了其目录下后缀为SNP的模块作网络通讯用,但时机还未知.


解决办法:
1.SetCooperativeLevel
004DEAE8      6A 08         push    13                               
004DEAEA  |.  52            push    edx
004DEAEB  |.  8B08          mov     ecx, dword ptr [eax]
004DEAED  |.  50            push    eax
004DEAEE  |.  FF51 50       call    dword ptr [ecx+50]               ;  <ddraw.SetCooperativeLevel>

将指令push 13换为push 8  ( DDSCL_ALLOWREBOOT|DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN --> DDSCL_NORMAL)


2.SetDisplayMode(注意,有两处调用,另外在处理后还需修改调色版,可以用加区段的办法)
004DEB48  |.  6A 08         push    8
004DEB4A  |.  50            push    eax
004DEB4B  |.  8B11          mov     edx, dword ptr [ecx]
004DEB4D  |.  57            push    edi
004DEB4E  |.  51            push    ecx
004DEB4F  |.  FF52 54       call    dword ptr [edx+54];  这里是SetDislayMode
将此调用换为xor eax,eax
其它的NOP掉.
2007-1-24 18:12
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
;作者:CNBlastMAN
;函数功能:计算检验字
;参数: ecx  =>数据缓冲指针  edx        =>数据长度
;返回: ax   =>校验字

0BAA20E0 >  51              push    ecx                                     ; 保护ecx        //函数功能:计算检验字
0BAA20E1    56              push    esi                                     ; 保护esi
0BAA20E2    83C2 FE         add     edx, -2                                 ; edx=edx-2; //edx保存的是长度
0BAA20E5    83C1 02         add     ecx, 2                                  ; ecx=ecx+2; //ecx指向数据开始第三个字节
0BAA20E8    E8 53EFFFFF     call    <求和取余>                                  ; 求和取余
0BAA20ED    25 FFFF0000     and     eax, 0FFFF                              ; eax=eax&0xffff; //eax=LOWORD(<求和取余>函数的返回值)
0BAA20F2    B9 FF000000     mov     ecx, 0FF                                ; ecx=0xff; //ecx=255
0BAA20F7    8BF0            mov     esi, eax                                ; esi=eax; //将<求和取余>的结果保存到esi
0BAA20F9    25 FF000000     and     eax, 0FF                                ; eax=LOBYTE(LOWORD(eax));
0BAA20FE    C1EE 08         shr     esi, 8                                  ; esi=esi>>8; //esi=HIBYTE(LOWORD(esi)),shr,补0
0BAA2101    03C6            add     eax, esi                                ; eax=eax+esi; //eax=LOBYTE(LOWORD(eax))+HIBYTE(LOWORD(esi))
0BAA2103    99              cdq                                             ; 除法准备; //用eax的符号位填充edx的所有位
0BAA2104    F7F9            idiv    ecx                                     ; eax=eax/255,edx=eax%255;
0BAA2106    0AC1            or      al, cl                                  ; al=0xff; //al=al|cl = 0x00|0xff  ===> al=LOBYTE(AX)|LOBYTE(CX)
0BAA2108    2AC2            sub     al, dl                                  ; al=al-dl; //al=0xff-余数 (al=0xff-dl)
0BAA210A    884424 04       mov     byte ptr [esp+4], al                    ; //这里其实破坏了堆栈中的数据,不知道是不是故意这么做的.
0BAA210E    8B4C24 04       mov     ecx, dword ptr [esp+4]                  ; //
0BAA2112    81E1 FF000000   and     ecx, 0FF                                ; ecx=al;
0BAA2118    8D0431          lea     eax, dword ptr [ecx+esi]                ; eax=al+esi;
0BAA211B    BE FF000000     mov     esi, 0FF                                ; esi=0xff;
0BAA2120    99              cdq                                             ; 除法准备; //用eax的符号位填充edx的所有位
0BAA2121    F7FE            idiv    esi                                     ; eax=eax/255,edx=eax%255;
0BAA2123    C1E1 08         shl     ecx, 8                                  ; ecx=ecx<<8; //shl,补0
0BAA2126    0C FF           or      al, 0FF                                 ; al=0xff;
0BAA2128    2AC2            sub     al, dl                                  ; al=al-dl; //见上一个对此语句的说明
0BAA212A    23C6            and     eax, esi                                ; eax=eax&0xff; //eax=eax&esi  ==>eax=LOBYTE(LOWORD(eax)
0BAA212C    5E              pop     esi                                     ; 恢复esi
0BAA212D    0BC1            or      eax, ecx                                ; eax=eax|ecx; //RetVal=eax,由上面的处理来看,相当于eax=MAKEWORD(ch,al)
0BAA212F    59              pop     ecx                                     ; 恢复ecx
0BAA2130    C3              retn

;函数功能:求和取余:
0BAA1040 >  53              push    ebx                                     ; 保护ebx; //函数功能:求和取余
0BAA1041    56              push    esi                                     ; 保护esi
0BAA1042    33DB            xor     ebx, ebx                                ; ebx=0;
0BAA1044    33F6            xor     esi, esi                                ; esi=0;
0BAA1046    8D4C11 FF       lea     ecx, dword ptr [ecx+edx-1]              ; ecx=ecx+edx-1; //ecx指向数据尾部字节,表达式中ecx为数据起始地址,edx=12  =>数据长度(14)-2
0BAA104A    8BC2            mov     eax, edx                                ; eax=edx; //eax=数据长度
0BAA104C    4A              dec     edx                                     ; edx--;
0BAA104D    85C0            test    eax, eax
0BAA104F    74 1F           je      short 0BAA1070                          ; if(eax==0) jmp 0BAA1070 //没有数据处理则跳转
0BAA1051    57              push    edi                                     ; else{ //变量保护
0BAA1052    8D7A 01         lea     edi, dword ptr [edx+1]                  ; edi=edx+1; //edi=eax=数据长度
0BAA1055    33D2            xor     edx, edx                                ; do{ edx=0; //此循环将数据的字节从尾部开始相加,当大于255时取大于部分累加成和,并保存到ecx,一直处理到缓冲的第3个字节为止,也就是此函数开始指所提供的ecx
0BAA1057    8A11            mov     dl, byte ptr [ecx]                      ; dl=(byte)*ecx; //dl=数据尾部字节
0BAA1059    03DA            add     ebx, edx                                ; ebx=ebx+dl; //ebx=ebx+数据尾部字节的值
0BAA105B    49              dec     ecx                                     ; ecx=ecx-1; //ecx向数据首部方向移动一字节
0BAA105C    81FB FF000000   cmp     ebx, 0FF                                ; if(ebx>=255) ebx-=255;
0BAA1062    72 06           jb      short 0BAA106A                          ; //
0BAA1064    81EB FF000000   sub     ebx, 0FF                                ; //endif
0BAA106A    03F3            add     esi, ebx                                ; esi=esi+ebx;
0BAA106C    4F              dec     edi                                     ; edi--;
0BAA106D  ^ 75 E6           jnz     short 0BAA1055                          ; }while(edi==0);
0BAA106F    5F              pop     edi                                     ; 恢复edi
0BAA1070    8BC6            mov     eax, esi                                ; eax=esi; //加的结果保存到eax
0BAA1072    33D2            xor     edx, edx                                ; edx=0;
0BAA1074    B9 FF000000     mov     ecx, 0FF                                ; ecx=0xff; //ecx=255
0BAA1079    5E              pop     esi                                     ; 恢复esi
0BAA107A    F7F1            div     ecx                                     ; eax=eax/255,edx=eax%255;
0BAA107C    33C0            xor     eax, eax                                ; eax=0
0BAA107E    8AC2            mov     al, dl                                  ; al=dl; //al=和的结果除以255的余数
0BAA1080    8AE3            mov     ah, bl                                  ; ah=bl; //bl=字节总和除以255的余(看上面的循环)
0BAA1082    5B              pop     ebx
0BAA1083    C3              retn                                            ; 返回eax; //eax=MAKEWORD(bl,dl)
2007-1-24 18:33
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
5
还不会看OD脚本

具体可以参考插件里的帮助文件

F7跟SHIFT+F7的区别,随便写代码产生异常,然后按F7没反应,按SHIFT+F7,你就可以看到系统处理异常的代码了。
2007-1-24 20:57
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
下午又跑了N次.给自己留点东西:
1.关于同步对象(如事件或临界变量)的下断注意事项.
  多线程程序中(现在基本不考虑单线程程序的存在了,如了部分壳的解码程序)
  如果下断函数WaitXXX,大多数情况下会导致目标程序崩溃.
  必须断在WaitXXX函数被调用之后,对临界区来说,就是EnterXXX.

2.send/recv被调用后,不要在其使用的缓冲上下访问断点,除非你已经清楚的知道目标程序所使用的通信模型是阻塞模型,而且在处理完该缓冲之前不会被投递到核心态事务,否则会使OD非法跳出.注:OD是一个用户级调试器.

3.尽可能的在某个函数上下断之前先读一下该函数的代码.根据其调用的外部函数和结构判断其功能,并在确定功能之后为其编辑标签.

4.[壳相关]
  粗跟壳的时候,在步过时会产生异常的地方,使用步入多半不会抛异常.
  一般比较牛的壳,在跟得比较深入了的时候,除了非常熟悉的壳,千万不要用ALT+F9,否则之前的东西会付之流水...



[天黑了]

读Themida的解码代码(不知道版本,也不知道其是否使用驱动).跳来跳去的头都晕了.先F8了一遍.除了会产生异常的地方,其它我都F8了.我现在的水平要研究这个无疑是大海捞针.不过跟了总是有益无害嘛.纯粹属于娱乐性质..
开个玩笑.只要你有时间,F7才是天下最牛的武器...呵


1.有一段解壳执行代码,将每个字节减1,总共7000h个字节,处理完后跳到处理后的代码执行(类似的有好几处).

00960354    FE0F            dec     byte ptr [edi]                          ; 还原后面要运行的指令,0096035A处开始,大小(7000h),每个字节减1
00960356    47              inc     edi
00960357    49              dec     ecx
00960358  ^ 75 FA           jnz     short 00960354


执行到这里的时候需要步入,否则会抛出异常,所以用F7:

00960388    E8 03000000     call    00960390

//-------------------跟进去后会用到下面这段代码.
009603DD    8BCA            mov     ecx, edx                                ; ecx=UPX段偏移
009603DF    33FF            xor     edi, edi
009603E1    66:8138 4D5A    cmp     word ptr [eax], 5A4D                    ; 比较MZ标志,跳到模块头部
009603E6    75 0E           jnz     short 009603F6
009603E8    0FB750 3C       movzx   edx, word ptr [eax+3C]
009603EC    03D0            add     edx, eax
009603EE    813A 50450000   cmp     dword ptr [edx], 4550
009603F4    74 08           je      short 009603FE
009603F6    2D 00100000     sub     eax, 1000
009603FB    47              inc     edi
009603FC  ^ EB E3           jmp     short 009603E1
009603FE    64:8F05 0000000>pop     dword ptr fs:[0]                        ; 设置异常处理程序
00960405    83C4 04         add     esp, 4
00960408    8D95 87378206   lea     edx, dword ptr [ebp+6823787]
0096040E    52              push    edx
0096040F    64:FF35 0000000>push    dword ptr fs:[0]                        ; 保存异常处理,替换为ESP中的值
00960416    64:8925 0000000>mov     dword ptr fs:[0], esp                   ; 替换异常处理=0012ffe0
0096041D    03C1            add     eax, ecx                                ; 文件基址+UPX段偏移
0096041F    2D 00100000     sub     eax, 1000                               ; eax=CreateFileA函数地址,准备驱动解码,注:CreateFileA存放于 UPX段地址+1000处(是UPX段地址而不是UPX段偏移)
00960424    8B70 04         mov     esi, dword ptr [eax+4]                  ; esi=ExitProcess
00960427    81E6 0000FFFF   and     esi, FFFF0000                           ; esi=Kernel32的模块基址+10000h
0096042D    81FE 00000080   cmp     esi, 80000000
00960433    76 03           jbe     short 00960438
00960435    8B70 1C         mov     esi, dword ptr [eax+1C]
00960438    33C0            xor     eax, eax                                ; eax清0,作为计数,准备取模块基址
0096043A    83F8 32         cmp     eax, 32                                 ; 计数eax等于32次,则跳转
0096043D    74 1F           je      short 0096045E
0096043F    66:813E 4D5A    cmp     word ptr [esi], 5A4D                    ; 比较esi是否模块基址
00960444    74 09           je      short 0096044F                          ; 是则跳转
00960446    81EE 00000100   sub     esi, 10000                              ; 不是则将esi-10000
0096044C    40              inc     eax                                     ; 计数eax+1
0096044D  ^ EB EB           jmp     short 0096043A
0096044F    8B7E 3C         mov     edi, dword ptr [esi+3C]                 ; 已取到模块基址,edi=PE头偏移
00960452    03FE            add     edi, esi                                ; edi=edi+esi; //edi=PE头地址
00960454    813F 50450000   cmp     dword ptr [edi], 4550                   ; 取PE头的标志字与"PE"比较,验证是否正确的PE头
0096045A    74 44           je      short 009604A0                          ; 是则跳转下一个处理(009604A0),否则重新取模块基址

009604A0    96              xchg    eax, esi                                ; PE头正确,设置ecx=eax,eax=模块基址
009604A1    64:8F05 0000000>pop     dword ptr fs:[0]                        ; 恢复异常处理


2.在跟到大概八九个VirtualAlloc(,,,40(EXECUTE_READWRITE))的调用后(马上就要正式解码了,可惜不小心F8跑飞了..),于是点支烟,直接Ctrl+F2...


//---------------------------------------------------
来了回一直F7(我纯粹是找死)..发现这段被执行了N次(要睡了,跟到这里有点犯困,来不及写注释,有点想放弃了):

00960205    55              push    ebp
00960206    8BEC            mov     ebp, esp
00960208    81C4 7CFFFFFF   add     esp, -84
0096020E    60              pushad
0096020F    E8 00000000     call    00960214
00960214    5A              pop     edx
00960215    81EA 1E358206   sub     edx, 682351E
0096021B    8D45 80         lea     eax, dword ptr [ebp-80]
0096021E    8B5D 08         mov     ebx, dword ptr [ebp+8]
00960221    C785 7CFFFFFF 0>mov     dword ptr [ebp-84], 0
0096022B    8B8D 7CFFFFFF   mov     ecx, dword ptr [ebp-84]
00960231    D1C3            rol     ebx, 1
00960233    8818            mov     byte ptr [eax], bl
00960235    41              inc     ecx
00960236    898D 7CFFFFFF   mov     dword ptr [ebp-84], ecx
0096023C    81BD 7CFFFFFF 8>cmp     dword ptr [ebp-84], 80
00960246  ^ 75 E3           jnz     short 0096022B
00960248    C785 7CFFFFFF 0>mov     dword ptr [ebp-84], 0
00960252    8DBA 3F348206   lea     edi, dword ptr [edx+682343F]
00960258    8D75 80         lea     esi, dword ptr [ebp-80]
0096025B    8A0E            mov     cl, byte ptr [esi]
0096025D    BB F4010000     mov     ebx, 1F4
00960262    B8 AB375478     mov     eax, 785437AB
00960267    D3D0            rcl     eax, cl
00960269    8A0F            mov     cl, byte ptr [edi]
0096026B    D3D0            rcl     eax, cl
0096026D    4B              dec     ebx
0096026E  ^ 75 F7           jnz     short 00960267
00960270    0FAFC3          imul    eax, ebx
00960273    47              inc     edi
00960274    46              inc     esi
00960275    8B8D 7CFFFFFF   mov     ecx, dword ptr [ebp-84]
0096027B    41              inc     ecx
0096027C    898D 7CFFFFFF   mov     dword ptr [ebp-84], ecx
00960282    81F9 80000000   cmp     ecx, 80
00960288  ^ 75 D1           jnz     short 0096025B
0096028A    61              popad
0096028B    C9              leave
0096028C    C2 0400         retn    4
2007-1-24 21:06
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
睡前顶一下,为明天留出补贴的位置!
2007-1-24 22:01
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
吃饭之前先补个位.
2007-1-28 12:02
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
9
GOOD.加个精华,以示鼓励,希望楼主继续更新下去。另外有什么不明白的也可以提出,我会尽可能告诉你如何查找你需要的资料的
2007-1-28 13:24
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
没想到有这样的意外收获,谢谢版主鼓励,顺便占个位...
2007-1-29 00:13
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
11
支持更新!
2007-1-29 10:00
0
雪    币: 91
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
顶一下.

学习断同步线程的方法.
2007-1-30 09:46
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
13
如果用了驱动,调试,你就蓝了,对于驱动,要双机调试,在反调试代码开始之前开始调试才可以。

或者静态分析
2007-1-30 12:40
0
雪    币: 208
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
我要好好学习一下
2007-1-31 11:15
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
com
15
学习了,感谢帖主发出来给大家分享!
2007-1-31 13:43
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
年关了..事情比较多.只有年后再继续了.
在此谢谢版主和各位朋友的鼓励.
2007-2-5 14:12
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
不错,帮你顶
2007-2-5 15:11
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
18
星际争霸和Themida有啥关系?
2007-2-5 17:04
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
有模糊的关系
2009-8-22 01:50
0
游客
登录 | 注册 方可回帖
返回
//