公孙秒秒 发表于 2019-4-26 19:17

我是用户实战二豪杰录屏爆破记录【含视频记录】

本帖最后由 公孙秒秒 于 2019-4-26 20:34 编辑

前言:
————————————————————————————————————

由于原来的帖子没有附件,这个我是百度搜索下载的一个为破解版本,解压即可用,不过与我是用户大大分析的原版本程序有所不同,少了一些文件,代码上虽然相同,不过思路上完全没办法了,记录一下我的思路吧
大大原帖传送门:https://www.52pojie.cn/thread-197598-1-1.html

视频传送门:
————————————————————————————————————


https://www.bilibili.com/video/av50351540/
https://www.bilibili.com/video/av50538005/


汇总帖传送门:
————————————————————————————————————
https://www.52pojie.cn/thread-932679-1-1.html



正文:
————————————————————————————————————

解压过后运行主程序:Courseware2.exe
发现弹出来一个注册界面:



打开任务管理器是看不到这个注册界面的进程的:



不过我们可以打开OD看一下,打开附件界面,然后按路径排序,看到了我们主程序旁边,还有一个EXE程序运行了,这个名字为注册的EXE程序其实就是注册的程序了:



先进行查壳,两个都查一下,发现无壳,所以就不上图了
那么我们就可以开始盘他了,我们先研究这个注册程序,用OD载入他
我们先把程序跑起来,然后输入好用户名和注册码,随便输入,确定看看,有一个弹窗




这里其实我们就可以有思路了,最简单的肯定是下按钮事件断点
其次下DialogBoxParamA,messagebox之类的断点断到这个弹窗出现的位置,向上回溯
或者下getwindowtext这些的获取文本的,因为要获取用户名和注册码很大可能会调用这些api,然后向下跟
这里本来打算下按钮事件断点的,不过试过了各种按钮事件,都断不下来,所以只好更改思路,同时下messagebox和dialogboxparam断点,然后再点确定尝试注册,成功的断在了DialogBoxParamA这里:



0012F7A8   00402553/CALL 到 DialogBoxParamA 来自 AuthReg.0040254D
0012F7AC   00930000|hInst = 00930000
0012F7B0   00000069|pTemplate = 0x69
0012F7B4   003C0898|hOwner = 003C0898 ('注册',class='#32770',parent=000100DA)
0012F7B8   004023E0|DlgProc = AuthReg.004023E0
0012F7BC   0012F7C0\lParam = 0012F7C0



直接进行回溯,返回到的地方上一句call就是调用dialogboxparam的地方了,那么我们往上找,找到这段的头部(00402480 处),下断,然后重新提交注册,F8跟一遍看看能不能有什么思路:
00402480/$83EC 40       sub esp,0x40
00402483|.8B0D 38CC4000 mov ecx,dword ptr ds:
00402489|.56            push esi
0040248A|.8B35 98914000 mov esi,dword ptr ds:[<&USER32.GetWindow>;user32.GetWindowTextA
00402490|.8D4424 04   lea eax,dword ptr ss:
00402494|.6A 08         push 0x8                                 ; /Count = 0x8
00402496|.50            push eax                                 ; |Buffer = 0012F7C0
00402497|.51            push ecx                                 ; |hWnd = 003C0898 ('注册',class='#32770',parent=000100DA)
00402498|.FFD6          call esi                                 ; \GetWindowTextA
0040249A|.A1 34CC4000   mov eax,dword ptr ds:
0040249F|.8D5424 09   lea edx,dword ptr ss:
004024A3|.6A 08         push 0x8                                 ; /Count = 0x8
004024A5|.52            push edx                                 ; |Buffer = offset Auth936.<ModuleEntryPoint>
004024A6|.50            push eax                                 ; |hWnd = 0012F7C0
004024A7|.FFD6          call esi                                 ; \GetWindowTextA
004024A9|.8B15 40CC4000 mov edx,dword ptr ds:
004024AF|.8D4C24 0E   lea ecx,dword ptr ss:
004024B3|.6A 08         push 0x8                                 ; /Count = 0x8
004024B5|.51            push ecx                                 ; |Buffer = 003C0898
004024B6|.52            push edx                                 ; |hWnd = 00930000
004024B7|.FFD6          call esi                                 ; \GetWindowTextA
004024B9|.8B0D 3CCC4000 mov ecx,dword ptr ds:
004024BF|.8D4424 13   lea eax,dword ptr ss:
004024C3|.6A 08         push 0x8                                 ; /Count = 0x8
004024C5|.50            push eax                                 ; |Buffer = 0012F7C0
004024C6|.51            push ecx                                 ; |hWnd = 003C0898 ('注册',class='#32770',parent=000100DA)
004024C7|.FFD6          call esi                                 ; \GetWindowTextA
004024C9|.8B15 30CC4000 mov edx,dword ptr ds:
004024CF|.68 00010000   push 0x100                               ; /Count = 100 (256.)
004024D4|.B0 2D         mov al,0x2D                              ; |
004024D6|.68 80CD4000   push AuthReg.0040CD80                  ; |Buffer = AuthReg.0040CD80
004024DB|.52            push edx                                 ; |hWnd = 00930000
004024DC|.884424 1E   mov byte ptr ss:,al            ; |
004024E0|.884424 19   mov byte ptr ss:,al            ; |
004024E4|.884424 14   mov byte ptr ss:,al            ; |
004024E8|.C64424 23 00mov byte ptr ss:,0x0         ; |
004024ED|.FFD6          call esi                                 ; \GetWindowTextA
004024EF|.A1 58C74000   mov eax,dword ptr ds:
004024F4|.5E            pop esi                                  ;AuthReg.00402553
004024F5|.85C0          test eax,eax
004024F7|.74 0E         je short AuthReg.00402507
004024F9|.8D4C24 00   lea ecx,dword ptr ss:
004024FD|.51            push ecx
004024FE|.68 80CD4000   push AuthReg.0040CD80                  ;ASCII "zhucema"
00402503|.FFD0          call eax
00402505|.EB 0F         jmp short AuthReg.00402516
00402507|>8D5424 00   lea edx,dword ptr ss:
0040250B|.52            push edx                                 ;Auth936.<ModuleEntryPoint>
0040250C|.68 80CD4000   push AuthReg.0040CD80                  ;ASCII "zhucema"
00402511|.E8 DA140000   call AuthReg.004039F0
00402516|>33C9          xor ecx,ecx
00402518|.8D5424 00   lea edx,dword ptr ss:
0040251C|.85C0          test eax,eax
0040251E|.0f95c1      setne cl
00402521|.52            push edx                                 ;Auth936.<ModuleEntryPoint>
00402522|.68 80CD4000   push AuthReg.0040CD80                  ;ASCII "zhucema"
00402527|.890D 40F84000 mov dword ptr ds:,ecx
0040252D|.E8 2E000000   call AuthReg.00402560
00402532|.8B4C24 4C   mov ecx,dword ptr ss:
00402536|.8B15 64CD4000 mov edx,dword ptr ds:          ;Auth936.<ModuleEntryPoint>
0040253C|.83C4 08       add esp,0x8
0040253F|.8D4424 00   lea eax,dword ptr ss:
00402543|.50            push eax                                 ; /lParam = 0012F7C0
00402544|.68 E0234000   push AuthReg.004023E0                  ; |DlgProc = AuthReg.004023E0
00402549|.51            push ecx                                 ; |hOwner = 003C0898 ('注册',class='#32770',parent=000100DA)
0040254A|.6A 69         push 0x69                              ; |pTemplate = 0x69
0040254C|.52            push edx                                 ; |hInst = 00930000
0040254D|.FF15 C4914000 call dword ptr ds:[<&USER32.DialogBoxPar>; \DialogBoxParamA



重新提交过后,程序断在了00402480 处,我们一路F8,这个时候注册观察堆栈会发现:
004024FD|.51            push ecx
004024FE|.68 80CD4000   push AuthReg.0040CD80                  ;ASCII "zhucema"
00402503|.FFD0          call eax                                 ;SthClass.100010A0



这个位置,前两句分别把我们输入的用户名和假码推进栈了,然后立刻调用了一个call,那么这个call其实就非常的可疑了,我们跟进去看看,进入call过后,先F8走走看,走到下面这段代码的时候发现:

100010C5    0FBE4434 08   movsx eax,byte ptr ss:
100010CA    83F8 41         cmp eax,0x41
100010CD    7C 08         jl short SthClass.100010D7
100010CF    83F8 5A         cmp eax,0x5A
100010D2    7F 03         jg short SthClass.100010D7
100010D4    83C0 20         add eax,0x20
100010D7    50            push eax                                 ; SthClass.100010A0
100010D8    E8 33020000   call SthClass.10001310
100010DD    83C4 04         add esp,0x4
100010E0    884434 08       mov byte ptr ss:,al
100010E4    46            inc esi
100010E5    83FE 04         cmp esi,0x4
100010E8^ 7C DB         jl short SthClass.100010C5


发现下面这一句的位置一直在产生一些字符,而且刚好这个循环又执行了四次,那么就很可疑了,会不会是在计算真码的某四位呢?,我们在数据窗口中跟随:
100010E0    884434 08       mov byte ptr ss:,al



然后我们继续往下走,当走到这一段的时候:
100010F8    8D4C14 08       lea ecx,dword ptr ss:
100010FC    0FBE040E      movsx eax,byte ptr ds:
10001100    83F8 41         cmp eax,0x41
10001103    7C 08         jl short SthClass.1000110D
10001105    83F8 5A         cmp eax,0x5A
10001108    7F 03         jg short SthClass.1000110D
1000110A    83C0 20         add eax,0x20
1000110D    0FBE09          movsx ecx,byte ptr ds:
10001110    3BC1            cmp eax,ecx
10001112    0F85 32010000   jnz SthClass.1000124A
10001118    42            inc edx
10001119    83FA 04         cmp edx,0x4
1000111C^ 7C DA         jl short SthClass.100010F8



发现又是一段循环,刚好四次,而且这里
100010FC    0FBE040E      movsx eax,byte ptr ds:



这一句取了我们假码的第一位
1000110D    0FBE09          movsx ecx,byte ptr ds:


又在上面这一句处取了刚才产生的四位字符的第一位,然后对他们进行比较,这个时候其实百分之99就可以确定这里是在比对注册码了,而上面产生的字符就是再计算真实的注册码
10001110    3BC1            cmp eax,ecx
10001112    0F85 32010000   jnz SthClass.1000124A


那么上面这个跳转的地方显然是要跳到不正确的处理结果处的的,我们顺着跳转的箭头找到这个位置的代码先保存下来,但是程序中我们不让这个跳转实现,因为这里循环比对了4次,改标志位太累了,直接nop吧
这是如果错误要跳转到的地方的代码:
1000124A    5F            pop edi
1000124B    33C0            xor eax,eax
1000124D    5E            pop esi
1000124E    83C4 20         add esp,0x20
10001251    C2 0800         retn 0x8



我们把跳转nop掉过后,继续跟,发现面又分别出现了三次同样的计算真码的代码,和三次比对的过程,然后就走到了刚刚那个跳转应该到达的上方:
1000123D    5F            pop edi
1000123E    B8 01000000   mov eax,0x1
10001243    5E            pop esi
10001244    83C4 20         add esp,0x20
10001247    C2 0800         retn 0x8


发现如果没有经过跳转的话,那么这里会把eax的值赋值为1,如果错误的话,就会通过xor eax,eax将eax置零,也就是说其实这段函数最后判断代验证码正不正确靠的的是eax的值,这里我们爆破的思路就多了:
1、我们nop掉所有对比处的跳转
2、我们直接在这段函数的头部修改代码,对eax赋值1,然后直接返回就好了:
mov eax,0x1
retn 0x8
3、我们直接拿到真码注册

修改过后,我们保存好修改的文件替换掉原来的文件,发现这个时候果然无论我们输入什么都会显示注册成功了:


不过这个时候如果我们直接打开主程序,会发现又弹出来了注册的页面,但是如果我们是用真码去注册的话,重启就不会弹出来,那么说明主程序其实在启动的时候又重新进行了验证,重启验证,我们如果在刚刚那个比对函数返回过后,跟到下一个call中就会发现注册程序进行了大量的注册表写入操作,怀疑是将注册信息写入了注册表,并在每次启动程序的时候重新验证一遍,我们把主程序用OD载入,然后下regopenkey和regopenkeyex看看,能不能找到有用的信息,下断过后,运行:
0012F9D4   80000000|hKey = HKEY_CLASSES_ROOT
0012F9D8   0012FA30|Subkey = "CLSID\{C0483E67-A363-40C8-BC4C-22EC7419CD21}\Implemented Categories"
0012F9DC   00000000|Reserved = 0x0
0012F9E0   00020019|Access = KEY_READ
0012F9E4   0012F9EC\pHandle = 0012F9EC


堆栈当中看到的地址显然不是我们程序的调用,忽略,继续运行:
0012F9D0   00413886/CALL 到 RegOpenKeyExA 来自 Coursewa.00413880
0012F9D4   80000000|hKey = HKEY_CLASSES_ROOT
0012F9D8   0012FA30|Subkey = "CLSID\{C0483E67-A363-40C8-BC4C-22EC7419CD21}\Implemented Categories"
0012F9DC   00000000|Reserved = 0x0
0012F9E0   00020019|Access = KEY_READ
0012F9E4   0012F9EC\pHandle = 0012F9EC


堆栈中的信息显示如上,发现是我们程序打开了一个键,我们直接返回用户代码,F8一路跟下去看看,程序访问了键过后,做了什么操作:
00413909|.8D4C24 10   lea ecx,dword ptr ss:          ;假码给到ecx
0041390D|.8D5424 50   lea edx,dword ptr ss:          ;用户名给到EDX
00413911|.51            push ecx                                 ;假码进栈
00413912|.52            push edx                                 ;用户名进栈
00413913|.E8 D8010000   call Coursewa.00413AF0                   ;所以这个call我们就要跟进去看看了,F7



走到上面这段的时候,发现出现了我们输入的假码和注册名,然后他们都被推进栈,我们跟进下面的call当中,发现里面的代码非常的熟悉,就是我们上面找到的产生真码和比对的地方一模一样,不过这次是写在主程序里面的,我们用相同的手法修改并且保存,执行我们修改过后的程序,发现没有了弹窗,同时查看注册信息发现,显示注册成功:






公孙秒秒 发表于 2019-4-27 23:26

划水摸鱼 发表于 2019-4-27 23:24
楼主你好,我按照你的步骤进行,下DialogBoxParamA断点,然后运行,成功的停了下来,可是整个OD和Autoreg程 ...

我也卡死过后几回,然后重启了就好了,最好用虚拟机玩吧,逆向这个事情直接拿电脑来很容易把系统玩坏的

公孙秒秒 发表于 2019-4-27 23:31

划水摸鱼 发表于 2019-4-27 23:30
谢谢!原来是这样,我还是太新手了,之前一直想不通为什么要用虚拟机

而且吾爱的那个虚拟机里面集成了非常非常多的软件的,不用自己到处找软件下了,包括插件什么的都挺多的,非常的方便了

buch1234 发表于 2019-4-26 19:37

这个破解思路不错,很实用。谢谢

501 发表于 2019-4-26 19:59

ev录屏目前最好,建议你破解一下

小生是书痴 发表于 2019-4-27 08:38

恒大老师

心里乐开花 发表于 2019-4-27 10:08

感谢大佬的分享,支持一下!

a764329871 发表于 2019-4-27 10:08

辛苦了。路过而已

2623666 发表于 2019-4-27 13:50

豪杰公司还在么? 话说消失很久了

wangshi467 发表于 2019-4-27 14:43

感谢分享,非常细的介绍,受益匪浅。

renyangyu 发表于 2019-4-27 15:46

思路非常清晰    遇到好几种软件都是这个

划水摸鱼 发表于 2019-4-27 23:24

楼主你好,我按照你的步骤进行,下DialogBoxParamA断点,然后运行,成功的停了下来,可是整个OD和Autoreg程序都卡死了,点哪都没反应,只能任务管理器结束,请问是哪里出了问题?(Win10专业版x64)
页: [1] 2
查看完整版本: 我是用户实战二豪杰录屏爆破记录【含视频记录】