今天刚弄了个程序,界面如下,
很好奇它的计算方法是什么, 想来我也在看雪混了有一段日子了,试试看能不能用OD找到它的算法.直接用OD载入,程序停在了入口点,OD并没有提示说有壳,看来程序没有加壳处理.
用OD加载,发现它没有加壳,好了正合我意,拿出OD来调戏它,嘻嘻~~~
在OD的命令插件中输入bp GetDlgItemInt,F9运行程序,随便输入一个数字,在这里我输入的是9,点"计算"按钮,程序被断下,F2清除断点,Alt+F9返回程序的领空,好了现在我们已经在程序的计算流程里面了,按钮的处理过程从00401330开始到00401369结束,F8一步一步分析,我的分析过程如下:
00401330 . 56 push esi
00401331 . 6A 01 push 1 ; GetDlgItemInt的第三个参数
00401333 . 6A 00 push 0 ; GetDlgItemInt的第二个参数
00401335 . 8BF1 mov esi, ecx
00401337 . 68 E8030000 push 3E8 ; 控件ID
0040133C . E8 2F020000 call <jmp.&MFC42.#3095_CWnd::GetDlgItemInt> ; 获取输入框中的数值
00401341 . 8BC8 mov ecx, eax ; 返回值保存在EAX中,EAX赋值给ECX,EAX里面的值就是我刚才输入的9
00401343 . 33D2 xor edx, edx
00401345 . C1E1 08 shl ecx, 8 ; 左移8位,相当于乘于2的8次方
00401348 . 03C8 add ecx, eax ; 结果再加上原值
0040134A . 6A 01 push 1
0040134C . 8D048D FCFFFF>lea eax, dword ptr [ecx*4-4] ; 所得结果乘于4后再减去4,并把结果保存到EAX中
00401353 . 8BCE mov ecx, esi
00401355 . 85C0 test eax, eax ; 判断计算的结果是否为零
00401357 . 0F9CC2 setl dl
0040135A . 4A dec edx
0040135B . 23D0 and edx, eax ; 若结果为0则输出结果也为0
0040135D . 52 push edx ; 把计算结果保存到edx中,做为SetDlgItemInt的参数
0040135E . 68 E9030000 push 3E9 ; 控件ID
00401363 . E8 02020000 call <jmp.&MFC42.#5951_CWnd::SetDlgItemInt> ; 输出计算的结果
00401368 . 5E pop esi
00401369 . C3 retn
由以上结果可以总结出程序所使用的算法如下:
假设m为输入的数字
m=((m<<8)+m)*4-4;
因为左移8位,相当于乘于2的8次方(2的8次方等于256),所以也可以这样写:
m=(m*256+m)*4-4;
还记得小学学的乘法分配律吗?化简一下得:
m=m*1028-4;
就是这一行代码而已,很简单吧。有了它我们自己也可以写一个计算器了,呵呵~~~
下面我附上程序,大家有空就拿出来玩吧~~~~
这个程序是我自己写的,大家可以拿来随意修改.
------------------------------------------------------------------------------------------
下载 :
磁盘分区计算器.rar
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)