CrackMe 1

简介

该Crack Me中有3个反调试,其根据反调试的检测,结果生成不同的KEY。然后利用生成的KEY与密码进行异或,再拿异或后的结果进行比较。只有检测到没有被调试时,该KEY的值才能与密码异或出的结果,才能比较成功。

反调试

将Crack Me拖入IDA中,查看其main函数,发现主要判断逻辑,如图:

1570522558612

NtGlobalFlags反调试

通过获取PEB中偏移为==0x68==的NTGlobalFlags标志位,来判断当前程序是否被调试,NTGlobalFlags标志位,默认情况下该值为0,如果在调试中会被设置为一个特定的值(0x70),并根据检测结果设置不同的==KEY==值,如图:

1570522583999

NtQueryInformationProcess反调试

该Crack Me通过函数NtQueryInformationProcess,来检测是否被调试。

其中通过函数NtQueryInformationProcess,进行了3次查询,分别为:

  • 检测参数==ProcessDebugPort(0x7)==,函数返回调试端口,当调试端口dwDebugPort不为0时,说明当前程序正在被调试。
  • 检测参数==ProcessDebugObjecthandle(0x1E)==,函数返回调试对象句柄,当句柄hDebugObject不为0时,说明当前程序正在被调试。
  • 检测参数==Debug Flag(0x1F)==,函数返回调试标志,当标志bDebugFlag为0,则处于调试状态;若为1,则处于非调试状态。

根据检测结果来生成不同的==KEY==,最终实现干扰password的比较,如图:

1570521508893

NtQueryObject反调试

该Crack Me通过函数NtQueryObject,来检测当前进程是否被调试。

当一个调试活动开始时,一个==debug object==便会被创建,可通过函数NtQueryObject查找该Object,从而来判断当前程序是否正在被调试,然后根据检测的结果,生成不同的密钥==KEY==,最终实现干扰password的比较,如图:

1570511183616

根据两种反调试函数的检测结果,来生成后面对比密码时用到的==KEY==,如图:

1570511738666

获取正确密码

首先,可以通过IDA或OD,知道密码一共有==20位==,如图:

1570511792991

然后结合IDA,通过OD去调试该CrackMe,发现会将输入的密码的每一位与之前生产的==KEY==进行异或运算,然后将运算结果与地址==true_PW_403250==中存储的数据进行比较,当完全一致时,便能验证密码是正确的。如图:

1570512289226

地址==true_PW_403250==中存储的数据,如图:

1570512332320

因为是将密码Password与密钥==KEY==进行异或后得到地址==true_PW_403250==中的值。

计算正确密码

  • 要想获得正确密码:就需要将地址==true_PW_403250==中的值与密钥==KEY==进行异或,就能得到原本正确的Password

  • 若命中反调试函数,==KEY==的值会被修改。因此这里用strongOD来反反调试,获取到正确的==KEY==值为37。

  • 然后经过计算,便能正确密码。

==正确密码为==:N1ha0bangbangya~^_^~

得到的正确结果,如图:

1570512628384