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; }