方法一:代码绕过 首先打开软件,输入错误的账号密码,点击登录显示“登陆失败”,点击“显示桌面”和“隐藏桌面”都显示“没有登陆,不能使用此功能”
很明显,这个软件的提示信息,不再是弹窗和按钮,所以我们不能直接去代码里通过搜索定位,也无法通过F12暂停法找到调用代码,我们需要首先找到入口函数
第一步:使用工具e-bug找到入口函数:40165B
第二步:od载入程序
第三步:分析代码
随便输入账号密码,点击登录,单步F8,至返回eax=“登陆失败”,打个断点
继续找下面代码中能绕过这个call函数的代码
沿着箭头往上找箭头的头部
jmp指令是无条件判断,所以上面肯定有代码跳过了jmp,继续找附近绕过jmp的代码
往上找,发现是个条件判断跳转
我们使这个跳转失败,修改为jnz 方法二:找用户名密码分析:用户名密码分两部判断:判断用户名,判断密码;判断用户名-用户名错误-登陆失败判断用户名-用户名正确,判断密码-密码错误-登陆失败判断用户名-用户名正确,判断密码-密码正确-登陆成功判断用户名和判断密码调用的同一个函数:1.查找调用同一个函数的两行代码 那么在00401741前的地址是对用户名进行判断,先看一下前面的代码,发现有个je能直接跳转到下面的代码,那么这个je就是判断用户名是否正确,如果不正确直接跳转到登陆失败,看一下影响je的因素是cmp [local.3],0x0,在往上找影响 [local.3]的因素 要想使je不跳转,那么[local.3]要大于0,而影响 [local.3]的因素是00401704中的call 004015AF返回的结果标志位eax,返回结果eax=0-->sete al-->eax=1-->[local.3]=1-->cmp [local.3],0x0-->ZF=0-->je不跳转
所以必须要调用call 004015AF,且call 004015AF很可能是对用户名进行校验的关键函数,继续看上面的代码
发现有两个跳过call 004015AF的代码,对于je来说,要想不跳转。ecx要不等于0;对于jnz来说,要想不跳转==>ebx=ecx
所以要想不跳转ebx=ecx且不等于0;再网上看ebx和ecx的影响因素 看上面代码,要想ebx不等于零,必须要经过004016ef,那么je不跳转--->eax不等于0--->[local.2]不等于0;要想ecx不等于0,必须要经过004016de,那么je不跳转--->eax不等于0 ecx:eax=00471dc1--->[00471DC1+4]--->[00471DC5]=00000009=ECXebx:[local.2]!=0--->eax!=0--->[eax+4]!=0--->ebx!=0所以关键点在于[local.2],[local.2+4]地址所在的值要等于9,继续往上找[local.2]的影响因素 [local.2]=eax,eax是004016B8中经过函数call 00401A43返回的地址
(EBX=[local.1],[local.1]是0040168F的call 00401A49返回的地址,决定着004016C8是否跳转,不跳转会经过004016CB的call 00401A37)
随便输入一个用户名密码,看一下返回值(0040168F 004016B8 ) 0040168F返回的eax为我们输入的用户名,[local.1]的值也就是我们输入的用户名,即005DAD88 而004016B8传入参数为[local.1]即我们输入的用户名以及ebx=00401BF0,返回值为005C49C8,[local.2]也就等于005C49C8,看一下[005C49C8+4]=[005C49CC]的值
[005C49CC]的值为5,不等于9,所以我们输入的用户名不正确,直接跳转到登陆失败,现在的问题在于我们传入的参数值:[local.1]即我们输入的用户名以及ebx=00401BF0,对于ebx是一个立即数,是个不变常量,问题也就聚集到了[local.1],即我们输入的用户名,我们可以跟进004016B8中的函数看一下为什么返回005C49C8这个值
进入发现调用ebx函数call ebx,即:call 00401BF0,继续跟进:
---找到关键位置:传入参数eax(我们输入的字符串的长度),esi(我们输入字符串内容的地址),调用call 0040F240返回地址005C49C8也就是[local.2],所以[local.2+4]地址返回的是我们输入的用户名长度 所以正确用户名的长度应该是9,004016B8是对我们的用户名长度进行一个校验,长度不正确,就会直接跳到登陆失败
我们用admin1234再来测试一下
成功绕过跳转,来到了call 004015AF,所以call 004015AF确定就是对用户名进行校验的关键函数了,我们跟进查看
这里有一个比较,有个大跳转,猜想会是一个校验,那么看一下cl-->esi-->edx-->[esp+4]=我们输入的用户名,所以cl的值为61,也就是"admin1234"中第一个字母a的ascii码,很明显这里就是对我们输入用户名的每个字符进行比较了,[edi]也就是正确的用户名了,我们跟踪看一下[edi]
所以我们的用户名第一个字母也就是m,继续看下面代码不进行跳转,esi-1,edi-1,eax-1,这三个值,esi是取我们输入用户名的字符值,edi是正确用户名字符值,eax是我们用户名长度,用来循环判断的,我就不往下一步步写了,所以我们的用户名也就是mfc71.dll,同理分析出密码也就是mfc71u.dll
|