首页
社区
课程
招聘
[原创]菜鸟对一crackme的分析尝试
发表于: 2010-4-29 21:44 3348

[原创]菜鸟对一crackme的分析尝试

2010-4-29 21:44
3348
最近对驱动有了兴趣,虽然前面基础都没打好就看驱动是冒进,但还是忍不住看了下资料,哪怕是先对它有个初步了解也好

正好看到http://bbs.pediy.com/showthread.php?t=111235里有个驱动的crackme,就拿来试试了

进入虚拟机,先用od看看,载入crackme,运行后输入如下图,

下WM_COMMAND消息断点,按下按钮checkdata,来到消息处理函数入口00401880
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
00401880   .  8B4424 08     MOV EAX,DWORD PTR SS:[ESP+8]
00401884   .  83E8 10       SUB EAX,10                               ;  Switch (cases 10..111)
00401887   .  0F84 DE000000 JE DriverCr.0040196B
0040188D   .  2D 00010000   SUB EAX,100
00401892   .  74 7B         JE SHORT DriverCr.0040190F
00401894   .  48            DEC EAX
00401895   .  0F85 E2000000 JNZ DriverCr.0040197D
0040189B   .  8B4424 0C     MOV EAX,DWORD PTR SS:[ESP+C]             ;  Case 111 (WM_COMMAND) of switch 00401884
0040189F   .  2D EA030000   SUB EAX,3EA                              ;  Switch (cases 3EA..3ED)
004018A4   .  74 3F         JE SHORT DriverCr.004018E5
004018A6   .  48            DEC EAX
004018A7   .  74 25         JE SHORT DriverCr.004018CE
004018A9   .  83E8 02       SUB EAX,2
004018AC   .  0F85 CB000000 JNZ DriverCr.0040197D
004018B2   .  8B4424 04     MOV EAX,DWORD PTR SS:[ESP+4]             ;  Case 3ED of switch 0040189F
004018B6   .  6A 40         PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004018B8   .  68 AC614000   PUSH DriverCr.004061AC                   ; |Title = "About"
004018BD   .  68 78614000   PUSH DriverCr.00406178                   ; |Text = "Driver Crackme #1
Level - 5
Writen By Coderess
 "
004018C2   .  50            PUSH EAX                                 ; |hOwner
004018C3   .  FF15 DC504000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
004018C9   .  33C0          XOR EAX,EAX
004018CB   .  C2 1000       RETN 10
004018CE   >  E8 2DFFFFFF   CALL DriverCr.00401800                   ;  Case 3EB of switch 0040189F
004018D3   .  8B4C24 04     MOV ECX,DWORD PTR SS:[ESP+4]
004018D7   .  6A 00         PUSH 0                                   ; /Result = 0
004018D9   .  51            PUSH ECX                                 ; |hWnd
004018DA   .  FF15 D0504000 CALL DWORD PTR DS:[<&USER32.EndDialog>]  ; \EndDialog
004018E0   .  33C0          XOR EAX,EAX
004018E2   .  C2 1000       RETN 10

继续单步来到处理这个按钮消息的代码
00401510   $  51            PUSH ECX                                 ; /hTemplateFile = NULL
00401511      53            DB 53                                    ;  CHAR 'S'
00401512      56            DB 56                                    ;  CHAR 'V'
00401513      57            DB 57                                    ;  CHAR 'W'
00401514      6A            DB 6A                                    ;  CHAR 'j'
00401515      00            DB 00
00401516   .  68 80000000   PUSH 80                                  ; |Attributes = NORMAL
0040151B   .  6A 03         PUSH 3                                   ; |Mode = OPEN_EXISTING
0040151D   .  6A 00         PUSH 0                                   ; |pSecurity = NULL
0040151F   .  6A 00         PUSH 0                                   ; |ShareMode = 0
00401521   .  68 000000C0   PUSH C0000000                            ; |Access = GENERIC_READ|GENERIC_WRITE
00401526   .  68 68604000   PUSH DriverCr.00406068                   ; |FileName = "\\.\SymbolDCM1"
0040152B   .  FF15 4C504000 CALL DWORD PTR DS:[<&KERNEL32.CreateFile>; \CreateFileA   ; 打开设备\\.\SymbolDCM1
00401531   .  8BD8          MOV EBX,EAX
00401533   .  83FB FF       CMP EBX,-1                  
00401536   .  75 10         JNZ SHORT DriverCr.00401548                               ; 若打开失败,关闭退出
00401538   .  50            PUSH EAX                                 ; /hObject            
00401539   .  FF15 54504000 CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle         
0040153F   .  5F            POP EDI
00401540   .  5E            POP ESI
00401541   .  33C0          XOR EAX,EAX
00401543   .  5B            POP EBX
00401544   .  59            POP ECX
00401545   .  C2 0400       RETN 4
00401548   >  8B7424 14     MOV ESI,DWORD PTR SS:[ESP+14]
0040154C   .  8B3D D4504000 MOV EDI,DWORD PTR DS:[<&USER32.GetDlgIte>;  USER32.GetDlgItemTextA
00401552   .  6A 0F         PUSH 0F                                  ; /Count = F (15.)
00401554   .  68 34674000   PUSH DriverCr.00406734                   ; |Buffer = DriverCr.00406734
00401559   .  68 E8030000   PUSH 3E8                                 ; |ControlID = 3E8 (1000.)
0040155E   .  56            PUSH ESI                                 ; |hWnd
0040155F   .  FFD7          CALL EDI                                 ; \GetDlgItemTextA   ;取得用户名wxxw
00401561   .  83F8 0F       CMP EAX,0F                                 
00401564   .  0F87 94010000 JA DriverCr.004016FE
0040156A   .  85C0          TEST EAX,EAX
0040156C   .  0F84 8C010000 JE DriverCr.004016FE                       ;用户名只取前15个字符,错误则退出
00401572   .  50            PUSH EAX
00401573   .  68 34674000   PUSH DriverCr.00406734                   ;  ASCII "wxxw"
00401578   .  E8 83FAFFFF   CALL DriverCr.00401000                   ;用户名里不能含有字符“-._<>?=@#$%^&*()”
0040157D   .  83C4 08       ADD ESP,8
00401580   .  85C0          TEST EAX,EAX
00401582   .  0F84 76010000 JE DriverCr.004016FE
00401588   .  6A 1E         PUSH 1E
0040158A   .  68 14664000   PUSH DriverCr.00406614                   ;  ASCII "12345-67890-12345-67890-12345"
0040158F   .  68 E9030000   PUSH 3E9
00401594   .  56            PUSH ESI
00401595   .  FFD7          CALL EDI                                 ;取得License key,大小必须为29个字符
00401597   .  83F8 1D       CMP EAX,1D
0040159A   .  0F85 5E010000 JNZ DriverCr.004016FE
004015A0   .  6A 21         PUSH 21
004015A2   .  68 50684000   PUSH DriverCr.00406850                   ;  ASCII "111111111111111111111111111111"
004015A7   .  68 EC030000   PUSH 3EC
004015AC   .  56            PUSH ESI
004015AD   .  FFD7          CALL EDI
004015AF   .  83F8 20       CMP EAX,20                                ;取得注册码,大小必须为32个字符
004015B2   .  0F85 46010000 JNZ DriverCr.004016FE
004015B8   .  68 14664000   PUSH DriverCr.00406614                   ;  ASCII "12345-67890-12345-67890-12345"
004015BD   .  E8 0EFBFFFF   CALL DriverCr.004010D0                    ;licence key里不能含有字符“~!@#$%^&*()”
004015C2   .  83C4 04       ADD ESP,4
004015C5   .  84C0          TEST AL,AL
004015C7   .  0F84 31010000 JE DriverCr.004016FE
004015CD   .  8A0D 19664000 MOV CL,BYTE PTR DS:[406619]
004015D3   .  B0 2D         MOV AL,2D
004015D5   .  3AC8          CMP CL,AL
004015D7   .  0F85 21010000 JNZ DriverCr.004016FE
004015DD   .  3805 1F664000 CMP BYTE PTR DS:[40661F],AL
004015E3   .  0F85 15010000 JNZ DriverCr.004016FE
004015E9   .  3805 25664000 CMP BYTE PTR DS:[406625],AL
004015EF   .  0F85 09010000 JNZ DriverCr.004016FE
004015F5   .  3805 2B664000 CMP BYTE PTR DS:[40662B],AL              ;licence key的第6,12,18,24位必须为“-”
004015FB   .  0F85 FD000000 JNZ DriverCr.004016FE
00401601   .  68 50684000   PUSH DriverCr.00406850                   ;  ASCII "111111111111111111111111111111"
00401606   .  E8 C5FAFFFF   CALL DriverCr.004010D0                   ;同样注册码里不能含有字符“~!@#$%^&*()”
0040160B   .  83C4 04       ADD ESP,4
0040160E   .  84C0          TEST AL,AL
00401610   .  0F84 E8000000 JE DriverCr.004016FE
00401616   .  68 34674000   PUSH DriverCr.00406734                   ;  ASCII "wxxw"
0040161B   .  E8 D0FCFFFF   CALL DriverCr.004012F0                    ;将wxxw转换成jkkj
00401620   .  BF 34674000   MOV EDI,DriverCr.00406734                ;  ASCII "jkkj"
00401625   .  83C9 FF       OR ECX,FFFFFFFF
00401628   .  33C0          XOR EAX,EAX
0040162A   .  F2:AE         REPNE SCAS BYTE PTR ES:[EDI]
0040162C   .  F7D1          NOT ECX
0040162E   .  49            DEC ECX
0040162F   .  51            PUSH ECX
00401630   .  68 34674000   PUSH DriverCr.00406734                   ;  ASCII "jkkj"
00401635   .  E8 36FAFFFF   CALL DriverCr.00401070                   ;对jkkj处理返回EAX=27FB
0040163A   .  50            PUSH EAX                                 ; |Arg2= 27FB
0040163B   .  68 34674000   PUSH DriverCr.00406734                   ; |Arg1 = 00406734 ASCII "jkkj"
00401640   .  E8 5BFDFFFF   CALL DriverCr.004013A0                   ; \DriverCr.004013A0 ;继续处理得到"jkkj;;27fb;;6b63763a;;"
00401645   .  8B35 3C504000 MOV ESI,DWORD PTR DS:[<&KERNEL32.lstrcat>;  kernel32.lstrcatA
0040164B   .  83C4 14       ADD ESP,14
0040164E   .  68 14664000   PUSH DriverCr.00406614                   ; /StringToAdd = "12345-67890-12345-67890-12345"
00401653   .  68 44674000   PUSH DriverCr.00406744                   ; |ConcatString =  "jkkj;;27fb;;6b63763a;;"
00401658   .  FFD6          CALL ESI                                 ; \lstrcatA
0040165A   .  68 A0604000   PUSH DriverCr.004060A0                   ; /StringToAdd = ";;"
0040165F   .  68 44674000   PUSH DriverCr.00406744                   ; |ConcatString =
00401664   .  FFD6          CALL ESI                                 ; \lstrcatA
00401666   .  68 50684000   PUSH DriverCr.00406850                   ; /StringToAdd = "111111111111111111111111111111"
0040166B   .  68 44674000   PUSH DriverCr.00406744                   ; |ConcatString =
00401670   .  FFD6          CALL ESI                                 ; \lstrcatA ;将上面的都连起来得到字符串
                jkkj;;27fb;;6b63763a;;12345-67890-12345-67890-12345;;11111111111111111111111111111111

00401672   .  B9 3F000000   MOV ECX,3F
00401677   .  33C0          XOR EAX,EAX
00401679   .  BF 34664000   MOV EDI,DriverCr.00406634                ;  ASCII "WORLD"
0040167E   .  6A 00         PUSH 0                                   ; /pOverlapped = NULL
00401680   .  F3:AB         REP STOS DWORD PTR ES:[EDI]              ; |
00401682   .  66:AB         STOS WORD PTR ES:[EDI]                   ; |
00401684   .  AA            STOS BYTE PTR ES:[EDI]                   ; |
00401685   .  8D4424 10     LEA EAX,DWORD PTR SS:[ESP+10]            ; |
00401689   .  BF 44674000   MOV EDI,DriverCr.00406744                ; |ASCII
0040168E   .  50            PUSH EAX                                 ; |pBytesReturned
0040168F   .  83C9 FF       OR ECX,FFFFFFFF                          ; |
00401692   .  33C0          XOR EAX,EAX                              ; |
00401694   .  68 FF000000   PUSH 0FF                                 ; |OutBufferSize = FF (255.)
00401699   .  F2:AE         REPNE SCAS BYTE PTR ES:[EDI]             ; |
0040169B   .  F7D1          NOT ECX                                  ; |
0040169D   .  68 34664000   PUSH DriverCr.00406634                   ; |OutBuffer = DriverCr.00406634
004016A2   .  51            PUSH ECX                                 ; |InBufferSize
004016A3   .  68 44674000   PUSH DriverCr.00406744                   ; |InBuffer = DriverCr.00406744
004016A8   .  68 08202200   PUSH 222008                              ; |IoControlCode = 222008
004016AD   .  53            PUSH EBX                                 ; |hDevice
004016AE   .  FF15 44504000 CALL DWORD PTR DS:[<&KERNEL32.DeviceIoCo>; \DeviceIoControl
传入字符“jkkj;;27fb;;6b63763a;;12345-67890-12345-67890-12345;;11111111111111111111111111111111"给驱动,输出结果到00406634
004016B4   .  85C0          TEST EAX,EAX
004016B6   .  74 3F         JE SHORT DriverCr.004016F7
004016B8   .  B9 34664000   MOV ECX,DriverCr.00406634                ;  ASCII "WORLD"
004016BD   .  85C9          TEST ECX,ECX
004016BF   .  74 23         JE SHORT DriverCr.004016E4
004016C1   .  68 C0604000   PUSH DriverCr.004060C0                   ; /String2 = "REGISTRED"
004016C6   .  51            PUSH ECX                                 ; |String1 => "WORLD"
004016C7   .  FF15 48504000 CALL DWORD PTR DS:[<&KERNEL32.lstrcmpA>] ; \lstrcmpA ;将上面驱动传回的字符与”REGISTRED“比较
004016CD   .  85C0          TEST EAX,EAX
004016CF   .  75 26         JNZ SHORT DriverCr.004016F7
004016D1   .  6A 40         PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004016D3   .  68 B8604000   PUSH DriverCr.004060B8                   ; |Title = "Done"
004016D8   .  68 A4604000   PUSH DriverCr.004060A4                   ; |Text = "Successfully done!"
004016DD   .  50            PUSH EAX                                 ; |hOwner
004016DE   .  FF15 DC504000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
004016E4   >  53            PUSH EBX                                 ; /hObject
004016E5   .  FF15 54504000 CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle
004016EB   .  5F            POP EDI
004016EC   .  5E            POP ESI
004016ED   .  B8 01000000   MOV EAX,1
004016F2   .  5B            POP EBX
004016F3   .  59            POP ECX
004016F4   .  C2 0400       RETN 4
004016F7   > \53            PUSH EBX                                 ; /hObject
004016F8   .  FF15 54504000 CALL DWORD PTR DS:[<&KERNEL32.CloseHandl>; \CloseHandle
004016FE   >  5F            POP EDI
004016FF   .  5E            POP ESI
00401700   .  33C0          XOR EAX,EAX
00401702   .  5B            POP EBX
00401703   .  59            POP ECX
00401704   .  C2 0400       RETN 4
[/code]
关闭OD,看样子关键在驱动里,查看了些资料,发现驱动就是处理IRP,跟消息处理差不多,不过它是每个IRP对应了一个处理函数,一堆IRP对应有一堆处理函数,组成一个函数

指针数组在driver_object结构里,这个driver_object结构又是driverentry的入口参数
NTSTATUS
  DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING  RegistryPath
    );
查到常用IRP如下
IRP_MJ_CREATE                                        equ 0
IRP_MJ_CREATE_NAMED_PIPE                equ 1
IRP_MJ_CLOSE                                        equ 2
IRP_MJ_READ                                                equ 3
IRP_MJ_WRITE                                        equ 4
IRP_MJ_QUERY_INFORMATION                equ 5
IRP_MJ_SET_INFORMATION                        equ 6
IRP_MJ_QUERY_EA                                        equ 7
IRP_MJ_SET_EA                                        equ 8
IRP_MJ_FLUSH_BUFFERS                        equ 9
IRP_MJ_QUERY_VOLUME_INFORMATION        equ 0Ah
IRP_MJ_SET_VOLUME_INFORMATION        equ 0Bh
IRP_MJ_DIRECTORY_CONTROL                equ 0Ch
IRP_MJ_FILE_SYSTEM_CONTROL                equ 0Dh
IRP_MJ_DEVICE_CONTROL                        equ 0Eh
IRP_MJ_INTERNAL_DEVICE_CONTROL        equ 0Fh
IRP_MJ_SHUTDOWN                                        equ 10h
IRP_MJ_LOCK_CONTROL                                equ 11h
IRP_MJ_CLEANUP                                        equ 12h
IRP_MJ_CREATE_MAILSLOT                        equ 13h
IRP_MJ_QUERY_SECURITY                        equ 14h
IRP_MJ_SET_SECURITY                                equ 15h
IRP_MJ_POWER                                        equ 16h
IRP_MJ_SYSTEM_CONTROL                        equ 17h
IRP_MJ_DEVICE_CHANGE                        equ 18h
IRP_MJ_QUERY_QUOTA                                equ 19h
IRP_MJ_SET_QUOTA                                equ 1Ah
IRP_MJ_PNP                                                equ 1Bh
IRP_MJ_PNP_POWER                                equ IRP_MJ_PNP        ; Obsolete....
IRP_MJ_MAXIMUM_FUNCTION                        equ 1Bh
上面程序调用DeviceIoControl函数应该对应发送了IRP_MJ_DEVICE_CONTROL给驱动,所以对应函数指针在数组入口+0e*4的位置
用lordpe可以得到driver.sys的DriverEntry在515F,在本机的windbg里下断点bu driver!515f,在虚拟机里运行Crackme,,中断在windbg里
driver+0x515f:
f790c15f 8bff            mov     edi,edi
堆栈esp=f7996c80,查看该处内存,f7996c80: 5c 68 57 80 c0 62 d7 85 00 c0 b5 85 00 00 00
(对windbg还不熟悉,可能用OD用惯了,所以按照OD的布局开了四个窗口,一个汇编,一个寄存器,一个内存,一个堆栈,但堆栈实在不好用,不知道大家是怎么弄的,有什么

好建议分享下哈)
可以得到esp+4为Driver_object,即85d762c0
先看下driver_object结构,输入dt nt!_driver_object
kd> dt nt!_driver_object 85d762c0
   +0x000 Type             : 4
   +0x002 Size             : 168
   +0x004 DeviceObject     : 0x85e71e00 _DEVICE_OBJECT
   +0x008 Flags            : 0x12
   +0x00c DriverStart      : 0xf7907000
   +0x010 DriverSize       : 0x7000
   +0x014 DriverSection    : 0x85b7ca30
   +0x018 DriverExtension  : 0x85d76368 _DRIVER_EXTENSION
   +0x01c DriverName       : _UNICODE_STRING "\Driver\ServiceDriver"
   +0x024 HardwareDatabase : 0x8066fd58 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
   +0x028 FastIoDispatch   : (null)
   +0x02c DriverInit       : 0xf790c15f     long  +0
   +0x030 DriverStartIo    : (null)
   +0x034 DriverUnload     : 0xf790b83a     void  +0
   +0x038 MajorFunction    : [28] 0xf790b7d8     long  +0

在windbg里按G运行,先加载完驱动,然后输入 dd 85d762c0+38看看函数指针数组吧
85d762f8  f790b7d8 804f4418 f790b7d8 804f4418
85d76308  804f4418 804f4418 804f4418 804f4418
85d76318  804f4418 804f4418 804f4418 804f4418
85d76328  804f4418 804f4418 f790b974 804f4418
85d76338  804f4418 804f4418 804f4418 804f4418
85d76348  804f4418 804f4418 804f4418 804f4418
85d76358  804f4418 804f4418 804f4418 804f4418
找到0E号IRP对应的为f790b974
当然也可以直接用
kd> dd 85d762c0+38+0E*4 L1
85d76330  f790b974
找到处理函数了,现在就直接下断,bp f790b974
这里有个问题就是如何对函数指针下断??比如上面的,我想用 bp  [85d762c0+38+0E*4] 或者bp *(long*)(85d762c0+38+0E*4)都报语法错。。。。。
好了,现在按照上图输入用户名注册码,点checkdata,呵呵,被断下来了,算法分析还太菜,弄得晕头转向,暂时到这儿吧

2010.5.3
找到对函数指针下断的方法了,是用poi
如上面的,可以下断 bp poi(85d762c0+38+0E*4)

[注意]看雪招聘,专注安全领域的专业人才平台!

上传的附件:
收藏
免费
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册