破解密码验证程序

程序:

#include "stdio.h"
#include "string.h"

#define PASSWORD "1234567"

int verify_password(char *password)
{
    int authenticated = 0;
    //strcmp:两字符串相等则返回0,不相等则返回1
    authenticated = strcmp(password, PASSWORD);

    return authenticated;
}

int main(void)
{
    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");
        }
        else
        {
            printf("Congratulation! You have passed the verification!\n");
            break;
        }
    }

    return 0;
}

工具:IDA Por、OllyDbg、LoadPE、UltraEdit、VS\VC++

在本次破解中,由源代码编译出来的.exe文件命名为 crack.exe

首先用 IDA 打开 crack.exe

在 IDA View-A 中找到 main 函数(默认情况下IDA会自动识别出main函数)
破解密码验证程序_第1张图片

然后 按空格键,出现如下界面
破解密码验证程序_第2张图片

从这里可以看到,程序并不是一开始就执行main函数的,而是有一些其他的前期准备工作。

我们双击 _main 然后IDA的图形界面会跳转到程序流程图
,找到如下流程
破解密码验证程序_第3张图片
我们可以看到,jz(jump if zero)指令下方有两个分支,符合C语言中if语句的效果,以此我们判断这条jz指令就是.c源文件中的if语句

单击选择 jz,然后按空格键,IDA会转到jz指令所在的汇编指令界面
破解密码验证程序_第4张图片
光标高亮的语句就是我们在图形界面中选中的引起程序分支的指令,可以看到这条指令位于PE文件的.text节,它在运行时的内存地址为VA:004010E5

接着打开 OllyDbg 进行动态调试来看看程序到底是如何分支的。
用OllyDbg打开crack.exe
破解密码验证程序_第5张图片
(其实如果现在就已经可以读取到正确密码了,注意那一行:ASCII “1234567”)

用快捷键Ctrl+G,直接跳转到VA:004010E5
这里写图片描述

选择这条指令,按F2设置断点,这时指令的地址会被标记为不同颜色。
按F9键让程序运行起来,这时控制权会回到程序,OllyDbg暂时挂起,在Console中随便输入一个错误的密码,回车确认后,控制权会被OllyDbg收回。
破解密码验证程序_第6张图片

密码验证函数verify_password()的返回值会被储存在EAX寄存器中,所以if语句是通过以下两条指令实现的

TEST EAX,EAX
JE [XXXXX]

也就是说当EAX中的值为0时,跳转将被执行,程序进入密码确认流程,否则跳转不执行,进入密码重输流程。

如果我们把JE修改为JNE(jump when not equal)那么输入错误密码将会被确认,输入正确密码反而要求重新输入;
或者将

TEST EAX,EAX

改为

XOR EAX,EAX

那么无论密码正确与否,都会得到确认。

双击 JE 指令,将其修改为 JNE ,单击Assemble按钮将其写入内存
破解密码验证程序_第7张图片

这时我们按F8单步执行,可以看到跳转被执行,输出了“Congratulation! You have passed the verification!”
破解密码验证程序_第8张图片

但这只是在内存中修改程序,我们还要进一步在PE文件中修改相应的字节。
用LoadPE打开crack.exe
破解密码验证程序_第9张图片
记下ImageBase(基址):00400000

查看区段
破解密码验证程序_第10张图片
由于jz指令位于PE文件的.text节,我们只需记下.text节的VOffset(文件虚拟地址):00001000和ROffset(文件物理址):00001000即可

根据VA与文件地址(FileOffset)的换算公式:
FileOffset = VA - ImageBase - VRk
VRk = VOffset - ROffset

可以计算出:
FileOffset
= VA - ImageBase - (VOffset - ROffset)
= 0x004010E5 - 0x00400000 - (0x00001000 - 0x00001000)
= 0x000010E5

也就是说,这条指令在PE文件中距离文件开始处0x000010E5字节的地方,用UltraEdit打开crack.exe文件
铵快捷键Ctrl+G,输入0x000010E5直接跳转到JE指令的机器代码处
破解密码验证程序_第11张图片
74即JE,我们将其改为75(JNE)
保存后重新运行程序,这时输入错误密码可以得到确认,输入正确密码"1234567"反而提示错误了。
破解密码验证程序_第12张图片

你可能感兴趣的:(#,C,/,C++)