当前位置: 首页 > 编程日记 > 正文

CrackMe_001

本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西。

其中,文章中按照如下逻辑编排(解决如下问题):

1、使用什么环境和工具

2、程序分析

3、思路分析和破解流程

4、注册机的探索


1、工具和环境:

WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指。

160个CrackMe的打包文件。

下载地址: http://pan.baidu.com/s/1xUWOY  密码: jbnq

注:

1、Win7系统对于模块和程序开启了随机初始地址的功能,会给分析带来很大的负担,所以不建议使用Win7进行分析。

2、以上工具都是在52PoJie论坛下的原版程序,NOD32不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。

image

2、程序分析:

    想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。

    打开CHM文件,将第一个文件 Acid burn.exe 保存下来,新建一个01的文件夹,将exe放到这里,同时将以后的分析文件也存放这里。打开Acid burn.exe,随意输入和点击,熟悉程序流程。

image

我们发现,这个软件分为了两个部分,一个是Serial/Name,需要输入用户名和注册码才能通过,另外一个Serial只需要输入一个注册码一类的东西。我们随意选一个开始,比如,先进行第一个。

image

我们随意输入一个用户名和序列号(伪码):

伪码:
Name:112233
Serial:44556677

点击Check it Baby! 它会弹出一个对话框提示: Sorry, The Serial is incorrect !

再换几个随意试试,发现就这一种情况。

OK,出现了对话框这就很好办,说明作者在校验注册码之后发现如果错误了就直接弹窗,我们只要找到弹出对话框的地方,向上跟踪,就可以找出判断是否正确的地方了,jmp或者Nop就算爆破了。


3、具体步骤如下:

我们随意输入一个用户名和序列号(伪码):

Name:112233
Serial:44556677

点击Check it Baby! 它会弹出一个对话框提示: Sorry, The Serial is incorrect !

此时不要点击确定按钮,返回OD暂停(F12),点击堆栈-K小图标(Ctrl+K) ,如下图:

c2

这里有两个MessageBox的地址,第一个地址为77D5082F这个地址明显太大,不在模块的领空,不是的。第二个地址为0042A1AE,和00400100地址非常接近,十有八九就是它了。

右键 show call, 在Call上面设置断点。

查看附近代码:

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
0042A170  /$  55            push ebp
0042A171  |.  8BEC          mov ebp,esp
0042A173  |.  83C4 F4       add esp,-0xC
0042A176  |.  53            push ebx
0042A177  |.  56            push esi
0042A178  |.  57            push edi
0042A179  |.  8BF9          mov edi,ecx
0042A17B  |.  8BF2          mov esi,edx
0042A17D  |.  8BD8          mov ebx,eax
0042A17F  |.  E8 7CB4FDFF   call <jmp.&user32.GetActiveWindow>       ; [GetActiveWindow
0042A184  |.  8945 F8       mov [local.2],eax
0042A187  |.  33C0          xor eax,eax
0042A189  |.  E8 12A0FFFF   call 004241A0
0042A18E  |.  8945 F4       mov [local.3],eax
0042A191  |.  33C0          xor eax,eax
0042A193  |.  55            push ebp
0042A194  |.  68 D0A14200   push 0042A1D0
0042A199  |.  64:FF30       push dword ptr fs:[eax]
0042A19C  |.  64:8920       mov dword ptr fs:[eax],esp
0042A19F  |.  8B45 08       mov eax,[arg.1]
0042A1A2  |.  50            push eax                                 ; /Style
0042A1A3  |.  57            push edi                                 ; |Title
0042A1A4  |.  56            push esi                                 ; |Text
0042A1A5  |.  8B43 24       mov eax,dword ptr ds:[ebx+0x24]          ; |
0042A1A8  |.  50            push eax                                 ; |hOwner
0042A1A9  |.  E8 FAB5FDFF   call <jmp.&user32.MessageBoxA>           ; \MessageBoxA

发现,没有跳转语句,逻辑很简单,在之上几行处就有retn,在头部push ebp下断,重新点击Check it baby 按钮,在右下角堆栈处找到最近一条Return语句:

0012F974   0042FB37  RETURN to Acid_bur.0042FB37 from Acid_bur.0042A170

右键 Follow in Disassm..(反汇编跟随),这里直接连接了一个跳转,代码如下:

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
0042FAD5  |.  68 C8FB4200   push 0042FBC8                            ;  UNICODE "-"
0042FADA  |.  FF75 F8       push [local.2]
0042FADD  |.  8D45 F4       lea eax,[local.3]
0042FAE0  |.  BA 05000000   mov edx,0x5
0042FAE5  |.  E8 C23EFDFF   call 004039AC
0042FAEA  |.  8D55 F0       lea edx,[local.4]
0042FAED  |.  8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3  |.  E8 60AFFEFF   call 0041AA58
0042FAF8  |.  8B55 F0       mov edx,[local.4]
0042FAFB  |.  8B45 F4       mov eax,[local.3]
0042FAFE  |.  E8 F93EFDFF   call 004039FC
0042FB03      75 1A         jnz short 0042FB1F                       ;  // 这个JNZ条件判断很关键?
0042FB05  |.  6A 00         push 0x0
0042FB07  |.  B9 CCFB4200   mov ecx,0042FBCC
0042FB0C  |.  BA D8FB4200   mov edx,0042FBD8
0042FB11  |.  A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042FB16  |.  8B00          mov eax,dword ptr ds:[eax]
0042FB18  |.  E8 53A6FFFF   call 0042A170
0042FB1D  |.  EB 18         jmp short 0042FB37                       ;  // 这个跳转是不是很可疑?
0042FB1F  |>  6A 00         push 0x0
0042FB21  |.  B9 74FB4200   mov ecx,0042FB74                         ;  ASCII 54,"ry Again!"
0042FB26  |.  BA 80FB4200   mov edx,0042FB80                         ;  ASCII 53,"orry , The serial is incorect !"
0042FB2B  |.  A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042FB30  |.  8B00          mov eax,dword ptr ds:[eax]
0042FB32  |.  E8 39A6FFFF   call 0042A170                            ;  这个CALL是导致跳转的语句
0042FB37  |>  33C0          xor eax,eax                              ;  返回到了这里

看到和提示框一样的文本,是不是感到很亲切?OK,我们大概浏览下代码,最近部分有两个可疑跳转JNZ 和JMP, JNZ会通过它上面的call 004039FC 判断我们的伪码是否正确,判断的结果存在EAX中,如果EAX不等于就跳转到错误提示信息框那里。我们的目的是无论伪码是否正确都通过验证,所以最简单的 办法就是将jnz这句使用NOP填充,我们尝试一下:选择JNZ这句,右键Binary->Fill with NOPS.回到原始程序,再次点击Check it baby!

哈哈,提示Good Job!通过了!

再次比对MessageBox和堆栈(Ctrl+K)窗口最后一个调用,是不是发现什么特殊的地方?对啦!那个CALL就是调用MessageBox的地方,所以,下次我们就不用在MessageBox处下断跟踪了,直接最后一个地址,show call。


4、注册机部分

以上部分是爆破分析,我们看看能否分析出注册机算法。
在原JNZ上面一行CALL下断:点击Ckeck it Baby!按钮,程序断下:

1
2
3
0042FAF8  |.  8B55 F0       mov edx,[local.4]                        ;  // EDX=44556677
0042FAFB  |.  8B45 F4       mov eax,[local.3]                        ;  // EAX=CW-4018-CRACKED
0042FAFE  |.  E8 F93EFDFF   call 004039FC

我们发现,EDX存储的是我们的假序列号,EAX看上去像是一个正确的序列号,也有可能是对应的用户名也说不定,我们可疑尝试一下。
现将我们之前修改的代码恢复:选中那两行NOP,右键Undo... 。取消断点。先尝试是否是Name,Name输入EAX的值,下一行继续44556677,结果继续弹错。然后尝试作为序列号,Name为 112233,Serial为CW-4018-CRACKED,再尝试,OK!完全正确!

小结一下:在这个CALL之前程序已经将用户名对应的序列号算出来了,然后和我们输入的Serial通过这个CALL对比,最终给出提示信息。我们要的算法不再这个CALL中。

下一步的思路就是继续在这个CALL之上的CALL下断,分析出产生出这个序列号的CALL。由于CALL的返回值一般都存在EAX中,所以我们可以查看附近的CALL之后EAX的值,从而判断出正确的注册码生成函数。

附近的两个CALL:

1
2
3
4
5
6
7
8
9
0042FADD  |.  8D45 F4       lea eax,[local.3]
0042FAE0  |.  BA 05000000   mov edx,0x5
0042FAE5  |.  E8 C23EFDFF   call 004039AC                            ;  // 最近的CALL2
0042FAEA  |.  8D55 F0       lea edx,[local.4]
0042FAED  |.  8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3  |.  E8 60AFFEFF   call 0041AA58                            ;  // 最近的CALL 1
0042FAF8  |.  8B55 F0       mov edx,[local.4]                        ;  // EDX=44556677
0042FAFB  |.  8B45 F4       mov eax,[local.3]                        ;  // EAX=CW-4018-CRACKED
0042FAFE  |.  E8 F93EFDFF   call 004039FC

分别在CALL之后的那一句下断,点击按钮,F8步过,发现在 附近的CALL 1 处,EAX出现正确的注册码,说明他可能是关键的注册码CALL,下面对它的进行分析:
重新在call 0041AA58 下断,

1
2
3
0042FAEA  |.  8D55 F0       lea edx,[local.4]                        ;  edx=0012F998
0042FAED  |.  8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]         ;  eax=00A85E4C
0042FAF3  |.  E8 60AFFEFF   call 0041AA58                            ;  // 最近的CALL 1,注册码CALL

其中edx和eax都没有特殊信息出现,我们就可以更加断定注册码都是在call中生成的。

这时我们就有两种方案了,一种分析CALL的参数,直接远程调用CALL生成正确的注册码,另一种是分析CALL的内容,根据他的算法自己写一个这个生成流程。这两个无明显的好坏之分,只看用在什么地方了。

按照我的理解,第一种,内存调用适合算法复杂或者更新不频繁的程序,这么做可以节省时间和复杂度。第 二种,适合算法不是特别复杂,或者软件更新频繁的软件,算法的复杂度就不说了,软件无论更新多么频繁,一般注册码算法是不会变的,这样生成的注册机就可以 适用所有的版本,大家都省事。

好了,啰嗦了这么多,开始正式分析:
(由于已经在这里CALL被调用了很多次了,各个寄存器参数很乱,建议从新加载一次程序,方便分析)
进入CALL 0041AA58,代码如下:
(由于这个CALL被很多地方一直调用,所以我们必须每次从上层CALL单步F7跟踪,直到找到正确的CALL)

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
0041AA58  /$  53            push ebx
0041AA59  |.  56            push esi
0041AA5A  |.  57            push edi
0041AA5B  |.  8BFA          mov edi,edx
0041AA5D  |.  8BF0          mov esi,eax
0041AA5F  |.  8BC6          mov eax,esi
0041AA61  |.  E8 A2FFFFFF   call 0041AA08                            ;  // 这里直接跳出去了,所以需要继续跟踪
0041AA66  |.  8BD8          mov ebx,eax
0041AA68  |.  8BC7          mov eax,edi
0041AA6A  |.  8BCB          mov ecx,ebx
0041AA6C  |.  33D2          xor edx,edx
0041AA6E  |.  E8 E18CFEFF   call 00403754
0041AA73  |.  85DB          test ebx,ebx
0041AA75  |.  74 0C         je short 0041AA83
0041AA77  |.  8D4B 01       lea ecx,dword ptr ds:[ebx+0x1]
0041AA7A  |.  8B17          mov edx,dword ptr ds:[edi]
0041AA7C  |.  8BC6          mov eax,esi
0041AA7E  |.  E8 95FFFFFF   call 0041AA18
0041AA83  |>  5F            pop edi
0041AA84  |.  5E            pop esi
0041AA85  |.  5B            pop ebx
0041AA86  \.  C3            retn
继续跟踪到这里:
0041AA08  /$  6A 00         push 0x0                                 ; /Arg1 = 00000000
0041AA0A  |.  33C9          xor ecx,ecx                              ; |
0041AA0C  |.  BA 0E000000   mov edx,0xE                              ; |
0041AA11  |.  E8 F6070000   call 0041B20C                            ; \Acid_bur.0041B20C
0041AA16  \.  C3            retn
继续:
0041B20C  /$  55            push ebp
0041B20D  |.  8BEC          mov ebp,esp
0041B20F  |.  83C4 F0       add esp,-0x10
0041B212  |.  53            push ebx
0041B213  |.  8955 F0       mov [local.4],edx
0041B216  |.  894D F4       mov [local.3],ecx
0041B219  |.  8B55 08       mov edx,[arg.1]
0041B21C  |.  8955 F8       mov [local.2],edx
0041B21F  |.  33D2          xor edx,edx
0041B221  |.  8955 FC       mov [local.1],edx
0041B224  |.  85C0          test eax,eax
0041B226  |.  74 0B         je short 0041B233
0041B228  |.  8D55 F0       lea edx,[local.4]
0041B22B  |.  8BD8          mov ebx,eax
0041B22D  |.  8B43 2C       mov eax,dword ptr ds:[ebx+0x2C]
0041B230  |.  FF53 28       call dword ptr ds:[ebx+0x28]
0041B233  |>  8B45 FC       mov eax,[local.1]
0041B236  |.  5B            pop ebx
0041B237  |.  8BE5          mov esp,ebp
0041B239  |.  5D            pop ebp
0041B23A  \.  C2 0400       retn 0x4
继续F7步入:
0041CB64  /$  53            push ebx
0041CB65  |.  56            push esi
0041CB66  |.  57            push edi
0041CB67  |.  83C4 F0       add esp,-0x10
0041CB6A  |.  8BF2          mov esi,edx
0041CB6C  |.  8BD8          mov ebx,eax
0041CB6E  |.  8B06          mov eax,dword ptr ds:[esi]
0041CB70  |.  3D 84000000   cmp eax,0x84                             ;  Switch (cases 7..20A)
0041CB75  |.  7F 18         jg short 0041CB8F
0041CB77  |.  74 69         je short 0041CBE2
...

跟了一大堆,我们发现没有地方可产生注册码,并且所有的CALL都是不断地在被调用,所以,初步判定 注册码不是在这里生成的。但是这么想就与之前的猜测完全推翻了,说明我们的想法有问题,即思路有问题。既然他的码不是及时算出来的,那肯定就是事先算好 的,我们再次回到产生注册码的CALL那里,向上查找,F8单步进行查看。

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
0042FA4D  |.  A1 6C174300   mov eax,dword ptr ds:[0x43176C]          ;  // name/Tag
0042FA52  |.  E8 D96EFDFF   call 00406930                            ;  // 关键CALL
0042FA57  |.  83F8 04       cmp eax,0x4                              ;  // 判断tag/serial 是否合格
0042FA5A  |.  7D 1D         jge short 0042FA79
0042FA5C  |.  6A 00         push 0x0
0042FA5E  |.  B9 74FB4200   mov ecx,0042FB74                         ;  ASCII 54,"ry Again!"
0042FA63  |.  BA 80FB4200   mov edx,0042FB80                         ;  ASCII 53,"orry , The serial is incorect !"
0042FA68  |.  A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042FA6D  |.  8B00          mov eax,dword ptr ds:[eax]
0042FA6F  |.  E8 FCA6FFFF   call 0042A170
0042FA74  |.  E9 BE000000   jmp 0042FB37
0042FA79  |>  8D55 F0       lea edx,[local.4]
0042FA7C  |.  8B83 DC010000 mov eax,dword ptr ds:[ebx+0x1DC]
0042FA82  |.  E8 D1AFFEFF   call 0041AA58
0042FA87  |.  8B45 F0       mov eax,[local.4]                        ;  EAX=112233的地址
0042FA8A  |.  0FB600        movzx eax,byte ptr ds:[eax]              ;  第一个字节1=0x31
0042FA8D  |.  F72D 50174300 imul dword ptr ds:[0x431750]             ;  *0x29
0042FA93  |.  A3 50174300   mov dword ptr ds:[0x431750],eax          ;  eax=0x7d9=0x29*0x31
0042FA98  |.  A1 50174300   mov eax,dword ptr ds:[0x431750]
0042FA9D  |.  0105 50174300 add dword ptr ds:[0x431750],eax          ;  加一倍
0042FAA3  |.  8D45 FC       lea eax,[local.1]
0042FAA6  |.  BA ACFB4200   mov edx,0042FBAC
0042FAAB  |.  E8 583CFDFF   call 00403708
0042FAB0  |.  8D45 F8       lea eax,[local.2]
0042FAB3  |.  BA B8FB4200   mov edx,0042FBB8
0042FAB8  |.  E8 4B3CFDFF   call 00403708
0042FABD  |.  FF75 FC       push [local.1]
0042FAC0  |.  68 C8FB4200   push 0042FBC8                            ;  UNICODE "-"
0042FAC5  |.  8D55 E8       lea edx,[local.6]                        ;  12F990
0042FAC8  |.  A1 50174300   mov eax,dword ptr ds:[0x431750]          ;  4018
0042FACD  |.  E8 466CFDFF   call 00406718
0042FAD2  |.  FF75 E8       push [local.6]                           ;  // 注册码中间的值
0042FAD5  |.  68 C8FB4200   push 0042FBC8                            ;  UNICODE "-"
0042FADA  |.  FF75 F8       push [local.2]
0042FADD  |.  8D45 F4       lea eax,[local.3]
0042FAE0  |.  BA 05000000   mov edx,0x5
0042FAE5  |.  E8 C23EFDFF   call 004039AC
0042FAEA  |.  8D55 F0       lea edx,[local.4]                        ;  edx=0012F998
0042FAED  |.  8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]         ;  eax=00A85E4C
0042FAF3  |.  E8 60AFFEFF   call 0041AA58                            ;  // 注册码CALL
0042FAF8  |.  8B55 F0       mov edx,[local.4]                        ;  // EDX=44556677
0042FAFB  |.  8B45 F4       mov eax,[local.3]                        ;  // EAX=CW-4018-CRACKED
0042FAFE  |.  E8 F93EFDFF   call 004039FC
0042FB03      75 1A         jnz short 0042FB1F                       ;  // 这个JNZ条件判断很关键?
0042FB05  |.  6A 00         push 0x0
0042FB07  |.  B9 CCFB4200   mov ecx,0042FBCC
0042FB0C  |.  BA D8FB4200   mov edx,0042FBD8
0042FB11  |.  A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042FB16  |.  8B00          mov eax,dword ptr ds:[eax]
0042FB18  |.  E8 53A6FFFF   call 0042A170
0042FB1D  |.  EB 18         jmp short 0042FB37                       ;  // 这个跳转是不是很可疑?
0042FB1F  |>  6A 00         push 0x0
0042FB21  |.  B9 74FB4200   mov ecx,0042FB74                         ;  ASCII 54,"ry Again!"
0042FB26  |.  BA 80FB4200   mov edx,0042FB80                         ;  ASCII 53,"orry , The serial is incorect !"

总结:取第一个字母的ASNI的数字,如112233中第一个字符1对应数字0x31,然后用它乘以0x29,结果再自增一倍(即x2),将得到的数字转为10进制的字符串,在前加上”CW-”,后加上”-CRACKED”,就组成了用户名对应的注册码。

C/CPP程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// CrackMe160.cpp : 定义控制台应用程序的入口点。
// NameSerial部分
#include "stdafx.h"
#include "iostream"
int _tmain(int argc, _TCHAR* argv[])
{
    printf("Input Name:\r\n");
    // 取第一个字符值
    int cName = getchar();
    if ( cName > 0x21) // 只处理可见字符
    {
        cName *= 0x29; // 乘法
        cName *= 2; // 自增一倍
        printf("Serial: CW-%4d-CRACKED\r\n",cName);
    }else{
        printf("input error!\r\n");
    }
    system("pause");
    return 0;
}


第二个单独Serial

流程同第一个,

c2

但是这个很简单,直接在调用CALL那里向上F8走一遍就基本明白了。

核心代码:

CALL之前的那个JNZ是爆破的关键,直接NOP就OK了。

JNZ之前的那个CALL是进行Serial判断的关键,通过单步跟踪发现他就是一个固定值。

代码如下:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
0042F470  /.  55            push ebp
0042F471  |.  8BEC          mov ebp,esp
0042F473  |.  33C9          xor ecx,ecx
0042F475  |.  51            push ecx
0042F476  |.  51            push ecx
0042F477  |.  51            push ecx
0042F478  |.  51            push ecx
0042F479  |.  53            push ebx
0042F47A  |.  8BD8          mov ebx,eax
0042F47C  |.  33C0          xor eax,eax
0042F47E  |.  55            push ebp
0042F47F  |.  68 2CF54200   push 0042F52C
0042F484  |.  64:FF30       push dword ptr fs:[eax]
0042F487  |.  64:8920       mov dword ptr fs:[eax],esp
0042F48A  |.  8D45 FC       lea eax,[local.1]
0042F48D  |.  BA 40F54200   mov edx,0042F540                         ;  ASCII 48,"ello"
0042F492  |.  E8 7142FDFF   call 00403708
0042F497  |.  8D45 F8       lea eax,[local.2]
0042F49A  |.  BA 50F54200   mov edx,0042F550                         ;  ASCII 44,"ude!"
0042F49F  |.  E8 6442FDFF   call 00403708
0042F4A4  |.  FF75 FC       push [local.1]
0042F4A7  |.  68 60F54200   push 0042F560                            ;  UNICODE " "
0042F4AC  |.  FF75 F8       push [local.2]
0042F4AF  |.  8D45 F4       lea eax,[local.3]
0042F4B2  |.  BA 03000000   mov edx,0x3
0042F4B7  |.  E8 F044FDFF   call 004039AC
0042F4BC  |.  8D55 F0       lea edx,[local.4]
0042F4BF  |.  8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042F4C5  |.  E8 8EB5FEFF   call 0041AA58
0042F4CA  |.  8B45 F0       mov eax,[local.4]                        ;  // eax=112233
0042F4CD  |.  8B55 F4       mov edx,[local.3]                        ;  // edx=Hello Dude!
0042F4D0  |.  E8 2745FDFF   call 004039FC
0042F4D5      75 1A         jnz short 0042F4F1                       ;  // 爆破的关键
0042F4D7  |.  6A 00         push 0x0
0042F4D9  |.  B9 64F54200   mov ecx,0042F564
0042F4DE  |.  BA 70F54200   mov edx,0042F570
0042F4E3  |.  A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042F4E8  |.  8B00          mov eax,dword ptr ds:[eax]
0042F4EA  |.  E8 81ACFFFF   call 0042A170
0042F4EF  |.  EB 18         jmp short 0042F509
0042F4F1  |>  6A 00         push 0x0
0042F4F3  |.  B9 84F54200   mov ecx,0042F584
0042F4F8  |.  BA 8CF54200   mov edx,0042F58C
0042F4FD  |.  A1 480A4300   mov eax,dword ptr ds:[0x430A48]
0042F502  |.  8B00          mov eax,dword ptr ds:[eax]
0042F504  |.  E8 67ACFFFF   call 0042A170
0042F509  |>  33C0          xor eax,eax

这个没有动态生成的注册码,是一个固定的:Hello Dude!

摘自:http://www.cnblogs.com/bbdxf/p/3777711.html

转载于:https://www.cnblogs.com/milantgh/p/3865650.html

相关文章:

用javascript实现的纵版飞行射击游戏—《天机》

花了一个半月的时间用javascript完成了这款web版飞行射击游戏&#xff0c;游戏效果接近一般的客户端游戏&#xff0c;不过对机器的要求稍微高点点&#xff0c;主要是CPU&#xff0c;最好在1.5GHZ以上&#xff0c;不然可能会比较卡&#xff0c;支持IE、FF、Opera、safari。 用ja…

对分组交换(packet switching)高效迅速灵活可靠四个优点的理解

1.什么是分组&#xff1f; 通信过程中要发送的整块数据被称为一个报文(message)&#xff0c;报文被划分为一个个更小的等长数据段&#xff0c;每个数据段前加入一些由必要的控制信息组成的首部后&#xff0c;就构成了一个分组。分组是在互联网中传送的数据单元(长报文&#xff…

06、ActivationDeactivation

1、将App.xaml中的StartupUri"MainWindow.xaml"删除。 2、使用NuGet安装Prism.Wpf、Prism.Core、Prism.Unity。 3、添加类“Bootstrapper”&#xff0c;编辑如下&#xff1a; 1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System…

Git 学习笔记一

Git的基本配置和使用 一、git add ;git commit;git commit -a(默认跟踪修改直接提交(不包括新文件))。 二、tig命令 查看修改记录的前端工具&#xff0c;方面查看修改记录。相当于git log –p。 三、git config --global alias.ci "commit -a -v"添加命令别名&#x…

vb 取得计算机名及目录

Public gCompName 取得计算机名及Windows目录 Dim i% Dim c$ Dim cSql As String Dim cProduct As String c Space(256) i GetComputerName(c, 256) gCompName Trim(c) gCompName Left(gCompName, Len(gCompName) - 1) 读取MAC地址 Dim…

速率单位和信息量单位区分

网络技术钟的速率指的是数据的传送速率&#xff0c;也称为数据率或比特率。 单位是bit/s 比特每秒 也写作b/s 或bps(bit per second) 当数据率较高时 常常在bit/s前面加一个字母&#xff0c;如 k 10^3 M 10^6 G 10^9 T 10^12 P 10^15 …… 数据量往往用字节B作为度量单位…

python 自动生成C++代码 (代码生成器)

python 代码自动生成的方法 &#xff08;代码生成器&#xff09; 遇到的问题 工作中遇到这么一个事&#xff0c;需要写很多C的底层数据库类&#xff0c;但这些类大同小异&#xff0c;无非是增删改查&#xff0c;如果人工来写代码&#xff0c;既费力又容易出错&#xff1b;而借用…

WPF实用指南二:移除窗体的图标

原文:WPF实用指南二&#xff1a;移除窗体的图标WPF没有提供任何功能来移除窗体上的icon图标。一般的做法是设置一个空白的图标&#xff0c;如下图1: 这种做法在窗体边框与标题之间仍然会保留一片空白。比较好的做法是使用Win32API提供的函数来移除这个图标。使用如下的代码&…

什么是EAI?

什么是EAI(enterprise application integration)企业应用集成? EAI是将基于各种不同平台、用不同方案建立的异构应用集成的一种方法和技术。EAI通过建立底层结构&#xff0c;来联系横贯整个企业的异构系统、应用、数据 源等&#xff0c;完成在企业内部的 ERP、CRM、SCM、数据库…

C# 中的委托和事件

引言 委托 和 事件在 .Net Framework中的应用非常广泛&#xff0c;然而&#xff0c;较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿&#xff0c;过了这个槛的人&#xff0c;觉得真是太容易了&#xff0c;而没有过去的人每次见到委托和事件就觉…

零代价修复海量服务器的内核缺陷——UCloud内核热补丁技术揭秘

下述为UCloud资深工程师邱模炯在InfoQ架构师峰会上的演讲——《UCloud云平台的内核实践》中非常受关注的内核热补丁技术的一部分。给大家揭开了UCloud云平台内核技术的神秘面纱。 如何零代价修复海量服务器的Linux内核缺陷&#xff1f; 对于一个拥有成千上万台服务器的公司&…

软件工程技术基础-(软件复用技术)

软件可重用问题&#xff0c;包括源程序代码重用、静态库重用和组建重用。 源程序代码重用是直接将其他项目或系统开发完成的代码复制过来&#xff0c;直接使用。 限制源程序代码重用技术使用的关键因素是要考虑代码的语言实现&#xff0c;以及源代码 公开可能带来的知识产权问题…

Parcelable与Serializable的比较

Parcel: Android中的序列化方式&#xff0c;可用于跨进程传输 Parcelable 进程间 如&#xff1a;想从一个第三方app拿进程回来 Serializable 进程内

20140725 快速排序时间复杂度 sTL入门

1、快速排序的时间复杂度(平均时间复杂度为) 数组本身就有序时&#xff0c;效果很差为O(n^2) 2、STl入门 &#xff08;1&#xff09; C内联函数(inline)和C中宏(#define)区别 内联函数有类型检查&#xff0c;宏定义没有&#xff1b;C编程尽量使用内联函数 template <class T…

小编带你进入强如 Disruptor 也发生内存溢出?

前言OutOfMemoryError 问题相信很多朋友都遇到过&#xff0c;相对于常见的业务异常&#xff08;数组越界、空指针等&#xff09;来说这类问题是很难定位和解决的。 本文以最近碰到的一次线上内存溢出的定位、解决问题的方式展开&#xff1b;希望能对碰到类似问题的同学带来思路…

数据库反规范设计

< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd> 反规范化设计 为了提升性能而使用反规范化设计 常用方法&#xff1a; A、在多个表中存储某个字段的副本 B、在父表中存储汇总值 C、将活动数据和历史数据分开存储 D、应用程序本地缓…

安卓的两种界面编写方式对比

1.XML进行描述 优点是可以直接在Android studio Preview 栏中查看效果(所见即所得&#xff0c;但是不是所有的都可以立刻看到效果) 注意&#xff1a;包含两种方式-编辑layout文件夹下的XML文件 和 直接从下图的图形化界面操作 2.Java/Kotlin代码进行编写 随着学习的深入&#x…

对象***已断开连接或不在该服务器上 的解决方案之一

使用VS2008在发布网站的时候&#xff0c;出现了这样的一个错误&#xff0c;先前一直是OK的。网上找了老半天&#xff0c;几乎没有此问题的解决办法。很是郁闷。只能一个一个地进行编译。单个层Build是OK的&#xff0c;整个Solution的Rebuild也是OK的&#xff0c;一开始使用VS自…

Web.XML文件中关于代码提示的一些问题

1. 问题描述 在进行ssm的整合时&#xff0c;我发现在web.xml文件中里按了alt/以后没有下面的提示&#xff1a;这样真的很不爽。。。于是弄了半天&#xff08;主要是等着&#xff09;终于解决了&#xff0c;特此写篇博客记录下。 2. 解决方案 在eclipse中安装Spring IDE的插件&a…

安卓开发之点九图

Nine-Patch图 xxx.9.png 口诀&#xff1a;左上进行拉伸&#xff0c;右下进行显示。

ImportError: No module named images

&#xff3b;问题&#xff3d; 在使用学习wxPython时&#xff0c;一个Dem抱有如题所示错误 &#xff3b;解决&#xff3d; images 只不过是wxpython自带demo中的一个文件 体验wxpython IN action的时候ImportError: No module named images替换为import wx.py.images as images…

从 Java 到 Scala(二):object

本文由 Rhyme 发表在 ScalaCool 团队博客。 object是一种让静态回归常态、打破模式、天然的语言特性。 其实在写这篇文章之前&#xff0c;我思绪万千&#xff0c;迟迟不能落笔&#xff0c;总想着自己会不会遗漏了某个知识点&#xff0c;或者有讲得不太那么准确的地方&#xff0…

Python获取屏幕分辨率大小

获取屏幕大小有两种方法可以办到: 1.wxPython里的 2.win32api 1 #coding:gb23122 #wxApp.py 3 #author: aoogur4 importos5 importwx6 fromwin32api importGetSystemMetrics7 8 classFrame(wx.Frame):9 def__init__(self):10 wx.Frame.__init__(self,None,-1,title"wxApp.…

安卓事件传递机制

1.触摸事件 MotionEvent ACTION_DOWN:按下 ACTION_MOVE:移动 ACTION_UP:松开 2.以上三个触摸事件都会经历三个函数 事件分发&#xff08;Dispatch&#xff09;&#xff1a;dispatchTouchEvent 事件拦截 &#xff08;Intercept&#xff09;&#xff1a;onInterceptTouchEvent 事…

财务软件的管理监督

随着现代企业的发展&#xff0c;企业财务管理的内涵、外延、功能及其地位发生了深刻的变化&#xff0c;强化企业的财务管理已经成为现代企业在激烈的市场竞争中得以生存和发展、现代企业制度得以保证和实施的重要环节。财务管理软件的应用已经非常普及了。 现代企业财务管…

[Vue CLI 3] 插件编写实战和源码分析

当你看过了官方的几个插件之后&#xff0c;慢慢地&#xff0c;其实你也有需求了。 那如何编写一个 Vue CLI 3 的插件呢&#xff1f;本文代码已经放到 github 上&#xff0c;地址&#xff1a;https://github.com/dailynodej... 我们建一个文件夹&#xff0c;取名 vue-cli-plugin…

突然想起99年的那次离别

今天妹妹离开成都回家了突然发现某一件事情又那么蹿了出来了&#xff0c;是99年的秋天那次&#xff0c;同f到成都且分开的那短暂的2天&#xff01;很多年了&#xff0c;不知道是忘记了再回忆起&#xff0c;还是一直埋在最深处&#xff0c;瞬间又重现&#xff01;想了&#xff0…

列表组件之ListView

1.ListView是什么 一个显示可滚动项目的视图组件系统使用Adapter(适配器)将列表项目插入列表适配器从来源提取内容 下图从MVC分析的话&#xff0c;ListView相当于View&#xff0c;Adapter相当于Controller&#xff0c;data相当于Model 缺点&#xff1a;屏幕里面只能展示有限个…

C#杂记系列之日期函数

//2008年4月24日 System.DateTime.Now.ToString("D"); //2008-4-24 System.DateTime.Now.ToString("d"); //2008年4月24日 16:30:15 System.DateTime.Now.ToString("F"); //2008年4月24日 16:30 System.DateTime.Now.ToString("f"); /…