= 66、InstallShield Pro 5 Build 221 for Win95 ======================================================= How to find the password of IS5P221.exe(InstallShield PrfessionalEdition 5.0, build 221) ======================================================================================== Tools that I used: 1. SoftIce for NT. 2. Windows NT Workstation 4.0 (english version, build 1381 with service pack 3) Let's go: Run the Is5P221.exe, after the about screen, it will ask you to type the password to continue, below the Password dialog, you will not get a enabled 'Finish' button until you have entered the correct password. So, Let us think how to find the correct pasword. After we type a character the package must compare the characters we have entered with the correct password. So let's begin: First, just type anay number of characters, for example, '121212', to the pasword field, press Ctrl-D to switch to softice, type :bpx getwindowtexta :Ctrl-D Now we are back to the password dialog, enter another '1' to password field, softice will pop up at User32!GetWindowTextA, hit F12 to return to is5p221, now we try to serach the stack to find the password we have entered, :s ss:0 lffffffff '121212' Pattern find at xxxx:01800820 We have to set the breakpoints to any code they read this area, so type :bpm 018000820 r Press F5 to continue running, SoftIce will pop up at KERNEL!CompareStringA :77f2b318 mov al, [esi] :77f2b31a cmp [ebx], al <--- softice pop up at here, ebx equal to '01800820' :77f2b31c jnz 77f2b325 <--- if not equal, incorrect password, jump away :77f2b31e inc esi <--- if equal, increment index :77f2b31f inc ebx :77f2b320 cmp byte ptr[esi], 00 <--- test if this is the last character of stored password :77f2b323 jnz 77f2b318 <--- compare with next character OK, take a rest, light a cigarette, we have found the stored password, is it so easy ? dump the data at [ebx], [esi] :d ebx <--- you will see the password you have entered. :d esi <--- you will see the stored password(I will give you a clue, the stored password is "dol???????", just try to find out by yourself) Write down the stored password you have found to a paper, then disable any breakpoints, :bd * :Ctrl-D We are back to the password dialog again, erase the incorrect password, type the sotred password you have found to the password field, you will get a enabled 'Finish' button. Now let's think how could we crack this type of application quickly ? The answer is : 1. run this type of program. 2. type any number of characters to the password field. 3. switch to the SoftIce. 4. set a breakpoint to KERNEL32!CompareStringA by :bpx CompareStringA 5. run the program again and type one more character to the password field 6. softice will pop up at KERNEL32!CompareStringA 7. step the code until you stop at "jnz 77f2b325" :77f2b318 mov al, [esi] :77f2b31a cmp [ebx], al <--- softice pop up at here, ebx equal to '01800820' :77f2b31c jnz 77f2b325 <--- if not equal, incorrect password, jump away :77f2b31e inc esi <--- if equal, increment index :77f2b31f inc ebx :77f2b320 cmp byte ptr[esi], 00 <--- test if this is the last character of stored password :77f2b323 jnz 77f2b318 <--- compare with next character 8. dump the data pointed by [esi], you will get the stored password. 这是很有深度的思考,不过既然要能对所有的密码保护都能所向无敌,应该从密码保护程式设计的角度去 观察。当然在做更深入的探讨之前,我赶忙去下载了一份InstallShield Pro 5 Build 221。我以後的软 体会用得到。 那麽,这类的边输入边查核的密码保护到底还可以用什麽方式作出来呢?有没有办法不透过 GetWindowText 就可以取得使用者在编辑窗的输入呢?答案是肯定的,事实上,有许多方法可以达成。其一,可以以 SendMessage EM_GETLINE拷贝缓冲区。其二,直接利用 SendMessage EM_SETHANDLE 指定缓冲区给编辑 窗,直接从自己的缓冲区读输入。甚或是直接 Subclass 或 Hook编辑窗,直接一个字一个字自己组合起 来。前两种范例,都可以利用 soft-ice search 的功能,再设定 BPR (Breakpoint on Range,中断於一 记忆体范围) 的 breakpoint 达成拦截,唯最後一者比较棘手,可能要找出 subclass 或 hook 的程序才 加以breakpoint,并要过滤出 WM_CHAR 或相关可以取得使用者输入字元的讯息。头皮发麻了吧? 好吧,来谈谈处理输入、判定密码的问题。一个程式,其实要做密码的判断并不难。可是不知道怎麽搞的, 许多程式一窝蜂的使用系统呼叫。其实下列不出32 bytes 的组合语言片段即可做字串比较。 ; 假设 ds=es mov esi, offset 字串1 mov edi, offset 字串2 mov ecx, 字串长度 repe cmpsb jne 字串不相同 ; 字串相同 也可以搞得复杂一点,如下所示,既有简易密码保护,也有简易流程保护: ; 假设 ds=es xor ecx, ecx ; ecx=0 xor ebx, ebx ; ebx=0 mov ebp, offset 字串1 ; 密码值 mov esi, offset 字串2 ; 输入值 fetch_one_dword: ; 如果索性跳过这一行,会造成堆叠损毁 push dword ptr ds:[ebp + cx] ; 可能也可以用 byte ptr 吧?我不确定。 pop eax xor eax, 55aa55aah ; 简易编码过的密码值,再 xor 一次以还原 cmp eax, dword ptr [esi + cx] jnz password_error add ebx, eax ; ebx += eax add ecx, 4 cmp ecx, 字串长度 jnb done jmp short fetch_one_dword done: ; 先把使用者的输入字串和计算好,在此略 call calc_checksum ; esi = 字串2, 传回: eax = checksum cmp eax, ebx ; 如果你试着要跳过前面的 cmp 的话 jne password_error ; ebx 得到的 checksum 在此会不同 ; 密码答对了,有奖! 流程保护是指,不论如何,一定要完全检查过密码就是了。不然有得瞧! 当然,也有更高段的保护的。这里示范的只是一个概念,并无意要出题考各位破解 的功力。这里我还想得到的保护,还有利用 soft-ice的死角。概念是,因为 soft-ice 只能为单一执行绪除错,其他的不是被终止,就是在你执行系统呼叫时才偷偷执行, 你无法一次除错或确实终止多重执行绪,所以我就想到利用建立另一个执行绪来帮 我比较密码的概念。 嗯,能跟我跟到这里,也要谢谢您的耐心,我希望诸君都一个字一个字地看过一遍, 因为我有些句子浓缩了不少(打完字後才发现)。不过我衷心的希望这多多少少对 您有帮助。 -- Robin Hood ICQ UIN: 1311717 mailto:robin.hood@ibm.net -----------------------------------