1. 观察程序,发现错误时输出Error
2. 猜测程序流程:
a) 使用printf输出提示字符串
b) 使用scanf获取用户输入的字符串
c) 检查输入字符串的正确性来选择输出正确字符或是错误字符串
3. 寻找突破口:
a) 字符串搜索找到提示正确或错误的字符串
发现并不能找到核心流程使用的字符串(”Error”)。发生这种情况,可能是由于字符串已经被加密,所以无法识别。
碰到这种情况,那么只能观察出其它的突破口了。
1. 如果代码比较简单, 能够猜测出核心流程的位置,那么可以直接到核心流程的位置去阅读反汇编进行分析,信息的收集
2. 如果代码比较复杂,不能够轻易猜测出核心流程的位置,那么只能找出其他步骤可能会有的突破口,比如字符串”%s”,可能就是步骤a或步骤b使用到的字符串。虽然这并不能够直接我们把带到核心的流程中,但是它和核心流程肯定存在千丝万缕的联系。
发现这里面的代码可能并没有明显的字符串和API,在这里下个断点,动态调试看看是否能够断到这里。
发现能够断下来,并接受输入,所以此函数应该就是sanf函数,[ebp-0x68]就是接受输入的缓冲区。这时,可以对这个函数打上一个标签。
继续粗略的单步,观察寄存器和内存,搜集更多的信息。
当执行到这一步的时候,发现了一个有用的信息:
打上标签后,可以看出大致的信息,首先,如果密码错误了,就会跑到这里,将提示信息的字符串解密,使用printf输出,然后又将字符串加密回去。
所以,Pggzg是Error经过加密的字符串。
找到了输出错误的地方,那么差不多就可以找到关键判断和关键跳了,关键判断和关键跳转可能是一系列的,因此,还需要进行一定的分析,但是静态分析可能并不能有效的分析出来。
因此需要结合动态调试。
下面是经过动态调试后得到的分析结果:
核心的比对代码:
因此可以看出, 处的字符串就是加密后的密码,而用于加密用户名的函数也能够进行解密,因此,可以通过分析加密的算法来解析出明文的密码,也可以通过更简单的方式来解析出: