• 标 题:关于防止同一程序多次运行的破解方法之补充篇 (3千字)
  • 作 者:liangs
  • 时 间:2001-10-28 14:12:34
  • 链 接:http://bbs.pediy.com

关于防止同一程序多次运行的破解方法之补充篇

                    by  liangs 


  上次写了一篇关于防止同一程序多次运行的破解方法,主要针对
使用FindWindowA函数的程序,具体可参见论坛精华Ⅲ。这次写一
篇针对使用CreateMutexA函数程序的破解方法,因为使用这个API
函数的程序实在是太多了!

  这次的目标是瑞星杀毒软件2002版v13.23,选中它的原因就是因
为它就是使用CreateMutexA函数来防止同时运行多个进程的。

  在破解前,大家可以在自己的机器上运行瑞星试试,当一个进程
运行后,再想运行另一个进程时就会发现什么反映都没有,程序只
是将刚才运行的第一个进程的程序窗口弹到前面。

  下面是我两次跟踪程序API的调用结果:

==========================================================================
★程序运行第一个进程的结果★

CreateMutexA(LPDATA:00000000,BOOL:00000000,LPSTR:0043A88C:"{F25D2D81-9FA5-11d4-BE4D-444553540001}")::0040DAB3
CreateMutexA'returns: 00000018

GetLastError()::0040DABF
GetLastError'returns: 00000000 //注意这个返回值

==========================================================================
★程序运行第二个进程的结果★

CreateMutexA(LPDATA:00000000,BOOL:00000000,LPSTR:0043A88C:"{F25D2D81-9FA5-11d4-BE4D-444553540001}")::0040DAB3
CreateMutexA'returns: 00000018

GetLastError()::0040DABF
GetLastError'returns: 000000B7 //哈哈,看到了吧这个返回值与上面不一样了

=========================================================================

由于瑞星是用VC6开发的,那么上面一段API语句我把它翻译成如下的VC代码:
当然瑞星程序里的这段代码肯定就是这么写的。

hMutex=CreateMutex(
        NULL,  //nosecurityattributes
        FALSE, //initiallynotowned
        "F25D2D81-9FA5-11d4-BE4D-444553540001" //命名Mutex的全局对象名,在所有进程都可以访问到
        );

if(hMutex==NULL||ERROR_ALREADY_EXISTS==::GetLastError())
{
  //程序第二次或以后运行时,会得到Mutex已经创建的错误
  AfxMessageBox("程序已经运行!"); //这句是我写的,瑞星就退出了,没有提示
  return FALSE;
}

=========================================================================

对应于上面VC代码的程序汇编代码如下:

* Possible StringData Ref from Data Obj ->"{F25D2D81-9FA5-11d4-BE4D-444553540001}"
                                  |
:0040DAA4 688CA84300              push 0043A88C
:0040DAA9 6A00                    push 00000000
:0040DAAB 6A00                    push 00000000

* Reference To: KERNEL32.CreateMutexA, Ord:003Fh
                                  |
:0040DAAD FF1550F14200            Call dword ptr [0042F150] //建立mutex对象
:0040DAB3 898504070000            mov dword ptr [ebp+00000704], eax

* Reference To: KERNEL32.GetLastError, Ord:011Ah
                                  |
:0040DAB9 FF15ACF14200            Call dword ptr [0042F1AC]
:0040DABF 3DB7000000              cmp eax, 000000B7 //对象已经存在,返回000000B7
:0040DAC4 0F85CB000000            jne 0040DB95 //这句当然是一定要使它跳转的

========================================================================

将0040DAC4处的代码0F85CB000000改为90E9CB000000,再运行程序试试,
呵呵,这回运行N个进程都没问题了吧。

一点补充:

  要使瑞星的多个进程同时能运行杀毒功能还需处理以下两个地方
0040D6E4处是CRC的检测,004132D7是检测是否有另一个进程正在
运行杀毒操作。这两处很容易搞定,这里就不多说了。

(1):0040D6E4 0F8594000000        jne 0040D77E //改为Jmp

(2):004132D7 0F859A000000        jne 00413377 //改为Jmp


修改后的优点:

  可同时运行N个进程,分别对N的硬盘同时进行杀毒,提高了N倍的效率,
经实际使用测试,呵呵,没发现不良影响。


申明:本文仅以技术交流为目的,转载请保持文章的完整性!


                                              2001/10/28