winrar过时了总是弹窗,超恶心,今天也不想去上课,算了ri掉rar吧。 ios
cmp eax,28h //用eax存的天数和28h(等于40天)比较 判断是否过时 //二进制值为 0x83,0xf8,0x28
咱们将上面的指令替换为: windows
汇编指令 对应二进制值 cmp eax,eax // 0x3b, 0xc0 nop // 0x90这样eax和本身比较,就不知道是否过时了。由于cmp eax,eax只有2字节 因此后面又加上nop指令,这样写入文件时能够直接覆盖数据,而不用考虑移动其余数据。
#include <stdio.h> #include <windows.h> #include <string> #include <ShlObj.h> #include <iostream> #include <fstream> using namespace std; string ChoseFolder(){ char szPathName[MAX_PATH]; BROWSEINFO bInfo={0}; bInfo.hwndOwner=GetForegroundWindow();//父窗口 bInfo.lpszTitle=TEXT("请选择winrar安装路径"); bInfo.ulFlags=1; LPITEMIDLIST lpDlist; lpDlist=SHBrowseForFolder(&bInfo); if (lpDlist!=NULL){//单击了肯定按钮 SHGetPathFromIDList(lpDlist,szPathName); return string(szPathName); }else{ return string(); } } int backups( const string filename){ string sfilename(filename+".beifen"); const char *pfilename = sfilename.c_str(); if( CopyFile(filename.c_str(),pfilename,false) != true ){ return -1;//CopyFile error } return 0;//copy success } int rollback(const string filename){ string sfilename(filename+".beifen"); const char *pfilename = sfilename.c_str(); if( CopyFile(pfilename,filename.c_str(),false) != 0 ){ return -1;//CopyFile error } return 0;//copy success } int check(string filename){ ifstream filein(filename.c_str(), ios::binary); if( filein==NULL ){ return -1; } filein.close(); return 0; } int process(string filename){ FILE *fp; unsigned long filesize; fp = fopen(filename.c_str(),"rb+"); if( !fp ){ printf("open file error"); return -1; } //rewind(fp); fseek(fp,0,SEEK_END); filesize=ftell(fp); fseek(fp,0,SEEK_SET); unsigned char ch; unsigned char *data = (unsigned char*)malloc(filesize); size_t count = fread(data,sizeof(char),filesize, fp); if( count != filesize ){ cout << "count=" << count << endl; printf("read file error\n"); // return -2; } unsigned char symbol[3] = { 0x83, 0xf8, 0x28 }; //cmp eax,28h unsigned char cover[3] = {0x3b, 0xc0, //cmp eax,eax 0x90 }; //nop //cmp eax,28h 用来判断软件使用时间是否超过40天 //咱们用 cmp eax,eax 替换这个指令,软件就老是觉得咱们试用40天还没过时 //由于cmp eax,eax 只占2字节 而cmp eax,28h 占3字节,为了方便处理 //直接在cmp eax,eax 后加上nop指令。如今要替换的数据也是3字节了。 //在文件中找到symbol的位置 而后用cover直接覆盖便可。 int index = -1; for(int i=0; i<filesize; i++){ if(memcmp(&data[i], symbol, sizeof(symbol)) == 0 ){ index = i; break; } } if( index!= -1 ){ fseek(fp,index,SEEK_SET); fwrite(cover, sizeof(char), sizeof(cover), fp); }else{ return -3; } fclose(fp); return 0; } int main(){ char *filename; string path; //选择程序安装路径 path = ChoseFolder(); if( path.length()==0 ){ cout << "ChoseFolder error" << endl; return -1; } //检查文件是否打开正常 string fullpath( path + "\\WinRAR.exe" ); if( check(fullpath) != 0 ){ cout << "check error" << endl; return -2; } //备份文件 以便恢复 if( backups(fullpath) != 0 ){ cout << "backups error" << endl; return -3; } //打开文件处理 if( process(fullpath)!=0 ){ cout << "process fail" << endl; rollback(fullpath); //处理失败回滚 return -4; } cout << "process success" << endl; return 0; }