新手破解练习Crackme160之096 - register

  1. 脱壳
    xp下用PEiD的通用脱壳插件去壳成功~
     

  2. 去NAG
    OD载入去壳后程序, 单步执行到00438517处弹出提示框, 所以我们把这行nop掉, 不让弹, 保存~
     

  3. 用户名与注册码
    由IDR反编译源码分析可得注册码输入框Edit1change事件入口00437D28, 向下找到关键算法方法00435DC8处, 进入方法分析具体算法(用户名的输入框是Edit2, 事件有验证用户名长度是否6位, 是的话改变注册码框的可写性)
    1). 00435E00 ~ 00435E13 循环6次将每一位值加起来存到[ebx]中
    2).
    [ebx] += len(user)
    [ebx] *= 0x15C10E
    [ebx] /= 3
    [ebx] += 0x29A
    [ebx] /= 1388
    [ebx] *= len(user)
    [ebx] *= user[2]
    [ebx] *= user[4]
    if([ebx] <= 0x5F5E0FF) { goto E77; }
    if([ebx] < 0x3B9ACA00) { goto EB2; }
    E77:
    [ebx] += len(user)
    [ebx] *= user[0]
    [ebx] *= [43A99C]
    if([ebx] >= 0) { goto EA2; }
    [ebx] *= -1
    EA2:
    if([ebx] <= 0x5F5E0FF) { goto E77; }
    if([ebx] >= 0x3B9ACA00 )

    算法分析完成, 开始写注册机: keygen.c

	#include <stdio.h>
	#include <string.h>

	int main() {
		char name[7] = {0};
		int len = 0;
		long code = 0, code1, val = 0xC27E1BDB;
		
		while(len != 6){
			printf("请输入用户名(6位): ");
			scanf("%s", name);
			len = strlen(name);  
		}
		for(int i=0; i<6; i++){
			code += name[i];
		}
		code += len;
		code *= 0x15C10E;
		code /= 3;
		code += 0x29A;
		code /= 0x1388;
		code *= len;
		code *= name[2];
		code *= name[4];
		if(code <= 0x5F5E0FF)  goto E77;
		if(code >= 0x3B9ACA00) {
			E77:
			code += len;
			code *= name[0];
			code *= val;
			code &= 0xFFFFFFFF;
			if(code < 0) code *= -1;
			if(code <= 0x5F5E0FF)  goto E77;
			if(code >= 0x3B9ACA00) goto E77;
		}
		
		code1 = code;
		EB6:
		code1 /= len;
		code1 = code1 - val / code1;
		if(code1 < 0x2710) { code1 *= code1; } //平方
		code1 &= 0xFFFFFFFF; 
		if(code1 <= 0x270F)  goto EB6;
		if(code1 >= 0x186A0) goto EB6;
		
		printf("用户名为: %s\n注册码为: %ld\n滑块码为: %ld\n", name, code, code1);
		
		getchar();getchar();
		return 0;
	}

 运行示例:
用户名为: abc123
注册码为: 826371706
滑块码为: 72640
输入测试正常~
 

  1. 滑块验证
    这个比较简单, 需要上一步完成后便可以得到正确的码~
     

  2. 文件验证
    IDR中查看所有方法可知, 在TForm1.FormCreate事件(00435F70)中包含了文件验证lockey.key 和 register.exe, 进入方法, 反编译代码如下:

 Unit1::TForm1.FormCreate
 00435F70    push       ebp
 00435F71    mov        ebp,esp
 00435F73    add        esp,0FFFFFEB0
 00435F79    push       ebx
 00435F7A    xor        ecx,ecx
 00435F7C    mov        dword ptr [ebp-150],ecx
 00435F82    mov        ebx,eax
 00435F84    xor        eax,eax
 00435F86    push       ebp
 00435F87    push       436234
 00435F8C    push       dword ptr fs:[eax]
 00435F8F    mov        dword ptr fs:[eax],esp
 00435F92    mov        al,63
 00435F94    call       004358CC
 00435F99    mov        [0043A99C],eax
 00435F9E    mov        edx,436248; 'lockey.key'
 00435FA3    lea        eax,[ebp-14C]
 00435FA9    call       @Assign
 00435FAE    mov        edx,4
 00435FB3    lea        eax,[ebp-14C]
 00435FB9    call       @ResetFile
 00435FBE    call       IOResult
 00435FC3    test       eax,eax
>00435FC5    jne        0043603C
 00435FC7    mov        eax,436248; 'lockey.key'
 00435FCC    call       00435954
 00435FD1    cmp        eax,5E62823F
>00435FD6    jne        00436002
 00435FD8    mov        byte ptr ds:[43A995],1
 00435FDF    mov        eax,dword ptr [ebx+28C]; TForm1.Label25:TLabel
 00435FE5    mov        eax,dword ptr [eax+50]; TLabel.?f50:dword
 00435FE8    mov        edx,80000008
 00435FED    call       TFont.SetColor
 00435FF2    mov        edx,43625C; 'valid'
 00435FF7    mov        eax,dword ptr [ebx+28C]; TForm1.Label25:TLabel
 00435FFD    call       TControl.SetText
 00436002    mov        eax,436248; 'lockey.key'
 00436007    call       00435954
 0043600C    cmp        eax,5E62823F
>00436011    je         00436058
 00436013    lea        eax,[ebp-14C]
 00436019    call       @Close
 0043601E    call       @_IOTest
 00436023    mov        byte ptr ds:[43A995],0
 0043602A    mov        edx,43626C; 'invalid'
 0043602F    mov        eax,dword ptr [ebx+28C]; TForm1.Label25:TLabel
 00436035    call       TControl.SetText
>0043603A    jmp        00436058
 0043603C    mov        eax,[0043A7AC]; 0x0
 00436041    mov        eax,dword ptr [eax+28C]; TForm1.Label25:TLabel
 00436047    mov        edx,43627C; 'not found'
 0043604C    call       TControl.SetText
 00436051    mov        byte ptr ds:[43A995],0
 00436058    mov        eax,436290; 'register.exe'
 0043605D    call       00435954
 00436062    mov        [0043A998],eax
 00436067    cmp        dword ptr ds:[43A998],53E8C9D0
>00436071    je         0043608E
 00436073    push       2010
 00436078    push       4362A0; 'File patched (?)!'
 0043607D    push       4362B4; 'File REGISTER.EXE has been modified.\rIf you didn't change anything try to get a genuine one\r(or try without patching... :-) )'
 00436082    push       0
 00436084    call       USER32.MessageBoxA
 00436089    call       @Halt0
 0043608E    push       0
 00436090    mov        eax,[00439AA8]; ^Application:TApplication
 00436095    mov        eax,dword ptr [eax]
 00436097    mov        eax,dword ptr [eax+24]; TApplication.?f24:dword
 0043609A    push       eax
 0043609B    call       USER32.ShowWindow
 004360A0    call       00435A84
 004360A5    mov        edx,43633C; 'unregistered'
 004360AA    mov        eax,dword ptr [ebx+1F4]; TForm1.Label4:TLabel
 004360B0    call       TControl.SetText
 004360B5    lea        edx,[ebp-150]
 004360BB    mov        eax,dword ptr [ebx+204]; TForm1.TrackBar3:TTrackBar
 004360C1    mov        eax,dword ptr [eax+130]; TTrackBar.Position:Integer
 004360C7    call       IntToStr
 004360CC    mov        edx,dword ptr [ebp-150]
 004360D2    mov        eax,dword ptr [ebx+210]; TForm1.Label5:TLabel
 004360D8    call       TControl.SetText
 004360DD    lea        edx,[ebp-150]
 004360E3    mov        eax,dword ptr [ebx+1FC]; TForm1.TrackBar1:TTrackBar
 004360E9    mov        eax,dword ptr [eax+130]; TTrackBar.Position:Integer
 004360EF    call       IntToStr
 004360F4    mov        edx,dword ptr [ebp-150]
 004360FA    mov        eax,dword ptr [ebx+214]; TForm1.Label6:TLabel
 00436100    call       TControl.SetText
 00436105    lea        edx,[ebp-150]
 0043610B    mov        eax,dword ptr [ebx+200]; TForm1.TrackBar2:TTrackBar
 00436111    mov        eax,dword ptr [eax+130]; TTrackBar.Position:Integer
 00436117    call       IntToStr
 0043611C    mov        edx,dword ptr [ebp-150]
 00436122    mov        eax,dword ptr [ebx+218]; TForm1.Label7:TLabel
 00436128    call       TControl.SetText
 0043612D    lea        edx,[ebp-150]
 00436133    mov        eax,dword ptr [ebx+208]; TForm1.TrackBar4:TTrackBar
 00436139    mov        eax,dword ptr [eax+130]; TTrackBar.Position:Integer
 0043613F    call       IntToStr
 00436144    mov        edx,dword ptr [ebp-150]
 0043614A    mov        eax,dword ptr [ebx+21C]; TForm1.Label8:TLabel
 00436150    call       TControl.SetText
 00436155    lea        edx,[ebp-150]
 0043615B    mov        eax,dword ptr [ebx+20C]; TForm1.TrackBar5:TTrackBar
 00436161    mov        eax,dword ptr [eax+130]; TTrackBar.Position:Integer
 00436167    call       IntToStr
 0043616C    mov        edx,dword ptr [ebp-150]
 00436172    mov        eax,dword ptr [ebx+220]; TForm1.Label9:TLabel
 00436178    call       TControl.SetText
 0043617D    mov        edx,9
 00436182    mov        eax,dword ptr [ebx+204]; TForm1.TrackBar3:TTrackBar
 00436188    call       TTrackBar.SetPosition
 0043618D    mov        edx,9
 00436192    mov        eax,dword ptr [ebx+1FC]; TForm1.TrackBar1:TTrackBar
 00436198    call       TTrackBar.SetPosition
 0043619D    mov        edx,9
 004361A2    mov        eax,dword ptr [ebx+200]; TForm1.TrackBar2:TTrackBar
 004361A8    call       TTrackBar.SetPosition
 004361AD    mov        edx,9
 004361B2    mov        eax,dword ptr [ebx+208]; TForm1.TrackBar4:TTrackBar
 004361B8    call       TTrackBar.SetPosition
 004361BD    mov        edx,9
 004361C2    mov        eax,dword ptr [ebx+20C]; TForm1.TrackBar5:TTrackBar
 004361C8    call       TTrackBar.SetPosition
 004361CD    xor        edx,edx
 004361CF    mov        eax,dword ptr [ebx+1DC]; TForm1.Edit1:TEdit
 004361D5    call       TControl.SetEnabled
 004361DA    xor        edx,edx
 004361DC    mov        eax,dword ptr [ebx+1FC]; TForm1.TrackBar1:TTrackBar
 004361E2    call       TControl.SetEnabled
 004361E7    xor        edx,edx
 004361E9    mov        eax,dword ptr [ebx+200]; TForm1.TrackBar2:TTrackBar
 004361EF    call       TControl.SetEnabled
 004361F4    xor        edx,edx
 004361F6    mov        eax,dword ptr [ebx+204]; TForm1.TrackBar3:TTrackBar
 004361FC    call       TControl.SetEnabled
 00436201    xor        edx,edx
 00436203    mov        eax,dword ptr [ebx+208]; TForm1.TrackBar4:TTrackBar
 00436209    call       TControl.SetEnabled
 0043620E    xor        edx,edx
 00436210    mov        eax,dword ptr [ebx+20C]; TForm1.TrackBar5:TTrackBar
 00436216    call       TControl.SetEnabled
 0043621B    xor        eax,eax
 0043621D    pop        edx
 0043621E    pop        ecx
 0043621F    pop        ecx
 00436220    mov        dword ptr fs:[eax],edx
 00436223    push       43623B
 00436228    lea        eax,[ebp-150]
 0043622E    call       @LStrClr
 00436233    ret
<00436234    jmp        @HandleFinally
<00436239    jmp        00436228
 0043623B    pop        ebx
 0043623C    mov        esp,ebp
 0043623E    pop        ebp
 0043623F    ret

在00435FD1 cmp eax,5E62823F处有个关键比较, 所以上一行 00435FCC call 00435954 应该就是关键算法了, 我们跟进去瞧瞧, 代码如下:

Unit1::sub_00435954
 00435954    push       ebp
 00435955    mov        ebp,esp
 00435957    add        esp,0FFFFF6D0
 0043595D    push       ebx
 0043595E    push       esi
 0043595F    mov        dword ptr [ebp-10],eax
 00435962    mov        eax,dword ptr [ebp-10]
 00435965    call       @LStrAddRef
 0043596A    lea        ebx,[ebp-0C]
 0043596D    xor        eax,eax
 0043596F    push       ebp
 00435970    push       435A75
 00435975    push       dword ptr fs:[eax]
 00435978    mov        dword ptr fs:[eax],esp
 0043597B    mov        eax,[00439AE4]; ^FileMode:Byte
 00435980    mov        byte ptr [eax],0
 00435983    mov        edx,dword ptr [ebp-10]
 00435986    lea        eax,[ebp-15C]
 0043598C    call       @Assign
 00435991    mov        edx,4
 00435996    lea        eax,[ebp-15C]
 0043599C    call       @ResetFile
 004359A1    call       IOResult
 004359A6    test       eax,eax
>004359A8    jne        00435A58
 004359AE    lea        eax,[ebp-15C]
 004359B4    call       @FileSize
 004359B9    call       @_IOTest
 004359BE    mov        edx,eax
 004359C0    sar        edx,1
>004359C2    jns        004359C7
 004359C4    adc        edx,0
 004359C7    lea        eax,[ebp-15C]
 004359CD    call       @Seek
 004359D2    call       @_IOTest
 004359D7    lea        eax,[ebp-15C]
 004359DD    call       @FileSize
 004359E2    call       @_IOTest
 004359E7    mov        esi,eax
 004359E9    dec        esi
 004359EA    lea        eax,[ebp-15C]
 004359F0    call       @FilePos
 004359F5    call       @_IOTest
 004359FA    sub        esi,eax
 004359FC    mov        dword ptr [ebp-8],esi
 004359FF    cmp        dword ptr [ebp-8],1F4
>00435A06    jle        00435A0F
 00435A08    mov        dword ptr [ebp-8],1F4
 00435A0F    push       0
 00435A11    lea        edx,[ebp-930]
 00435A17    mov        ecx,dword ptr [ebp-8]
 00435A1A    lea        eax,[ebp-15C]
 00435A20    call       @BlockRead
 00435A25    call       @_IOTest
 00435A2A    lea        eax,[ebp-15C]
 00435A30    call       @Close
 00435A35    call       @_IOTest
 00435A3A    lea        eax,[ebp-930]
 00435A40    mov        dword ptr [ebp-4],eax
 00435A43    xor        eax,eax
 00435A45    xor        ecx,ecx
 00435A47    mov        edi,dword ptr [ebp-4]
 00435A4A    add        eax,dword ptr [edi+ecx*4]
 00435A4D    inc        ecx
 00435A4E    cmp        ecx,dword ptr [ebp-8]
<00435A51    jl         00435A4A
 00435A53    mov        dword ptr [ebp-0C],eax
>00435A56    jmp        00435A5F
 00435A58    mov        byte ptr ds:[43A995],0
 00435A5F    xor        eax,eax
 00435A61    pop        edx
 00435A62    pop        ecx
 00435A63    pop        ecx
 00435A64    mov        dword ptr fs:[eax],edx
 00435A67    push       435A7C
 00435A6C    lea        eax,[ebp-10]
 00435A6F    call       @LStrClr
 00435A74    ret
<00435A75    jmp        @HandleFinally
<00435A7A    jmp        00435A6C
 00435A7C    mov        eax,dword ptr [ebx]
 00435A7E    pop        esi
 00435A7F    pop        ebx
 00435A80    mov        esp,ebp
 00435A82    pop        ebp
 00435A83    ret

这段代码里面我们又看到了几个关键函数 FileSize, Seek, FilePos, BlockRead 同理还得分别进去看, 对应都有算法, 所以我们在OD中找到对应的位置下相关入口断点~ 接着便是慢慢的分析了~
我们先创建好lockey.key文件, 写入80字节内容(因为算法中有除以4的运算,所以整个4的倍数的)"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+'-=[]"

1). eax = filesize (00404BDD) 假设有80字节 -- filesize
2). eax /= 4 (00404BE9) (20)
3). edx=eax sar 1 => edx /= 2 (004359C0) (10)
4). eax = edx * 4 (00404DA4) (40) -- seek 文件指针移动到了40的位置了
5). eax += 1 (00404DB0) (41)
6). eax = filesize (80) -- filesize
7). eax /= 4 (20)
8). esi = eax, esi -= 1 (004359E9) (19)
9). esi -= eax; (9)
10). eax = (40) / 4 (00404BA9) (10) -- filepos
11). esi -= eax (004359FA) (9)
12). eax = esi * 4 (00404B03) (36) -- BlockRead 从文件40位置开始读取36字节
13). str = "EFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+`" (00404B06)
14). eax = str每4位相加(ESI 9次循环) = 60848AA1
15). eax ?= 0x5E62823F, (00435FD1) 相等则验证成功
到此算法分析完成~ 就是从文件的某个位置开始读取一些内容, 然后加起来与固定值比较
假设循环次数ESI = 1, 那么就有 (filesize / 4 - 1) - filesize / 4 / 2 = 1 得到 filesize = 16
再正算出 文件取内容位置 = 16 / 4 / 2 * 4 = 8, 取4字节内容, 所以文件内容即为(16进制):
00 00 00 00 00 00 00 00 3F 82 62 5E 00 00 00 00 (其中00可任意16进制数)
重新运行程序验证通过, 进入00436058, 开始验证第二个文件register.exe, 用了同样的算法, 结果与0x53E8C9D0比较, 原文件验证通过(未脱壳的文件), 所以破解时, 原文件得保留, 其他脱壳, 去NAG等文件需要另存为, 不然可能这步会验证不过~, 弹框提示文件被修改过~, 到此所有破解完成~

 
 
 
这是160个软件part1
这是160个软件part2

1~160每个破解过程,在吾爱破解论坛都有高手破解过了,也有整理好现成的, 我这边主要就是自己动手操作的过程,与他们的不太一样
附上高手们的连接: 点击前往查看
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载

新人入门教程"玩玩破解,写给新人看" 点击前往查看
我就是从这里开始的,对我这样的小白感觉超级友好~

下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~
OD界面布局

posted @ 2024-07-09 13:42  hankerstudio  阅读(14)  评论(0)    收藏  举报