-
-
[原创]菜鸟对一crackme的分析尝试
-
发表于: 2010-4-29 21:44 3348
-
最近对驱动有了兴趣,虽然前面基础都没打好就看驱动是冒进,但还是忍不住看了下资料,哪怕是先对它有个初步了解也好
正好看到http://bbs.pediy.com/showthread.php?t=111235里有个驱动的crackme,就拿来试试了
进入虚拟机,先用od看看,载入crackme,运行后输入如下图,

下WM_COMMAND消息断点,按下按钮checkdata,来到消息处理函数入口00401880
继续单步来到处理这个按钮消息的代码
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)
正好看到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)
赞赏
他的文章
- [原创]cs 透视初步尝试 15313
- 中毒了,怎么处理,帮看看 9644
- [原创]qqgame 升级的秘密[1楼、36楼更新](已失效) 22043
- [原创]菜鸟也做注册机 12080
- [原创]QQGAME挤房改造 10294
赞赏
雪币:
留言: