CrackMe 1
简介
该Crack Me中有3个反调试,其根据反调试的检测,结果生成不同的KEY。然后利用生成的KEY与密码进行异或,再拿异或后的结果进行比较。只有检测到没有被调试时,该KEY的值才能与密码异或出的结果,才能比较成功。
反调试
将Crack Me拖入IDA中,查看其main函数,发现主要判断逻辑,如图:
NtGlobalFlags
反调试
通过获取PEB中偏移为==0x68==的NTGlobalFlags
标志位,来判断当前程序是否被调试,NTGlobalFlags
标志位,默认情况下该值为0,如果在调试中会被设置为一个特定的值(0x70),并根据检测结果设置不同的==KEY==值,如图:
NtQueryInformationProcess
反调试
该Crack Me通过函数NtQueryInformationProcess
,来检测是否被调试。
其中通过函数NtQueryInformationProcess
,进行了3次查询,分别为:
- 检测参数==ProcessDebugPort(0x7)==,函数返回调试端口,当调试端口
dwDebugPort
不为0时,说明当前程序正在被调试。 - 检测参数==ProcessDebugObjecthandle(0x1E)==,函数返回调试对象句柄,当句柄
hDebugObject
不为0时,说明当前程序正在被调试。 - 检测参数==Debug Flag(0x1F)==,函数返回调试标志,当标志
bDebugFlag
为0,则处于调试状态;若为1,则处于非调试状态。
根据检测结果来生成不同的==KEY==,最终实现干扰password的比较,如图:
NtQueryObject
反调试
该Crack Me通过函数NtQueryObject
,来检测当前进程是否被调试。
当一个调试活动开始时,一个==debug object==便会被创建,可通过函数NtQueryObject
查找该Object,从而来判断当前程序是否正在被调试,然后根据检测的结果,生成不同的密钥==KEY==,最终实现干扰password的比较,如图:
根据两种反调试函数的检测结果,来生成后面对比密码时用到的==KEY==,如图:
获取正确密码
首先,可以通过IDA或OD,知道密码一共有==20位==,如图:
然后结合IDA,通过OD去调试该CrackMe
,发现会将输入的密码的每一位与之前生产的==KEY==进行异或运算
,然后将运算结果与地址==true_PW_403250==中存储的数据进行比较,当完全一致时,便能验证密码是正确的。如图:
地址==true_PW_403250==中存储的数据,如图:
因为是将密码Password
与密钥==KEY==进行异或
后得到地址==true_PW_403250==中的值。
计算正确密码
要想获得正确密码:就需要将地址==true_PW_403250==中的值与密钥==KEY==进行异或,就能得到原本正确的
Password
。若命中反调试函数,==KEY==的值会被修改。因此这里用
strongOD
来反反调试,获取到正确的==KEY==值为37。然后经过计算,便能正确密码。
==正确密码为==:N1ha0bangbangya~^_^~
得到的正确结果,如图: