首先,我们打开TraceMe分析程序,查看基本功能:
它的验证逻辑是这样的:
紧接着,我们使用OllyDbg加载这个程序并进行调试,当然了,在加载之前需要把断点设置在“WinMain”处。
请注意:32位的OD不能直接打开64位的程序,我找了一个32位的程序,参考其他博客也可以添加高级插件。
按下F9运行这个程序,可以看到已经开始进入running状态。
设置断点,Ctrl+G打开跟随表达式窗口,输入GetDlgItemTextA,这个函数属于USER32.DLL,点击OK后:
将当前地址设置为断点,一旦此函数被调用,OD就会进行中断。此时,在TraceMe中输入姓名和序列号,check之后,就可以看到行到断点处停止了。
Alt+F9走出GetDlgItemTextA函数后,可以看到:
查看微软提供的HLP文件,https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getdlgitemtexta,查看GetDlgItemText的参数:
进入TraceMe领空,ALT+B打开断点窗口,将刚才设置的断点禁止。
再在返回地址前一个地址设置断点,以便反复跟踪调试。
中断后的代码为:
再次运行一下TraceMe,进行调试。单步步过至004011CA处,发现
跟踪esp+4,查看字符窗口,出现了用户名:
接着开始看下面的内容:
如图可知判断了输入的用户名是否是空的,然后判断用户名长度是否小于5.
接着出现了下面:
两个lea分别传入了用户名和序列号.
步入下面的call调用,
可以看到正在计算序列号,再次回到领空后。接着我们找到了判断序列号正确与否的核心,即如下:
只要将这个跳转不执行,就可以继续下面的代码,显示正确了。将汇编指令改成nop即可:
继续F8步过,运行完毕后:
我很开森~
为了进一步把这个修改写入磁盘,选中修改代码,右键,Copy to executable->Selecetion,接着进行保存就好。
为了更好提升,我们转过头来看一下分析序列号的算法:
我们挨着来分析:
push ebp
mov ebb,[esp+c];这里将用户名cName指针从栈中传入给了ebp
push esi
push editors
;--------------------------------------------------------
;for(i=3,j=0;i<len;i++,j++)
mov edi,[esp+18]
mov ecx,00000003;设置i
xor esi,esi
xor eat,eax
cmp edi,ecx;i<len?
jle 00401379
push ebx
;if(j>7) j=0
/cmp eat,00000007;j>7吗
|jle 00401360
|xor eat,eax;j=0
;code+=((BYTE)name[I]*Table[j])
|xor edx,edx
|xor ebx,ebx
|mov dl,[ecx+ebp]
|mov bl,[eax+405030]
|imul edx,ebx
|add esi,edx;code+=edx
|inc ecx ;i++
|inc eax ;j++
|cmp ecx,edi;i<len?
\jl 00401359;如果小于则循环,计算下一位
pop ebx
;---------------------------------------------------------
;wsprints(name,TEXT("%ld"),code)
push psi
push 00405078
push ebb
call [0040409C]
mov eax,[esp+1C]
add esp,0000000C
push ebp
push eax
call [00404004]
neg eax
sbb eax,eax
pop edi
pop esi
inc eax
pop ebx
ret
TraceMe最后调用了lstrcmp函数来比较字符,如果相等返回0,如果不相等,返回1.
到这边,就已经分析完毕了。继续加油!