qzhsjz 发表于 2020-8-1 19:01

不用调试,我才是最简单的CrackMe:大道至简


不需要任何分析,你甚至不需要调试器的参与,只要点击“破解”按钮即可破解这个程序。
对于这个程序来说,破解失败比破解成功要困难许多。
那么,你准备好了吗?只要按一下按钮,即可完成任务哦!

如果你不幸破解失败了,那么恭喜你,你解出了完整的题目!

一如既往的,没有壳,没有花指令,只有VS默认的编译优化。


天南地北一群魔 发表于 2020-8-1 21:24

破解成功有什么用? 小白。。。

solly 发表于 2020-8-2 00:02

本帖最后由 solly 于 2020-8-2 02:00 编辑

qzhsjz 发表于 2020-8-1 21:38
有一些问题想请教:
您是怎么做到分析出分了好几个线程跑的逻辑?
直接把这里的eax置0,不会产生另一个 ...
没分析线程,不过可以看到全局变量 ds: 在不停变化,我还以为是定时器。
并且,界面UI的操作,一般是主线程的消息队列来处理的,正常情况不应该出现冲突。

我是通过strcpy()函数特征码找到函数,然后在 IDA 中查看对该函数的调用,稍微看看代码,就确定了这个button的事件函数或其子函数、或其启动的线程调用了这个strcpy(),下个断点,点按钮就断下来了,算运气好吧。因为要修改标签,肯定要调用内存拷贝函数。
特征码是:
74 1C 66 66 66 0F 1F 84 00 00 00 00 00
不要在 strcpy() 下断,调用次数太多。而调用的地方一般很有限,可在调用处一个个试,我刚好是一次试成功。主要是看到了下面这些函数前面的代码可疑:
.text:00000001400045CB loc_1400045CB:                        ; DATA XREF: .rdata:0000000140B67AC0o
.text:00000001400045CB               mov   eax, cs:dword_141040A50
.text:00000001400045D1               test    eax, eax
.text:00000001400045D3               jnz   loc_140004702
.text:00000001400045D9               mov   , 89E37834h
.text:00000001400045E0               mov   , 600172B6h
.text:00000001400045E7               mov   , 7834FF1Ah
.text:00000001400045EE               mov   , 593189E3h
.text:00000001400045F5               mov   , 8D25h
尝试把eax 修成0就看到了你要的效果了。

补充:
后来在IDA中看了那个全局变量的引用,发现是一个随机数,由另一线程调用 c++的 rand()生成的。你设置的关键点在这里吧:
00000001400036A0 | 48:83EC 28                     | sub rsp,28                              |
00000001400036A4 | E8 2F37AB00                  | call 大道至简.140AB6DD8                     |
00000001400036A9 | 44:8BC0                        | mov r8d,eax                           |
00000001400036AC | B8 56555555                  | mov eax,55555556                        |
00000001400036B1 | 41:F7E8                        | imul r8d                              |
00000001400036B4 | 8BCA                           | mov ecx,edx                           |
00000001400036B6 | C1E9 1F                        | shr ecx,1F                              |
00000001400036B9 | 03D1                           | add edx,ecx                           |
00000001400036BB | 8D0C52                         | lea ecx,qword ptr ds:      |
00000001400036BE | 44:3BC1                        | cmp r8d,ecx                           |
00000001400036C1 | 74 E1                        | je 大道至简.1400036A4                     |
00000001400036C3 | E8 1037AB00                  | call 大道至简.140AB6DD8                     | 这里改成 mov eax, 0
00000001400036C8 | 8905 82D30301                  | mov dword ptr ds:,eax      |
00000001400036CE | EB D4                        | jmp 大道至简.1400036A4                      |
只要把 置0就可以了。上面大概是一个死循环:
int var_141040A50 = 0; ///全局变量
void thread_proc() {
    while(true) {
      int a = rand();
      if(a != (a/3)*3) {
            var_141040A50 = rand();
      }
    }
}

solly 发表于 2020-8-1 21:22

关键点在这里:
00000001400045CB | 8B05 7FC40301          | mov eax,dword ptr ds:      |
00000001400045D1 | 85C0                   | test eax,eax                        |
00000001400045D3 | 0F85 29010000          | jne 大道至简.140004702                  |
eax == 0, 即不跳转,就显示破解失败。

没有细胞的人 发表于 2020-8-1 20:14

脑洞清奇,小白路过

liujiata 发表于 2020-8-1 20:42

好一个大道至简。可惜我是小白。

qzhsjz 发表于 2020-8-1 20:44

liujiata 发表于 2020-8-1 20:42
好一个大道至简。可惜我是小白。

小白可以点一下破解的,自动破解:lol

tardis2333 发表于 2020-8-1 20:59

学习了,感谢

qzhsjz 发表于 2020-8-1 21:38

solly 发表于 2020-8-1 21:22
关键点在这里:
00000001400045CB | 8B05 7FC40301          | mov eax,dword ptr...

有一些问题想请教:
您是怎么做到分析出分了好几个线程跑的逻辑?
直接把这里的eax置0,不会产生另一个线程和这个线程之间对于破解状态那个Label的竞争吗?

没有细胞的人 发表于 2020-8-1 23:35

求问
小白:我只想知道你是怎么让我的OD附加或者载入都不行的· - ·,这种是怎么解决的?
页: [1] 2 3
查看完整版本: 不用调试,我才是最简单的CrackMe:大道至简