新手破解练习Crackme160之143 - tc.9

  1. 解锁
    IDR反编译查看解锁码的事件可得, 解锁码为: "CrackMe [id:9] by tC... ." (不包括双引号), 最后还得多输入任意一位才会成功

  2. 用户名注册码
    也是IDR直接看事件源码

 Unit1::TForm1.Register1Click
 00444754    push       ebp
 00444755    mov        ebp,esp
 00444757    push       0
 00444759    push       0
 0044475B    push       0
 0044475D    push       ebx
 0044475E    push       esi
 0044475F    push       edi
 00444760    mov        esi,eax
 00444762    xor        eax,eax
 00444764    push       ebp
 00444765    push       4448C3
 0044476A    push       dword ptr fs:[eax]
 0044476D    mov        dword ptr fs:[eax],esp
 00444770    lea        edx,[ebp-8]
 00444773    mov        eax,dword ptr [esi+2CC]; TForm1.Edit3:TEdit
 00444779    call       TControl.GetText
 0044477E    mov        edx,dword ptr [ebp-8]
 00444781    mov        eax,446868; gvar_00446868:AnsiString
 00444786    call       @LStrAsg
 0044478B    lea        edx,[ebp-8]
 0044478E    mov        eax,dword ptr [esi+2C8]; TForm1.Edit2:TEdit
 00444794    call       TControl.GetText
 00444799    mov        eax,dword ptr [ebp-8]
 0044479C    call       @LStrLen
 004447A1    cmp        eax,5			;;;;; 5位以上
>004447A4    jl         004448A5
 004447AA    xor        eax,eax
 004447AC    mov        [00446894],eax; gvar_00446894
 004447B1    xor        eax,eax
 004447B3    mov        [00446898],eax; gvar_00446898
 004447B8    lea        edx,[ebp-8]
 004447BB    mov        eax,dword ptr [esi+2C8]; TForm1.Edit2:TEdit
 004447C1    call       TControl.GetText
 004447C6    mov        eax,dword ptr [ebp-8]
 004447C9    call       @LStrLen
 004447CE    mov        [00446854],eax; gvar_00446854:Longint		;;;;;;长度存起来
 004447D3    lea        edx,[ebp-8]
 004447D6    mov        eax,dword ptr [esi+2C8]; TForm1.Edit2:TEdit
 004447DC    call       TControl.GetText
 004447E1    mov        eax,dword ptr [ebp-8]
 004447E4    call       @LStrLen
 004447E9    mov        edi,eax
 004447EB    test       edi,edi
>004447ED    jle        00444848
 004447EF    mov        dword ptr [ebp-4],1			;;;;;;;;;;;算法开始
 004447F6    mov        ebx,446870; gvar_00446870:Integer
 004447FB    lea        edx,[ebp-8]
 004447FE    mov        eax,dword ptr [esi+2C8]; TForm1.Edit2:TEdit
 00444804    call       TControl.GetText
 00444809    mov        eax,dword ptr [ebp-8]
 0044480C    mov        edx,dword ptr [ebp-4]
 0044480F    mov        al,byte ptr [eax+edx-1]
 00444813    xor        al,3
 00444815    mov        byte ptr [ebx],al
 00444817    xor        eax,eax
 00444819    mov        al,byte ptr [ebx]
 0044481B    mov        edx,dword ptr ds:[446894]; gvar_00446894		;;;;;;这几行需要读内存值,所以需要OD跟踪
 00444821    add        edx,edx
 00444823    add        eax,edx
 00444825    mov        [00446894],eax; gvar_00446894
 0044482A    mov        al,[00446870]; gvar_00446870:Integer
 0044482F    imul       byte ptr ds:[446854]; gvar_00446854:Longint
 00444835    add        byte ptr [ebx],al
 00444837    xor        eax,eax
 00444839    mov        al,byte ptr [ebx]
 0044483B    add        dword ptr ds:[446898],eax; gvar_00446898
 00444841    inc        dword ptr [ebp-4]
 00444844    inc        ebx
 00444845    dec        edi
<00444846    jne        004447FB
 00444848    call       00444460
 0044484D    call       00444670			;;;;;;;;;;;;算法结束 
 00444852    mov        eax,[00446850]; gvar_00446850
 00444857    cmp        eax,dword ptr ds:[446854]; gvar_00446854:Longint	;;;;;;对比
>0044485D    jne        004448A5
 0044485F    lea        edx,[ebp-8]
 00444862    mov        eax,dword ptr [esi+2C8]; TForm1.Edit2:TEdit
 00444868    call       TControl.GetText
 0044486D    mov        ecx,dword ptr [ebp-8]
 00444870    lea        eax,[ebp-0C]
 00444873    mov        edx,4448DC; 'Registered to: '
 00444878    call       @LStrCat3
 0044487D    mov        edx,dword ptr [ebp-0C]
 00444880    mov        eax,dword ptr [esi+2F0]; TForm1.StatusBar1:TStatusBar
 00444886    call       TStatusBar.SetSimpleText
 0044488B    xor        edx,edx
 0044488D    mov        eax,dword ptr [esi+2C8]; TForm1.Edit2:TEdit
 00444893    mov        ecx,dword ptr [eax]
 00444895    call       dword ptr [ecx+60]; TControl.SetEnabled
 00444898    xor        edx,edx
 0044489A    mov        eax,dword ptr [esi+2CC]; TForm1.Edit3:TEdit
 004448A0    mov        ecx,dword ptr [eax]
 004448A2    call       dword ptr [ecx+60]; TControl.SetEnabled
 004448A5    xor        eax,eax
 004448A7    pop        edx
 004448A8    pop        ecx
 004448A9    pop        ecx
 004448AA    mov        dword ptr fs:[eax],edx
 004448AD    push       4448CA
 004448B2    lea        eax,[ebp-0C]
 004448B5    call       @LStrClr
 004448BA    lea        eax,[ebp-8]
 004448BD    call       @LStrClr
 004448C2    ret
<004448C3    jmp        @HandleFinally
<004448C8    jmp        004448B2
 004448CA    pop        edi
 004448CB    pop        esi
 004448CC    pop        ebx
 004448CD    mov        esp,ebp
 004448CF    pop        ebp
 004448D0    ret

中间算法有一堆的计算, 需要很认真的一步步跟进去, 跟套娃一样, 一层套一层, 中间虚虚实实, 有些是没用的, 分析步骤如下:
1). 004447FB ~ 00444846 循环用户名得到一个5位的字符串(内存00446870处) 和 2个数值([00446894] 和 [00446898])
2). 004444848 这个子方法中, 00444497 ~ 004444B 修正上面的5位串并计算到到新的1个数值([00446890]), 004444E5 ~ 0044450B 计算得到新的1个数值([0044689C]),
3). 0044484D 这个子方法中, 00444691 ~ 004446FE 这13次循环组装了8个字符串(应该有其中5个是重复的地址)不知道干嘛用的, 没整明白,第1个数和第4个数分别拼上65A 和 H3, 中间两个数也作了些运算, 组装结果类似于: 127565A-3023-815-FFFFD847H3, 组装好后都存在了内存中032F7D8附近, 组装完, 又进入一个子方法(00444700), F7进入, 00444575 ~ 004445FF 循环8次判断 前面组装的串是否等于输入的注册码[edi], 循环到第6次时, 程序进到另一分支(这才是真正组装正确注册码串的地方), 004445C2这里就是正确串组装好后的地方, 此处即可追码拿到正确的注册码, 与输入串对比成功后(004445CC), 将用户名的长度[00446854]赋值给[00446850] (004445D3处), 然后继续无效循环, 结束后, 再来5次无效循环, 这些循环每个都像真正的算法, 让你必须认认真真的单步跟踪, 好心累, 到这里这个子方法就结束了
4). 一路F8返回到主方法00444852处, 对比[00446854]与[00446850]这两个内存值是否相等(可见得上一步第6次循环的关键性), 相等则提示注册成功, 否则就没任何提示结束~

算法分析完了, 下面是注册机代码:

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

int main() {
	char user[21] = {0}; //用户名 
	unsigned char str[21] = {0}; //计算所得临时串 
	printf("用户名: "); scanf("%s", user);
	int len = strlen(user);
	if(len < 5){
		printf("用户名5位以上");
		return 0; 
	} 
	int s1 = 0, s2 = 0, s3 = 0;
	unsigned int s4 = 0;
	unsigned char al = 0, bl = 0;
	for(int i=0; i<len; i++) {
		al = user[i];
		al ^= 3;
		str[i] = al;
		s1 = al + s1 * 2;
		al = str[0] * len;
		str[i] += al;
		s2 += str[i];
	}
	for(int i=0; i<len; i++){ //00444848 call 0044460
		str[i] += i + 1 + 4;
		s3 = str[i] + s3 * 2;
	}
	s4 = s1 + s2 - s3 * (len - 2);
	
    printf("注册码: %X-%d-%d-%X\n", s3, s1, s2, s4);
    
	getchar();getchar();
	return 0;
}

运行示例:
用户名: abcde
注册码: 1275-3036-970-FFFFD847

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

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

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

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

posted @ 2024-08-06 16:02  hankerstudio  阅读(21)  评论(0)    收藏  举报