首页
社区
课程
招聘
[原创]加密与解密二版菜鸟学习笔记(1)-Anti-spy
发表于: 2005-2-1 15:11 14385

[原创]加密与解密二版菜鸟学习笔记(1)-Anti-spy

2005-2-1 15:11
14385

【文章标题】 菜鸟《加密与解密》二版学习笔记(1)-反调试,及OD中API断点的使用
【软件名称】Anti-spy.exe
【下载地址】《加密与解密》二版配套光盘
【使用工具】flyod 1.10
【保护方式】Anti-SPY : regmon filemon
【开发语言】MasM
【本文写于】2005-2-1
【软件简介】《加密与解密》二版,第10章反Anti练习程序。
―――――――――――――――――――――――――――――――――
【破解分析】
破解分析
1.--------------------------------------------------------------------------------------------
Od载入,来到入口代码:
00401000 A>/$  6A 01             push 1
00401002   |.  6A 00             push 0
00401004   |.  6A 00             push 0
00401006   |.  6A 00             push 0                                        ; /pModule = NULL
00401008   |.  FF15 00204000     call dword ptr ds:[<&KERNEL32.GetModuleHandle>; \GetModuleHandleA
0040100E   |.  50                push eax
0040100F   |.  E8 0C000000       call Anti-Spy.00401020 //应用程序入口

00401020   /$  8B4424 04         mov eax,dword ptr ss:[esp+4]                  ;  Anti-Spy.00400000
00401024   |.  6A 00             push 0                                        ; /lParam = NULL
00401026   |.  68 A0104000       push Anti-Spy.004010A0                        ; |DlgProc = Anti-Spy.004010A0
0040102B   |.  6A 00             push 0                                        ; |hOwner = NULL
0040102D   |.  6A 65             push 65                                       ; |pTemplate = 65
0040102F   |.  50                push eax                                      ; |hInst
00401030   |.  A3 08314000       mov dword ptr ds:[403108],eax                 ;
00401035   |.  FF15 20204000     call dword ptr ds:[<&USER32.DialogBoxParamA>] ; \DialogBoxParamA //产生对话
0040103B   |.  33C0              xor eax,eax
0040103D   \.  C2 1000           retn 10

00401014   |.  50                push eax                                      ; /ExitCode //结束进程
00401015   \.  FF15 0C204000     call dword ptr ds:[<&KERNEL32.ExitProcess>]   ; \ExitProcess
0040101B    .  C3                retn
0040101C       90                nop
2.--------------------------------------------------------------------------------------------
学习一下设置api断点:
参看一下当前模块中的和消息有关的api函数:
名称位于 Anti-Spy
地址       区段       类型    (  名称                                    注释
00402004   .rdata     导入    (    KERNEL32.CloseHandle
00402008   .rdata     导入    (    KERNEL32.CreateFileA
00402020   .rdata     导入    (    USER32.DialogBoxParamA
00402014   .rdata     导入    (    USER32.EndDialog
0040200C   .rdata     导入    (    KERNEL32.ExitProcess
00402040   .rdata     导入    (    USER32.FindWindowA
00402024   .rdata     导入    (    USER32.GetDesktopWindow
00402038   .rdata     导入    (    USER32.GetDlgItem
00402000   .rdata     导入    (    KERNEL32.GetModuleHandleA
00402028   .rdata     导入    (    USER32.GetWindowRect
00402030   .rdata     导入    (    USER32.LoadIconA
00402034   .rdata     导入    (    USER32.MessageBoxA
00401000   .text      导出         <ModuleEntryPoint>
0040201C   .rdata     导入    (    USER32.MoveWindow
00402018   .rdata     导入    (    USER32.PostMessageA //*******1
0040202C   .rdata     导入    (    USER32.SendDlgItemMessageA //是给对话里的控件发消息的,我们不需要,不管它.
0040203C   .rdata     导入    (    USER32.SendMessageA //*******2
/**********************************************************************
*********1看一下PostMessageA函数原型:
The PostMessage function places (posts) a message in the message queue (消息队列)associated with
the thread that created the specified window and then returns without waiting for the thread
to process the message. Messages in a message queue are retrieved by calls to the GetMessage or PeekMessage function.
翻译:  把消息放到当前创建了一个特定窗口的线程的消息队列里,然后不等待次线程处理这个消息就返回.
       消息队列里的消息通过调用GetMessage或PeekMessage函数来获得.
BOOL PostMessage(
    HWND hWnd,        // handle of destination window //当前窗口的句柄
    UINT Msg,        // message to post              //要送走的消息
    WPARAM wParam,        // first message parameter  //消息附加信息
    LPARAM lParam         // second message parameter //消息附加信息
   );
Return Values 返回值
If the function succeeds, the return value is nonzero. //成功,返回非0
If the function fails, the return value is zero.       //失败返回0
/**********************************************************************
********2看一下sendMessageA函数原型:
The SendMessage function sends the specified message to a window or windows.
The function calls the window procedure for the specified window and does not
return until the window procedure has processed the message. The PostMessage
function, in contrast, posts a message to a thread's message queue and returns immediately.
翻译: SendMessage函数给一个窗口或多个串口发送一个特定的消息.函数调用这个特定窗口的窗口过程,
      直到这个窗口过程处理了这个消息才返回.相对应的PostMessage函数是把消息发送到线程的消息队列里,并马上返回.
LRESULT SendMessage(
    HWND hWnd,        // handle of destination window //目标窗口的句柄
    UINT Msg,        // message to send              //要发送的消息
    WPARAM wParam,        // first message parameter//消息附加信息
    LPARAM lParam         // second message parameter//消息附加信息
   );
Return Values返回值
The return value specifies the result of the message processing and depends on the message sent.
/**********************************************************************
好了,看了这两个函数,设断点试试.
首先PostMessageA,好了开始:

00402018   .rdata     导入    (    USER32.PostMessageA //******* //在这里,按enter键
来到参考位置:
参考位于Anti-Spy:.text 到 USER32.PostMessageA
00401060   call dword ptr ds:[<&USER32.PostMessageA>]         USER32.PostMessageA

右键,选在每个命令上设断点,即bp PostMessageA 则发现任何操作都会中断到系统领空中.
中断太多了,不好用.

再试试sendMessageA,看解释它是给窗口过程发消息,并等待窗口过程处理消息,这正是我们需要的.
我们的目标是: 点了"检测"按钮,然后让程序处理这个消息,不就知道程序在干什么了吗.^_^

方法同上:
找到:
参考位于Anti-Spy:.text 到 USER32.SendMessageA //有3处
00401103   call dword ptr ds:[<&USER32.SendMessageA>]         USER32.SendMessageA // 会中断在系统领空
00401133   mov ebp,dword ptr ds:[<&USER32.SendMessageA>]      USER32.SendMessageA // 停在此指令处
00401217   mov edi,dword ptr ds:[<&USER32.SendMessageA>]      USER32.SendMessageA // 停在此指令处
右键,选在每个命令上设断点,即相当于在命令行bp SendMessageA,区别在于bp SendMessageA肯定会停在系统领空(即sendmessagea函数的第一条指令处),
而我们这种设断点的方法,会中断在那里,看上面的注释.这就是这两中设法的区别.

00401118    > \8B7424 34         mov esi,dword ptr ss:[esp+34]
0040111C    .  8B1D 38204000     mov ebx,dword ptr ds:[<&USER32.GetDlgItem>]   ;  USER32.GetDlgItem
00401122    .  6A 00             push 0                                        ; /lParam = 0
00401124    .  6A 00             push 0                                        ; |wParam = 0
00401126    .  68 F0000000       push 0F0                                      ; |Message = BM_GETCHECK
0040112B    .  68 FE030000       push 3FE                                      ; |/ControlID = 3FE (1022.) //是那个可选钮的ID
00401130    .  56                push esi                                      ; ||hWnd      
00401131    .  FFD3              call ebx                                      ; |\GetDlgItem
00401133    .  8B2D 3C204000     mov ebp,dword ptr ds:[<&USER32.SendMessageA>] ; |USER32.SendMessageA //停在这里
00401139    .  50                push eax                                      ; |hWnd
0040113A    .  FFD5              call ebp                                      ; \SendMessageA
0040113C    .  8B3D 34204000     mov edi,dword ptr ds:[<&USER32.MessageBoxA>]  ;  USER32.MessageBoxA
00401142    .  85C0              test eax,eax
00401144    .  74 24             je short Anti-Spy.0040116A
00401146    .  E8 95010000       call Anti-Spy.004012E0 //进入
{
004012E0   /$  6A 00             push 0                                        ; /hTemplateFile = NULL
004012E2   |.  68 80000000       push 80                                       ; |Attributes = NORMAL
004012E7   |.  6A 03             push 3                                        ; |Mode = OPEN_EXISTING
004012E9   |.  6A 00             push 0                                        ; |pSecurity = NULL
004012EB   |.  6A 03             push 3                                        ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
004012ED   |.  68 000000C0       push C0000000                                 ; |Access = GENERIC_READ|GENERIC_WRITE
004012F2   |.  68 BC304000       push Anti-Spy.004030BC                        ; |FileName = "\\.\REGVXD"
004012F7   |.  FF15 08204000     call dword ptr ds:[<&KERNEL32.CreateFileA>]   ; \CreateFileA //打开驱动文件,返回句柄
004012FD   |.  83F8 FF           cmp eax,-1  //找到会返回此文件句柄
00401300   |.  74 0D             je short Anti-Spy.0040130F //找到驱动,就不跳
00401302   |.  50                push eax                                      ; /hObject
00401303   |.  FF15 04204000     call dword ptr ds:[<&KERNEL32.CloseHandle>]   ; \CloseHandle //关闭文件
00401309   |.  B8 01000000       mov eax,1
0040130E   |.  C3                retn

0040130F   |>  68 84304000       push Anti-Spy.00403084                        ; /Title = "Registry Monitor - Sysinternals: www.sysinternals.com"
00401314   |.  6A 00             push 0                                        ; |Class = 0
00401316   |.  FF15 40204000     call dword ptr ds:[<&USER32.FindWindowA>]     ; \FindWindowA //实际是检查窗口标题
                                                                                //找到符合条件的顶级窗口,就返回此窗口句柄
                                                                                //没找到,返回0
0040131C   |.  F7D8              neg eax     //求补码
0040131E   |.  1BC0              sbb eax,eax //带借位减法
00401320   |.  F7D8              neg eax     //求补码
00401322   \.  C3                retn
举例分析:
eax=0x00000000时:  
neg eax ---> 0x00000000  CF=0
sbb eax,eax--->  0x00000000 - 0x00000000 -0=0x00000000
neg eax ---> 0x00000000  CF=0
eax=0x00000001时:  
neg eax ---> 0x00000001  CF=1
sbb eax,eax--->  0x00000001 - 0x00000001 -1=0xffffffff
neg eax ---> 0x00000001  CF=1
就是说,返回0时,运算结果为0
     返回非0时,运行结果为1
}
0040114B    .  85C0              test eax,eax               //判断一下
0040114D    .  6A 30             push 30
0040114F    .  74 0C             je short Anti-Spy.0040115D //=0就跳,表示没找到regmon或filemon
00401151    .  68 80304000       push Anti-Spy.00403080                        ;  ASCII "OK"
00401156    .  68 6C304000       push Anti-Spy.0040306C                        ;  ASCII "RegMON is Running!
"
0040115B    .  EB 0A             jmp short Anti-Spy.00401167
0040115D    >  68 64304000       push Anti-Spy.00403064                        ;  ASCII "Error"
00401162    .  68 40304000       push Anti-Spy.00403040                        ;  ASCII "Can't find RegMON with this method!"

00401167    >  56                push esi
00401168    .  FFD7              call edi //USER32.MessageBoxA
0040116A    >  6A 00             push 0
0040116C    .  6A 00             push 0
0040116E    .  68 F0000000       push 0F0
00401173    .  68 FF030000       push 3FF
00401178    .  56                push esi
00401179    .  FFD3              call ebx
0040117B    .  50                push eax
0040117C    .  FFD5              call ebp
0040117E    .  85C0              test eax,eax
00401180    .  0F84 40010000     je Anti-Spy.004012C6
00401186    .  E8 A5010000       call Anti-Spy.00401330
0040118B    .  85C0              test eax,eax
0040118D    .  6A 30             push 30
0040118F    .  74 1C             je short Anti-Spy.004011AD
00401191    .  68 80304000       push Anti-Spy.00403080                        ;  ASCII "OK"
00401196    .  68 28304000       push Anti-Spy.00403028                        ;  ASCII "FileMON is Running!
"
0040119B    .  56                push esi
0040119C    .  FFD7              call edi
0040119E    .  5F                pop edi
0040119F    .  5E                pop esi
004011A0    .  5D                pop ebp
004011A1    .  B8 01000000       mov eax,1
004011A6    .  5B                pop ebx
004011A7    .  83C4 20           add esp,20
004011AA    .  C2 1000           retn 10

相关api函数:
/****************************************************************
The CloseHandle function closes an open object handle. 关闭一个内核对象
BOOL CloseHandle(
    HANDLE hObject         // handle to object to close  
   );
Parameters
hObject
Identifies an open object handle.  // 一个打开的对象的句柄标识

Return Values
If the function succeeds, the return value is nonzero. //成功返回非0
If the function fails, the return value is zero.       //失败返回0
/****************************************************************
The CreateFile function creates or opens the following objects and returns
a handle that can be used to access the object: 创建或打开一个文件
HANDLE CreateFile(
    LPCTSTR lpFileName,                // pointer to name of the file  //指向文件名
    DWORD dwDesiredAccess,        // access (read-write) mode
    DWORD dwShareMode,                // share mode
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,        // pointer to security attributes
    DWORD dwCreationDistribution,                // how to create
    DWORD dwFlagsAndAttributes,        // file attributes
    HANDLE hTemplateFile         // handle to file with attributes to copy  
   );
Return Values//成功返回句柄
If the function succeeds, the return value is an open handle to the specified file.
If the specified file exists before the function call and dwCreationDistribution is CREATE_ALWAYS or OPEN_ALWAYS,
a call to GetLastError returns ERROR_ALREADY_EXISTS (even though the function has succeeded).
If the file does not exist before the call, GetLastError returns zero.
If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
/****************************************************************
The FindWindow function retrieves the handle to the top-level window whose class name
and window name match the specified strings. This function does not search child windows.
//翻译: FindWindow函数获得符合指定的类名和窗口名的顶级窗口的句柄.
HWND FindWindow(
    LPCTSTR lpClassName,        // pointer to class name  指向类名的指针
    LPCTSTR lpWindowName         // pointer to window name 指向窗口名的指针
   );
Return Values //成功,返回这个窗口的句柄,失败返回NULL
If the function succeeds, the return value is the handle to the window that has the specified class name and window name.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
―――――――――――――――――――――――――――――――――
【总结】
仅以学习为目的,知识是宝贵的,破解是次要的。
有些程序,不经过消息循环,通过sendmessagea发送消息后,就开始执行相应的处理代码,对于窗口的操作(如点按钮),在不知道设什么断点时,可以使用一下BP sendmessagea试试!当然这个断点也并不是总是好用的!
分析程序时,多查查api函数,会了解更多的底层的东西。
另:这个程序不能设置消息断点,请教大侠们指点一下。
我认为按下一个按钮就会,发送一个WM_COMAND消息,在通过消息循环处理。这个程序怎么不行呢?不会是没经过消息循环吧,那么怎么拦截这个按钮?
请大侠们多指点了!
感谢你看完此菜文!
―――――――――――――――――――――――――――――――――
本文由 <流行时代破文写手> 生成
http://www.popbase.net
附件:Anti-Spy.rar


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 12323
活跃值: (4040)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
收下学习
谢谢提供!
2005-2-1 17:20
0
雪    币: 47147
活跃值: (20445)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
最初由 ytcswb 发布

本文由 <流行时代破文写手> 生成
http://www.popbase.net
........


文章不错。不过这个生成器感觉开始几行处理的不好,没必要空一行。现在看不出,等制作CHM后,就看的不爽了。

建议再手工如下处理一下,这样省得制作论坛精华时,我再得一行行去空格行:

文章标题】 菜鸟《加密与解密》二版学习笔记(1)-反调试,及OD中API断点的使用

【软件名称】Anti-spy.exe
【下载地址】《加密与解密》二版配套光盘
【使用工具】flyod 1.10
【保护方式】Anti-SPY : regmon filemon
【开发语言】MasM
【本文写于】2005-2-1
【软件简介】《加密与解密》二版,第10章反Anti练习程序。
2005-2-1 19:10
0
雪    币: 214
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
收下学习,另外请楼主把这个软件放到论坛上好吗?
2005-2-2 01:36
0
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
冒看明白墨子你港的搂经,下次不要贴这么多API参考出来啦
2005-2-2 03:51
0
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
支持~~~UP
2005-2-2 03:52
0
雪    币: 332
活跃值: (479)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
7
不错啊,兄弟突飞猛进了,恭喜!
2005-2-2 09:40
0
雪    币: 225
活跃值: (146)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
最初由 阵雨 发布
冒看明白墨子你港的搂经,下次不要贴这么多API参考出来啦

谢谢,其实我也不希望把api加到代码中间,你能给个好些建议不吗?
2005-2-2 10:47
0
雪    币: 225
活跃值: (146)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
9
最初由 laoqian 发布
不错啊,兄弟突飞猛进了,恭喜!

谢谢laoqian兄鼓励了。^_^,准备利用过年这点空闲时间,多学习点。平时太忙没有大块时间系统 学习啊。。。。
2005-2-2 10:49
0
雪    币: 225
活跃值: (146)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
最初由 kanxue 发布



文章不错。不过这个生成器感觉开始几行处理的不好,没必要空一行。现在看不出,等制作CHM后,就看的不爽了。

........

老大给个好用的破文生成器如何?最好带着色的。。。。。
2005-2-2 10:51
0
雪    币: 332
活跃值: (479)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
11
其实加进来API参考也不错,可以加在文章尾部,比如:参考资料等
2005-2-2 11:13
0
雪    币: 117
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
最初由 ljy3282393 发布
收下学习,另外请楼主把这个软件放到论坛上好吗?


http://www.popbase.net/bbs/dispbbs.asp?boardID=47&ID=1895&page=1
请到流行时代下载
2005-2-2 12:57
0
雪    币: 225
活跃值: (146)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13
最初由 无奈无赖 发布


http://www.popbase.net/bbs/dispbbs.asp?boardID=47&ID=1895&page=1
请到流行时代下载

我用的就是这个破文生成器啊!。。。。。。。。。不过还是谢谢你了。。。。
另,根据laoqian兄建议,以后把api加到末尾。谢谢指点了^_^
2005-2-2 16:48
0
雪    币: 115
活跃值: (61)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
谢谢,认真学习
2005-2-2 18:24
0
雪    币: 204
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
利用此文研究一下消息函数还不错
2005-2-4 17:04
0
游客
登录 | 注册 方可回帖
返回
//