Crack小实验
- #include<stdio.h>
- #define PASSWORD "1234567"
- int verify_password (char *password)
- {
- int authenticated;
- authenticated = strcmp(password,PASSWORD); //strcmp比较两个字符,若相等返回0
- return authenticated;
- }
- int main()
- {
- int valid_flag = 0;
- char password[1024];
- while(1)
- {
- printf("please input password: ");
- scanf("%s",password);
- valid_flag = verify_password(password);
- if(valid_flag)
- {
- printf("incorrect password!\n\n");
- }
- else
- {
- printf("Congratulation! You have passed the verification!\n\n");
- break;
- }
- }
- return 0;
- }
复制代码
IDA静态反汇编
- 将编译的.exe用IDA打开,IDA就会把二进制文件翻译成质量上乘的反汇编代码
- 选中程序的分支点,也就是C代码的if语句,按空格键切换到汇编指令界面
- VA(虚拟内存地址)=RVA(相对虚拟地址) — Image Base(映射基址)
- 可以看到这条指令位于PE文件的.text节,VA:00401578
OllyDbg动态调式
- 注意32位或者64位的程序,要对应版本进行调式
- 将.exe文件用ollydbg打开,使用快捷键ctrl+g搜索由IDA分析出来的VA(虚拟内存地址)
- 选中这条指令按F2设置断点,成功后指令会被标记成不同颜色,按下F9让程序运行。进入程序输入错误密码,回车确认后,ollydbg会重新中断程序,收回控制权
- 密码验证函数的返回值会存在EAX寄存器中,if语句通过以下指令实现
- mov [esp+41Ch], eax //将eax寄存器的值放入[esp+41Ch]内存地址中,eax32位寄存器
- cmp dword ptr [esp+41Ch], 0 //将[esp+41Ch]内存地址的双字型数据和0进行比较
- je short loc_401588 //如若等于0跳转到密码确认流程,非0不跳转,执行密码重输流程
复制代码
- 如果我们将je这条指令修改位jnz(非0则跳转),那么整个程序的逻辑就会放过来,输入错误的密码会被确认,输入正确的密码反而要求1重新输入,双击这条指令,修改成jnz,点击"Assembly",确认修改,写入内存。会发现原来的机器指令74变为75,jump is taken提示跳转将要发生。
LordPE
- 将.exe用LordPE打开,查看PE文件的节信息,求出跳转指令在文件的偏移地址
- 用 相对虚拟内存地址 减 文件偏移地址 得到 节偏移地址
- 计算指令偏移地址等于之前得到相对偏移地址减去映射地址(exe的映射地址默认是0x00400000)再减去节偏移地址
- 文件偏移地址 = 相对偏移地址 - 装载基址 - 节偏移地址
- = 0x00401578 - 0x00400000 - (0x00001000 - 0x0000400)
- = 0x978
复制代码
- 计算得到这条指令在距离文件开始处的978h,用16进制编辑器进行修改
Hex Workshop
- 将.exe文件用hex wordshop打开,ctrl+g搜索978(16进制),将值74(JE)修改为75(JNZ),保存后重新运行可执行文件(可能会将.exe变成.bak文件,将.bak后缀修改为.exe运行即可)
- 运行结果如下,当输入正确密码"1234567"后,反而会被提示错误
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |