先跑一下

直接使用这个字符串去check,发现提示信息有关键字符串

CODE:0042FB80 00000021 C Sorry , The serial is incorect !

找到这个字符串的引用,有两个

跟下去发现这两个字符串都在一个函数中,最下面的3个框中左右都是错误,中间是对的,所以核心就在最上层和中间的这段代码

下面看看这段代码,直接在ollydbg中暂停,查看参数和返回值等信息

  1. CODE:0042F998 push ebp
  2. CODE:0042F999 mov ebp, esp
  3. CODE:0042F99B xor ecx, ecx
  4. CODE:0042F99D push ecx
  5. CODE:0042F99E push ecx
  6. CODE:0042F99F push ecx
  7. CODE:0042F9A0 push ecx
  8. CODE:0042F9A1 push ecx
  9. CODE:0042F9A2 push ecx
  10. CODE:0042F9A3 push ebx
  11. CODE:0042F9A4 push esi
  12. CODE:0042F9A5 mov ebx, eax
  13. CODE:0042F9A7 xor eax, eax
  14. CODE:0042F9A9 push ebp
  15. CODE:0042F9AA push offset loc_42FB67  
  16. CODE:0042F9AF push dword ptr fs:[eax]
  17. CODE:0042F9B2 mov fs:[eax], esp
  18. CODE:0042F9B5 mov ds:dword_431750, 29h
  19. CODE:0042F9BF lea edx, [ebp+var_10]
  20. CODE:0042F9C2 mov eax, [ebx+1DCh]
  21. CODE:0042F9C8 call sub_41AA58        ;这个函数返回18
  22. CODE:0042F9CD mov eax, [ebp+var_10]    ;这里取得了用户名字符串
  23. CODE:0042F9D0 call sub_403AB0        ;以用户名作为参数,调用sub_403AB0,这是一个判断用户名是不是空的函数
  24. CODE:0042F9D5 mov ds:dword_43176C, eax  ;将结果存放在固定位置,后面的第一个关键判断使用这个字符串
  25. CODE:0042F9DA lea edx, [ebp+var_10]
  26. CODE:0042F9DD mov eax, [ebx+1DCh]
  27. CODE:0042F9E3 call sub_41AA58
  28. CODE:0042F9E8 mov eax, [ebp+var_10]
  29. CODE:0042F9EB movzx eax, byte ptr [eax]
  30. CODE:0042F9EE mov esi, eax
  31. CODE:0042F9F0 shl esi,
  32. CODE:0042F9F3 sub esi, eax
  33. CODE:0042F9F5 lea edx, [ebp+var_14]
  34. CODE:0042F9F8 mov eax, [ebx+1DCh]
  35. CODE:0042F9FE call sub_41AA58
  36. CODE:0042FA03 mov eax, [ebp+var_14]
  37. CODE:0042FA06 movzx eax, byte ptr [eax+]
  38. CODE:0042FA0A shl eax,
  39. CODE:0042FA0D add esi, eax
  40. CODE:0042FA0F mov ds:dword_431754, esi
  41. CODE:0042FA15 lea edx, [ebp+var_10]
  42. CODE:0042FA18 mov eax, [ebx+1DCh]
  43. CODE:0042FA1E call sub_41AA58
  44. CODE:0042FA23 mov eax, [ebp+var_10]
  45. CODE:0042FA26 movzx eax, byte ptr [eax+]
  46. CODE:0042FA2A imul esi, eax, 0Bh
  47. CODE:0042FA2D lea edx, [ebp+var_14]
  48. CODE:0042FA30 mov eax, [ebx+1DCh]
  49. CODE:0042FA36 call sub_41AA58
  50. CODE:0042FA3B mov eax, [ebp+var_14]
  51. CODE:0042FA3E movzx eax, byte ptr [eax+]
  52. CODE:0042FA42 imul eax, 0Eh
  53. CODE:0042FA45 add esi, eax
  54. CODE:0042FA47 mov ds:dword_431758, esi
  55. CODE:0042FA4D mov eax, ds:dword_43176C
  56. CODE:0042FA52 call sub_406930        ;以用户名作为参数调用
  57. CODE:0042FA57 cmp eax,
  58. CODE:0042FA5A jge short loc_42FA79    ;第一个关键判断
  59. CODE:0042FA5C push ; uType
  60. CODE:0042FA5E mov ecx, offset aTryAgain_0 ; "Try Again!"
  61. CODE:0042FA63 mov edx, offset aSorryTheSerial ; "Sorry , The serial is incorect !"
  62. CODE:0042FA68 mov eax, ds:off_430A48
  63. CODE:0042FA6D mov eax, [eax] ; int
  64. CODE:0042FA6F call sub_42A170
  65. CODE:0042FA74 jmp loc_42FB37
  66. CODE:0042FA79 ; ---------------------------------------------------------------------------
  67. CODE:0042FA79
  68. CODE:0042FA79 loc_42FA79: ; CODE XREF: _TNS_BitBtn1Click+C2j
  69. CODE:0042FA79 lea edx, [ebp+var_10]
  70. CODE:0042FA7C mov eax, [ebx+1DCh]
  71. CODE:0042FA82 call sub_41AA58
  72. CODE:0042FA87 mov eax, [ebp+var_10]    ;取字符串
  73. CODE:0042FA8A movzx eax, byte ptr [eax]   ;取出字符串的第一个地址
  74. CODE:0042FA8D imul ds:dword_431750      ;前面将这个位置赋值成了0x29
  75. CODE:0042FA93 mov ds:dword_431750, eax   ;将第一个字符乘以0x29
  76. CODE:0042FA98 mov eax, ds:dword_431750
  77. CODE:0042FA9D add ds:dword_431750, eax    ;这里应该相当于乘以2
  78. CODE:0042FAA3 lea eax, [ebp+var_4]      ;将这个字符串的地址放到局部变量中
  79. CODE:0042FAA6 mov edx, offset _str_CW.Text
  80. CODE:0042FAAB call sub_403708          ;以字符串CW作为第二参数
  81. CODE:0042FAB0 lea eax, [ebp+var_8]        ;同上,将字符串地址放入局部变量
  82. CODE:0042FAB3 mov edx, offset _str_CRACKED.Text
  83. CODE:0042FAB8 call sub_403708          ;以字符串CRACKED作为第二参数
  84. CODE:0042FABD push [ebp+var_4]          ;pushCW
  85. CODE:0042FAC0 push offset _str___5.Text    ;push了又一个字符串
  86. CODE:0042FAC5 lea edx, [ebp+var_18]      ;这里是局部变量
  87. CODE:0042FAC8 mov eax, ds:dword_431750    ;这里是用户名第一个字符串经过运算之后的结果
  88. CODE:0042FACD call sub_406718          ;这里又对第一个字符串的运行结果再次进行一个运算
  89. CODE:0042FAD2 push [ebp+var_18]         ;将第二次运算结果放入var_18中,这里入栈了
  90. CODE:0042FAD5 push offset _str___5.Text    ;应该也是参数
  91. CODE:0042FADA push [ebp+var_8]
  92. CODE:0042FADD lea eax, [ebp+var_C]
  93. CODE:0042FAE0 mov edx,
  94. CODE:0042FAE5 call sub_4039AC          ;关键函数了,第一个参数是var_C,第二个是5,后面3个参数依次是前面push的内容
  95. CODE:0042FAEA lea edx, [ebp+var_10]
  96. CODE:0042FAED mov eax, [ebx+1E0h]
  97. CODE:0042FAF3 call sub_41AA58        ;这个函数读取了序列码的地址,然后返给var_10中作为下一个函数的参数
  98. CODE:0042FAF8 mov edx, [ebp+var_10]    ;第二个参数是序列码字符串
  99. CODE:0042FAFB mov eax, [ebp+var_C]    ;第一个参数是var_C,也是字符串
  100. CODE:0042FAFE call sub_4039FC        ;要求这个函数返回0
  101. CODE:0042FB03 jnz short loc_42FB1F
  102. CODE:0042FB05 push ; uType
  103. CODE:0042FB07 mov ecx, offset aCongratz_0 ; "Congratz !!"
  104. CODE:0042FB0C mov edx, offset aGoodJobDude ; "Good job dude =)"
  105. CODE:0042FB11 mov eax, ds:off_430A48
  106. CODE:0042FB16 mov eax, [eax] ; int
  107. CODE:0042FB18 call sub_42A170
  108. CODE:0042FB1D jmp short loc_42FB37
  109. CODE:0042FB1F ; ---------------------------------------------------------------------------
  110. CODE:0042FB1F
  111. CODE:0042FB1F loc_42FB1F: ; CODE XREF: _TNS_BitBtn1Click+16Bj
  112. CODE:0042FB1F push ; uType
  113. CODE:0042FB21 mov ecx, offset aTryAgain_0 ; "Try Again!"
  114. CODE:0042FB26 mov edx, offset aSorryTheSerial ; "Sorry , The serial is incorect !"
  115. CODE:0042FB2B mov eax, ds:off_430A48
  116. CODE:0042FB30 mov eax, [eax] ; int
  117. CODE:0042FB32 call sub_42A170

直接以默认的方式去运行,在ollydbg中看各个函数调用的参数和返回情况

在sub_406930处,传入用户名字符串,然后返回-2-(-1-length),也就是length-1,这里的length包括了'\0'字符,也就是说,最后这个函数的返回位用户名的字符串长度,最后结果为0x19,所以第一个条件判断为字符串长度大于4。这里已经符合了

然后是loc_42FA79处的函数,这个函数最后的跳转步骤在sub_4039FC处,要求这个函数返回0,而这个函数参数有两个,第一个参数是CW-6560-CRACKED,第二参数为序列码。所以这里猜测应该是根据用户名生成了6560这个字符串,和CW和CRACKED进行拼接,然后在这里进行最后一步的判断

从0042FA79开始,对汇编码进行了简要分析,这段可以直接在ollydbg中看各个函数的参数,结果以及栈的变化,可以大致猜出sub_4039AC应该是字符串拼接函数,而关键点的函数应该是一个字符串相对的判断函数。然后直接在序列码中输入CW-6560-CRACKED,发现果然正确,而6560这个值就是根据用户名字符串第一个字符乘以0x29再成2得到的,上文中没有分析的函数就是用来做字符串拼接(6560这个值在跟踪函数的过程中也会被放入到栈上,所以只需要用ollydbg跟踪调试每一步的变化就很容易得出结果了)

最后就OK了

适合新手的160个creakme(一)的更多相关文章

  1. 适合新手的160个creakme(四)

    这题没有什么特殊字符串,Delphi写的,使用DeDeDark分析一下,找到几个特殊的事件 一个是KeyUp 一个是chkcode 还有就是中间区域的单击或是双击事件 直接跟进去这几个函数,然后找比较 ...

  2. 适合新手的160个creakme(三)

    先跑一下,这个程序应该是有定时器,多久之后自动开启,测试一下输入,序列号以字母方式输入会出现类型不匹配,之后程序自动退出 但是如果以数字方式输入序列号,则会出现,Try Again,所以这里序列号应该 ...

  3. 适合新手的160个creakme(二)

    先跑一下,然后找出关键字符串 关键字符串是You Get Wrong和Try Again,不过IDA好像识别不出来这个字符串,在Ollydbg中右键Search For,寻找所有字符串,可以找到这些字 ...

  4. JavaSwing仿QQ登录界面,注释完善,适合新手学习

    使用说明: 这是一个java做的仿制QQ登录界面,界面仅使用一个类, JDK版本为jdk-11 素材包的名字为:素材(下载)请在项目中新建一个名字为“素材”的文件夹. 素材: https://pan. ...

  5. 最适合和最不适合新手使用的几款 Linux 发行版

    大多数知名的Linux发行版都属于"比较容易使用"这一类.一些观察人士可能会驳斥这个观点,但事实上,说到Linux,大多数并非从事IT或软件开发工作的人会被最容易的使用体验所吸引. ...

  6. python环境搭建-requests的简单安装(适合新手)

    安装完python之后,一定要记住安装后的路径.这是我当前的路径. 下面是requests的安装步骤: 我们这里直接用pip安装(这样比较适合新手),新版python自带pip,python3.6.1 ...

  7. 关于富文本编辑器ueditor(jsp版)上传文件到阿里云OSS的简单实例,适合新手

    关于富文本编辑器ueditor(jsp版)上传文件到阿里云OSS的简单实例,适合新手   本人菜鸟一枚,最近公司有需求要用到富文本编辑器,我选择的是百度的ueditor富文本编辑器,闲话不多说,进入正 ...

  8. 适合新手小白的UI学习路线完整版

    UI设计是很多年轻人活着想转行学习的人的新职业目标,越来越多的人看到UI设计良好的就业发展前景,纷纷投入到UI设计的大军中来,想学习UI设计,很多小白并不知道从何开始学起,用什么样的方法去学习,所以今 ...

  9. 适合新手的web开发环境

    学习web开发,环境搭建是必不可少的一个环节.你可以使用wamp一键安装包,或者使用sae.bae.gae这种PaaS平台来部署,或者安装*nix系统在本地部署. 对于一个希望体验LAMP式建站的新手 ...

随机推荐

  1. docker pull 报错Get https://xxx.xxx.xxx.xxx:5000/v1/_ping: http: server gave HTTP response

    解决方法: vim /etc/docker/daemon.json { "insecure-registries":["xxx.xxx.xxx.xxx:5000" ...

  2. Solr 7.X 安装和配置--Linux篇

    1. 关闭防火墙和Selinux 2. 安装所需环境JDK 3. 下载Solr7.4版本 4. 下载并配置solr的中文分词器IK Analyzer 5. 启动Solr 6. 注意事项以及说明 1. ...

  3. 验证HashSet和HashMap不是线程安全

    JAVA集合类: java.util包下的HashSet和HashMap类不是线程安全的, java.util.concurrent包下的ConcurrentHashMap类是线程安全的. 写2个测试 ...

  4. Win10 更新出现问题,建议完全重置系统

    语言包引起问题.   文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论

  5. Python下划线命名模式

  6. SQL中instr和like的使用区别

    1.instr函数 instr函数是一个字符串处理函数,它在Oracle/PLSQL中是返回子字符串在源字符串中的位置,如果在源串中没有找到子串,则返回0. instr函数定义如下: /* * 返回子 ...

  7. Spring事务管理4-----声明式事务管理(2)

    声明式事务管理  基于AspectJ的 XML 方式配置 通过对事务管理器TransactionManager配置通知(增强),然后再配置切点和切面,详细见applicationContext.xml ...

  8. 用python画函数图像

    import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 1, 50) # 从0到1,等分50分 y = 210*(x ...

  9. JAVA 基础编程练习题22 【程序 22 递归求阶乘】

    22 [程序 22 递归求阶乘] 题目:利用递归方法求 5!. 程序分析:递归公式:fn=fn_1*4! package cskaoyan; public class cskaoyan22 { @or ...

  10. pch文件的添加

    想说试了好久一直报错找不到文件,解决方法如下: 依次是:./项目名/文件夹名称/pch文件名