原文链接:http://user.qzone.qq.com/386520874/blog/1389369892
=======================================================================================================
---------------过客
很久很久以前,看到同事在用simcap.exe这个软件,但是只是一个Demo版,老是觉得人家老外写的算法牛X上天了,不愿意自己开发算法,年关将至,哥也不那么忙了,就花了点时间把这个软件给爆破了。
这个软件的官网是 http://www.umetrics.com/ ,可以去下载,但要注册加monney,看样子是瑞典人在1987年(那时候真不知道我在哪里游荡)就开始工作了,那时候微软的MFC小组应该还没成立,打开这个软件后,你会发现里面的菜单多的很,真是目不暇接啊,反正我是不管那么多的,我的目的只是破解,而不是使用。就像玩CS一样,你得知道地图的哪个地方可以蹲坑,哪个地方路过就掉血。破解也一样,得先跑一遍软件,知道大概多少步可以到达最后的窗口。闲话少扯,正式开始,爆破开始之前你得先准备一个无比牛X的ollyDbg,这是一个工作在Ring3级的远古神器(向开发它的人致以崇高的敬意)。
=======================================================================================================
simcap.exe这个软件有以下4个地方需要爆破:
1. 免费试用时间只有1个月
2. 右键菜单“Save Plot As ...”被禁用
3. 右键菜单“Save List As ...”或者 “Copy Ctrl+C” 被禁用
4. 背景图片中含有”Demo”字样水印版权信息
========= 1. 修改时间 ==========
先来说说怎么将只能免费使用1个月的时间修改成我们想要的时间。
首先得找到设置时间限制的代码,首先用 ollydbg 打开 simcap.exe ,先不要用附加方式打开,因为一般软件都是在最开始检测注册时间,注册时间未超过 1 个月的话,就正常启动,否则就弹出一个叫你掏腰包的对话框,因为我是在 2013.12.23 号安装的这个软件,要到 2014.1.23 才过期,而现在还早着捏,有的高手是先找到那个超时的对话框,然后根据对话框的字符串用 odb 右键菜单的“搜索 --> 所有参考字符串”反向查找某个字符串在整个 exe 里面的引用,在所有参考引用处一个一个的下断,理论上来说,这是正确的破解思路,但是我第一次用这个软件,并且还没满 1 个月,难道要让我等到 1 个月过后,先观察这厮的反应,再开始爆破吗,别这么笨蛋好不好,那条判断超时的语句一定就在 simcap.exe 里面,这点一定要坚信,好了,废话不多说,先看 odb 加载后的图,图中最左边黑色那一行是整个exe的入口点,
地址 HEX 数据 指令
0058C664 E8 0D040000 call simcap.0058CA76
第一列0058C664是程序入口地址
第二列E8 0D040000是程序的一条二进制源代码,共5个字节
第三列call simcap.0058CA76是上面5个字节对应的汇编指令,这条指令的意思是说让CPU的EIP寄存器跳到地址为0x0058CA76的地方,这实际上就是C语言的函数调用,这条call指令调用的函数是没有参数的,怎么判断一个函数有木有参数呢,很简单,编译器会规定参数都必须存在于栈中(堆中不知行不行),一个参数入栈,一般都是push指令,可能mov指令也可以模仿一下push指令,唉,不扯这么远了。到达上面的画面后,如果你什么断点都没设,按一下F9后,先出现下面
注意图中的”January 23, ”,其实是” January 23, 2014”,后面这个2014没输出来,可能是该软件的一个失误吧,这句话的意思就是说,你最多能用到2014.1.23,然后就玩完,请注意,这是一个很重要的信息,先拿笔记下来,然后接着在按一下F9,出现以下画面,
很明显我们已经错过检查时间的代码段,肿么办,我的办法关掉,重来,然后是不断的按F8(注意不是F9),不断的观察odb的4个窗口的变化,这个过程是很无聊的,我按了半天,直到遇到了下图,
00587086 |. 68 AC316000 push offset simcap.006031AC ; /Arg1 = ASCII"TimeKey.txt"
居然看到了time字样,哈哈,那个兴奋啊,现在想急切的知道这个"TimeKey.txt"住在哪里,继续按F8,直到下面的地方停住(最好慢慢按,否则会错过什么的哦),
====================================================================
00587E4A |. 8D4D E8 lea ecx,[ebp-18] ;|"C:\Documents and Settings\All Users\ApplicationData\Umetrics\SIMCA-P\11.5 Demo\TimeKey.txt"
00587E4D |. FF15 3CB25C00 call dword ptrds:[<&MFC80.#876>] ; |
00587E53 |. 50 push eax ; |Arg1= ASCII "C:\Documents and Settings\All Users\ApplicationData\Umetrics\SIMCA-P\11.5 Demo\TimeKey.txt"
00587E54 |. 8D8D 1CFFFFFF leaecx,[ebp-0E4] ; |
00587E5A |. FF15 D4BA5C00 call dword ptrds:[<&MSVCP80.?open@?$basic_fstr ;\MSVCP80.?open@?$basic_fstream@DU?$char_traits@D@std@@@std@@QAEXPBDHH@Z
00587E60 |. 8B85 1CFFFFFF mov eax,dwordptr ss:[ebp-0E4]
00587E66 |. 8B48 04 mov ecx,dword ptr ds:[eax+4]
00587E69 |. F6840D 24FFFF test byte ptrss:[ecx+ebp-0DC],06
00587E71 |.^ 75 85 jne shortsimcap.00587DF8
00587E73 |. 68 C8000000 push 0C8 ; /Arg2= 0C8
00587E78 |. 8D55 00 lea edx,[ebp] ; |
00587E7B |. 52 push edx ; |Arg1=> offset LOCAL.51
00587E7C |. 8D8D 1CFFFFFF leaecx,[ebp-0E4] ; |
00587E82 |. FF15 D8BA5C00 call dword ptr ds:[<&MSVCP80.?getline@?$basic_i ;\MSVCP80.?getline@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@PADH@Z
00587E88 |. 8D45 00 lea eax,[ebp]
00587E8B |. 50 push eax ; /Arg1=> offset LOCAL.51
00587E8C |. 8D4DE4 lea ecx,[ebp-1C] ; |
00587E8F |. FF15 A8B25C00 call dword ptrds:[<&MFC80.#784>] ; \MFC80.781F42AE
00587E95 |. 8D56 5C lea edx,[esi+5C]
00587E98 |. 51 push ecx ; /Arg2
00587E99 |. 8BCC mov ecx,esp ; |
00587E9B |. 8965 B8 mov dword ptr ss:[ebp-48],esp ; |
00587E9E |. 52 push edx ; |/Arg1
00587E9F |. FF15 A4B25C00 call dword ptrds:[<&MFC80.#297>] ; |\MFC80.781F3E65
00587EA5 |. C645 FC 05 mov byte ptr ss:[ebp-4],5 ; |
00587EA9 |. 8D45 E4 lea eax,[ebp-1C] ; |
00587EAC |. 50 push eax ; |Arg1=> offset LOCAL.58
00587EAD |. C645 FC 04 mov byte ptr ss:[ebp-4],4 ; |
00587EB1 |. 8BCE mov ecx,esi ; |
00587EB3 |. E878EBFFFF call simcap.00586A30 ; \simcap.00586A30,解码时间TimeKey.txt
00587EB8 |. 8D8D 1CFFFFFF leaecx,[ebp-0E4]
00587EBE |. FF15 DCBA5C00 call dword ptrds:[<&MSVCP80.?close@?$basic_fst ;[MSVCP80.?close@?$basic_fstream@DU?$char_traits@D@std@@@std@@QAEXXZ
====================================================================
很明显答案就在"C:\Documents and Settings\All Users\ApplicationData\Umetrics\SIMCA-P\11.5 Demo\TimeKey.txt"里面,打开看看先,里面是如下内容,
你能读懂吗,反正我是一开始没读懂,不过很显然的是这一定跟时间有关,到底什么关捏,继续按F8,然后在00587EB3停住,然后按F7,进入到被调用的函数入口处,然后按F8单步运行到下图处:
注意到ECX寄存器的变化了吗,哈哈,原先的“,.%*%(.$*$”现在变成了“13%*%(.$*$”,当你按F8运行到00586AE4,就跳出了这个循环,这个循环了10次,也就是那个字符串的长度,此时ECX的值变成了0A75DF40 这是一个字符串地址指针,内容为”1387853979”,很显然循环里面就是对每个字符做了一次xor(异或)运算(汗!这就算是加密了?太低端了吧),一路往下F8,到下面代码处:
00587FCF |. FF15 10BD5C00 call dword ptr ds:[<&MSVCR80._time64>] ; \MSVCR80._time64
00587FD5 |. 83C4 04 add esp,4
00587FD8 |. 8945 BC mov dword ptr ss:[ebp-44],eax
…………………
0058800C |. 6A 00 push 0 ;/Arg3 = 0
0058800E |. 3B4D BC cmp ecx,dword ptrss:[ebp-44] ; |将注册时间(2013-12-24 10:59:39)与当前时间(2014-01-07 10:39:14)进行比较
CPU Disasm
地址 HEX 数据 指令 注释
00588011 |. /7E 64 jle shortsimcap.00588077 ; |
00588013 |. |6A 10 push 10 ;|Arg2 = 10
00588015 |. |68 50326000 push offsetsimcap.00603250 ;|Arg1 = ASCII "Time warp detected!" //哥英语不太好,没法翻译这一句
0058801A |. |E8 07320000 call<jmp.&MFC80.#1123> ; \MFC80.78239E6C, AfxMessageBox(charconst *,unsigned int,unsigned int)
注意上面调用了_time64(…),即获得电脑的当前时间,当然你每次运行该软件之前,把你的电脑时间设置到注册的第二天,然后运行,然后再把电脑时间改回来,哈哈,笨蛋才用的笨方法。
……………..
CPU Disasm
地址 HEX 数据 指令 注释
00588077 |> \6A 00 push 0 ; |Arg3 = 0
00588079 |. 6A 00 push 0 ;|Arg2 = 0
0058807B |. 50 push eax ; |Arg1
0058807C |. 8D4D AC lea ecx,[ebp-54] ; |
0058807F |. E8 5CEBFFFF call simcap.00586BE0 ; \simcap.00586BE0,计算时间?很奇怪
00588084 |. 8B08 mov ecx,dword ptr ds:[eax]
00588086 |. 8B40 04 mov eax,dword ptr ds:[eax+4]
00588089 |. 014D DC add dword ptr ss:[ebp-24],ecx ; 0x52B8F89B + 0x00278D00 限时1个月,这个地方非常重要
继续按F8到下面处:
CPU Disasm
地址 HEX 数据 指令 注释
004128E8 |. 8B4424 40 mov eax,dword ptr ss:[esp+40] ; |
004128EC |. 52 push edx ; |Arg2
004128ED |. 50 push eax ;|Arg1, eax=0x7DE = 2014
004128EE |. 8D4C24 34 lea ecx,[esp+34] ; |
004128F2 |. E8 39D3FFFF call simcap.0040FC30 ; \simcap.0040FC30
004128F7 |. 8B4C24 1C mov ecx,dword ptr ss:[esp+1C]
004128FB |. 8B5424 18 mov edx,dword ptr ss:[esp+18]
004128FF |. 51 push ecx ;/Arg2, 0
00412900 |. 52 push edx ;|Arg1, edx=0x52E13C7F; // Thursday,January 23, 2014
00412901 |. 8D4C24 28 lea ecx,[esp+28] ;|ecx=[0x0013F6FC]=0x52CA651B // Monday, January 06, 2014
00412905 |. E8 06D4FFFF call simcap.0040FD10 ; \simcap.0040FD10
0041290A |. 84C0 test al,al ; al=0表示未超时,否则超时
0041290C |. 0F84 BC000000 jesimcap.004129CE
好了,游览到此处,基本上是摸清这个软件的注册时间的运行机制了,下面到了篡改代码的时候了,上面从入口处跑了老远,肯定早就错过了设置1个月时间的相关代码了,肿么办,回头呗,顺着上面的路往回倒车,怎么倒,你该不会希望odb有这个逆天的功能吧,两个办法,一个是你每路过一个你觉得重要的地方,做个“哥到此一游”的标记,在odb里面就是F2键啦,然后顺着标记找往回找代码,另一种就是关掉,重头再来(看成败,人生豪迈,只不过是重头再来 ),这一次就慢慢的按F8(你够聪明的话就按F9咯),直到遇到下面的代码
004127D9 |. FF15 5CE55C00 call dword ptrds:[<&SIMCAutlwin.?SetRegistryLo ;[SIMCAutlwin.?SetRegistryLocation@UmApp@@QAEXXZ
004127DF |. 6A1E push 1E ; /Arg1 = 1E ,很不起眼的1E哟,它就是十进制的30啊,是30天啊,找你找得好辛苦-_-!!!
004127E1 |. 8D8C24 800500 leaecx,[esp+580] ; |
004127E8 |. E8 03471700 call simcap.00586EF0 ; \simcap.00586EF0
找到这儿过后,也许猴急的你,马上把”6A 1E”改成”6A FE”,你或许天真的以为FE就是254天啊,我可以多用7个月了,等你保存存后,再运行simcap.exe,你会很后悔的,摆在你面前的是以下画面:
这下好了,人家说你只能用到2013.12.22,晕了吧,既然不对再改呗,当你改成”6A 7F”的时候,就ok了,它会告诉你,你可以用到2014.4.30号,爽吧,嚯嚯嚯,出现这个情况的原因很简单,就是7F和80的区别,即int和unsiged int的区别,FF就是-1啊,当然是23-1=22日啊。
也许你觉得多免费使用4个月好得不得了,但是我是想用100年的哦,在寒冷的瑞典,当地的人们是这样将30天换算成秒的,30*24*60*60,在遥远的东方人们酱紫换算的127*127*127*127,^_^反正我可以多用8年了。
有代码为证:
CPU Disasm
地址 HEX 数据 指令 注释
00586BE0 /$ 8B4424 04 mov eax,dword ptr ss:[esp+4] ; 真正计算时间限制的代码(arg1=0x1E=30天)
00586BE4 |. 56 push esi
00586BE5 |. 57 push edi
00586BE6 |. 6A 00 push 0 ;/Arg4 = 0
00586BE8 |. 99 cdq ; |
00586BE9 |. 6A18 push 18 ;|Arg3 = 18,0x18=24小时
00586BEB |. 52 push edx ; |Arg2
00586BEC |. 50 push eax ; |Arg1=> [ARG.1]
00586BED |. 8BF1 mov esi,ecx ; |
00586BEF |. E8 0C570000 call simcap.0058C300 ; \simcap.0058C300
…….
00586C01 |. 6A3C push 3C ;|Arg3 = 3C, 0x3C=60分钟
…….
00586C19 |. 6A3C push 3C ;|Arg3 = 3C, 0x3C=60秒钟
========= 2. 修改右键菜单“Copy Ctrl+C” ==========
上面时间已经搞定了,下面说说怎么修改右键菜单“Copy Ctrl+C”,因为这个软件是用MFC开发的(当你在odb中看到call dword ptr ds:[<&MFC80.#876>]这种调用就一切明白了,什么?还不明白,赶快对着墙壁立正),对了,忘了说这个软件是没有加壳的,不用费那劲去脱壳,MFC里面的右键菜单,一般会调用TrackPopupMenu,第一件事要做的就是,拦截WM_RBUTTONUP消息,怎么拦截捏,在odb里面,你得先找到每个窗口的入口地址,按”Alt+W”就会弹出被调试软件已经打开的所有窗口列表,跟Spy++类似的功能,然后找到你要找的那个窗口的句柄,右键选择“跟随ClassProc”,然后odb就会跳到WinProc(…)程序入口处,但有的窗口没有重载这个函数,那就会跳到user32.dll的领空,
77D2C17E /$ 6A 14 push 14 ;LRESULT USER32.DefWindowProcA(guessed hWnd,Msg,wParam,lParam)
这是默认的窗口过程函数,遇到它很多次后,你会觉得这个函数除了浪费时间一点意思都莫得,好,废话不多说,我现在要爆破下面图中的”Plot/List Plot [M1]”窗口的右键菜单的’Copy Ctrl+C”功能,默认情况下,这一菜单项是变灰的,由于菜单很难截图,就没放菜单的图片了,下面第一步要做的是拦截WM_RBUTTONUP,怎么拦截捏,在odb中设条件断点,最好是在MFC80.dll领空,消息分发处设,如下:
782027A0 55 push ebp ;CWnd:: OnWndMsg(UINT message,WPARAM wParam,LPARAM lParam,LRESULT* pResult);
设置条件断点为: [esp+4]==205 (注意:WM_RBUTTONUP = 0x0205)
然后一直按F8跟随吧,
反正我是找了2天,才找着真正的消息搬运工:
BOOL CCmdTarget::OnCmdMsg(UINT nID, intnCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
如下图:
而我又已经知道了"Copy Ctrl+C"对应的资源id号为0xE122,至于怎么知道的,可以用PEView.exe直接找到exe的全部资源信息,当然pexplorer.exe更强大,在MFC80领空0x7822AFDB处下条件断点:[ESP+4]==E122,至于为什么这样下就不多说了,最后你会发现下面寻她千百度的画面:
这个0x006927D0地址处对应的是结构
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; //Windows消息ID,对应图中0x00000111即WM_COMMAND
UINT nCode; //对应图中0xFFFFFFFF=-1=CN_UPDATE_COMMAND_UI
UINT nID; //对应图中0x0000E122即” CopyCtrl+C”的资源id
UINT nLastID; //对应图中0x0000E122
UINT nSig; //对应图中0x00000040
AFX_PMSG pfn; //对应图中0x004668E0,这个地址非常重要
};
接下来就跳转到simcap.exe领空的0x004668E0处,然后就可以干坏事了,呵呵
修改后就可以使用拷贝这个功能了,太帅了
========= 3. 修改右键菜单“Save List As ...”“Save Plot As ...” ==========
和修改“Copy Ctrl+C”一样的道理,修改这两项,不过道路要曲折得多了,全靠你的耐心去发现所有的AFX_MSGMAP_ENTRY这样的结构,不仅仅是在simcap.exe这个文件里面找这个结构喔,还得到可能调用的40个dll文件里面搜索这个结构啊,这个过程是漫长的并且无聊的。不过一份付出就一份收获是万万没错的。反正我是在茫茫的40个dll找到了所有涉及到响应“Save List As ...”“Save Plot As ...”这两个ID的AFX_MSGMAP_ENTRY
========= 4. 修改图片中”Demo”字样水印 ==========
其实修改图片中”Demo”字样水印是最难的,一开始我并不知道有这么难,一开我将所有的dll导出的函数中凡是含有”Draw”,”Plot”关键字样的函数全部下断,结果一无所获,3天就这么被浪费了,后来改变了策略,考虑到画图一定会调用BitBlt,TextOutA,LoadBitmapA等API,我就专门在这些地方蹲点,结果除了一遍遍的观摩这些API,全是在崩溃的边缘徘徊,木有办法,只有使用最后的绝招,狂按F8,最后umch2d.dll这个魂淡露出了圆型,
奶奶个熊,原来是用StretchDIBits(…)这么变态的函数来画图,哥以前从未用过这个API,并且塔凉的那张图片居然不是以明码方式存储的图片,更BT的是它是被放在"C:\Documents and Settings\dell\ApplicationData\Umetrics\SIMCA-P\11.5 Demo\dd.dll"这个塔儿,尼玛更更BT的是,这个dd.dll看起来是个dll,实际上是个锤子,而那张含”Demo”字样图片的数据就存在这个文件里面,我勒个擦,真想说张话,只要让哥找到你丫的藏身之处,那你就乖乖的占到墙角吧,然后顺藤摸瓜把umch2d.dll(另一个umch3d.dll里面居然是用OpenGL画的图,也被我发现了,哈哈)里面对应的代码改掉,就一下子天变得那么蓝,乌云变得那么白,今晚的月亮妹妹是多么的冻人啊,啦啦啦,啦啦啦,我是卖报的小行家,……… 收工回家
--------作者:过客
--------邮箱: 386520874@qq.com
-------- 时间: 2014.01.10 凌晨 于深圳盐田========================================================================
simcap.exe下载链接:http://pan.baidu.com/s/1AHq8Y