Hopper笔记-CrackMe系列
轻喷
简单记录 crackme 系列学习笔记,因为这些样例在m1(arm64)无法运行,所以记录的内容有些粗糙。
CrackMe01
- 视频: https://www.youtube.com/watch?v=yjvlNQNCm6w
- CrackMeAPP: https://reverse.put.as/wp-content/uploads/2010/05/MSJ20091.zip
找到关键函数validateSerial
查看伪代码:
validateSerial伪代码
Objective-C
/* @class Level1 */
-(char)validateSerial:(void *)serial forName:(void *)name {
name = name;
serial = serial;
if ([serial length] == 0x8) {
esi = 0x4;
ebx = 0x0;
eax = [name lossyCString];
edi = eax;
eax = strlen(eax);
ecx = 0x0;
name_length = eax;
while (name_length > ebx) {
eax = sign_extend_32(*(int8_t *)(edi + ebx));
ebx = ebx + 0x1;
eax = eax * esi;
esi = esi + 0x4;
ecx = ((eax << 0x4) - eax) + ecx + 0x29a;
var_20 = ecx - ((SAR(HIDWORD(0x68db8bad * ecx), 0xc)) - (SAR(ecx, 0x1f))) * 0x2710;
}
esi = 0x4;
ebx = 0x0;
result_1 = [NSString stringWithFormat:@"%i", var_20];
eax = strlen(edi);
ecx = 0x0;
var_2C = eax;
while (ebx < var_2C) {
eax = sign_extend_32(*(int8_t *)(edi + ebx));
ebx = ebx + 0x1;
eax = eax * esi;
esi = esi + 0x8;
ecx = ecx + eax + (eax + eax * 0x4) * 0x2 + 0x2d;
var_1C = ecx - ((SAR(HIDWORD(0x68db8bad * ecx), 0xc)) - (SAR(ecx, 0x1f))) * 0x2710;
}
result_2 = [NSString stringWithFormat:@"%i", var_1C];
eax = [serial substringWithRange:0x0];
esi = [serial substringWithRange:0x4];
if ([eax isEqual:result_1] != 0x0) {
eax = [esi isEqual:result_2];
edx = 0x1;
if (eax == 0x0) {
edx = 0x0;
}
}
else {
edx = 0x0;
}
}
else {
edx = 0x0;
}
eax = edx;
return eax;
}
如上取余那部分的伪代码相当难以理解的,ida这部分就处理的比hopper好,可以同时打开hopper和ida查看伪代码。
编写注册函数
Python
def main():
name = input("Name: ")
i = 0
s1, s2 = 0,0
r1, r2 = 0,0
while len(name) > i:
c = ord(name[i])
i+=1
t1 = c * (0x4 * i)
s1 += t1 * 15 + 0x29a
r1 = s1 % 10000
t2 = c * (0x8 * i - 0x4)
s2 += t2 * 11 + 0x2d
r2 = s2 % 10000
print("Serial: %d%d"%(r1,r2))
main()
# Name: cwm_studio
# Serial: 60009698
CrackMe02
- 视频: https://www.youtube.com/watch?v=aRpz577OWj0
- CrackMeAPP: https://reverse.put.as/wp-content/uploads/2010/05/MSJ20092.zip
反调试绕过
从入口函数找到 _main
方法,用 ptrace 实现的反调试,将这行 nop 掉即可:
笔记
- ptrace
在类 Unix 系统中,提供了一个系统调用 ptrace
用于实现断点调试和对进程进行跟踪和控制,而 PT_DENY_ATTACH
是 macOS
增加的一个 ptrace
选项,用于阻止 GDB 等调试器依附到某进程:
C
ptrace(PT_DENY_ATTACH, 0, 0, 0);
- 动态调试
po $eax
查看寄存器的值x $eax
查看寄存器中地址指向的值po (char *)$eax
查看寄存器地址指向字符串的值
CrackMe03
- 视频: https://www.youtube.com/watch?v=cxTgSWYJqnU
- CrackMeAPP: https://reverse.put.as/wp-content/uploads/2010/05/MSJ20093.zip
在 label 和 str 都找不到入口时,从 ui 界面(如声音、弹窗等)入手,动态调试查看 callback 栈。
最后更新:
2023-02-07