找回密码
 立即注册
首页 业界区 业界 0day安全-part1-chapt1-crack_me

0day安全-part1-chapt1-crack_me

腥狩频 2025-6-20 19:55:06
一、实验目标


  • 修改crack_me.exe文件源代码,实现“即使输入错误密码,也将通过验证”目标【软件爆破】
二、实验计划步骤


  • 使用IDA工具完成如下任务

    • 利用IDA打开crack_me.exe文件
    • 定位main函数中条件判断并跳转指令

  • 依据指令虚拟地址及文件加载地址计算指令在文件中的偏移地址
  • 使用动态调试软件动态观察跳转分支逻辑并进行动态修改测试
  • 利用二进制相关软件修改判断条件的指令码,使其完成“密码不相等时判定正确”任务,达到输入错误密码反而成功验证的目的
三、实验记录

3.1  IDA分析


  • 定位条件判断跳转语句




  • 获取jz指令虚拟地址:.text:00000001400014E8

    • 注意:jz(Jump if Zero)和 je(Jump if Equal)​​本质上是同一条指令的两种不同写法​​,功能完全相同

3.2  x64dbg动态调试


  • 使用x64dbg打开crack_me.exe文件
  • 定位je判断跳转语句

    • 注意:由于EXE文件加载时采用了ASLR(Address Space Layout Randomization地址空间布局随机化)技术,因此无法通过直接搜索程序地址定位目标je指令


  • 将je指令修改为jne

    • 原代码



    • 修改后代码(调试工具自动反汇编,显示jne指令)



    • 通过命令行终端完成修改后的动态测试

3.3  LordPE查看PE文件segment信息


  • jz判断跳转语句的虚拟地址:.text:00000001400014E8
  • 区段表



  • 装载基址:0x0000000140000000



  • 计算指令在文件中的偏移地址【重点

    • 确定RVA(Relative Virtual Address相对虚拟地址)

      • RVA = VA(指令虚拟地址) - ImageBase(可执行映像文件的加载基址) = 0x00000001400014E8 - 0000000140000000 = 0x14E8

    • 确定数据所属段(Section)

      • .text

    • 计算指令的文件偏移FOA(File Offset Address文件偏移地址)

      • FOA = .text.PointerToRawData(段在文件中的起始地址) + (RVA - .text.VirtualOffset) = .text.Roffset(LordPE查看) + (RVA - .text.VirtualOffset) = 0x600 + 0x14E8 - 0x1000 = 0xAE8


3.4  UltraEdit修改EXE二进制文件,完成文件判断逻辑修改


  • 使用CTRL + G,输入待查找文件偏移0xAE8
  • 定位待修改字节



  • 将jz指令码74修改为jnz指令码75,保存文件,完成软件爆破
四、实验成果


  • 验证程序

    • 理论正确密码



    • 输入正确密码后的运行结果



    • 输入错误密码后的运行结果




五、实验总结

5.1  PE文件格式


  • 正确清晰地掌握PE文件格式,对Windows下的逆向工程至关重要

    • 拓展:Linux下的ELF文件也需重点掌握,两者同宗同源

5.2  使用工具


  • IDA、x64dbg、UltraEdit、010 Editor
六、知识拓展

6.1  汇编语法

6.1.1  关键字


  • ptr关键字的作用

    • 作用

      • 明确操作的数据长度​

    • 示例




6.1.2  普通指令


  • lea

    • 结构:LEA 寄存器, 内存操作数
    • 功能:计算一个内存地址,并将该地址存储到指定的寄存器中

6.1.3  跳转相关指令


  • test

    • 结构:test eax, eax
    • 功能:对两个操作数进行按位逻辑与操作,操作结果影响标志位,不影响寄存器中存储值

      • 影响ZF

        • 如果操作结果为0:ZF=1
        • 如果操作结果为1:ZF=0

      • 影响SF

        • 如果操作结果符号位为1:SF=1
        • 反之:SF=0

      • 影响PF

        • PF位用于指示结果中1的个数的奇偶性



  • cmp

    • 结构:cmp [rbp+3B0h+var_4], 0
    • 功能:比较两值,结果影响标志位,包括溢出标志(OF)、符号标志(SF)、零标志(ZF)、进位标志(CF)、辅助进位标志(AF)和奇偶标志(PF)

      • 影响ZF

        • 相等:ZF为1
        • 不等:ZF为0



  • jmp

    • 结构:jmp [目标地址]
    • 功能:无条件跳转指令

  • jz

    • 结构:jz [目标地址]
    • 功能:

      • ZF=1:跳转到目标地址
      • ZF=0:不跳转

    • 类似

      • jnz:当ZF为0时跳转
      • je:jz(Jump if Zero)和 je(Jump if Equal)​​本质上是同一条指令的两种不同写法​​,功能完全相同,均根据零标志位(ZF)决定是否跳转


6.2  C语言语法

6.2.1  函数语法


  • strcmp()

    • 语法:int strcmp(const char *str1, const char *str2)
    • 功能:比较 str1 所指向的字符串和 str2 所指向的字符串
    • 返回值:

      • 如果返回值小于 0,则表示 str1 小于 str2
      • 如果返回值大于 0,则表示 str1 大于 str2
      • 如果返回值等于 0,则表示 str1 等于 str2


七、源代码
  1. /*****************************************************************************      To be the apostrophe which changed "Impossible" into "I'm possible"!                POC code of chapter 3.7 in book "Vulnerability Exploit and Analysis Technique" file name        : crack_me.cauthor                : failwest  date                : 2006.9.20description        : used as a simple demo to show how to crack a PE file   Noticed                : should be complied with VC6.0 and build into release version  version                : 1.0E-mail                : failwest@gmail.com                        Only for educational purposes    enjoy the fun from exploiting :)******************************************************************************/#include #include #define PASSWORD "1234567"int verify_password (char *password){        int authenticated;        authenticated=strcmp(password,PASSWORD);        return authenticated;}void 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");                        break;                }        }}
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册