c/c++ 100行代码破解winrar

  • 写在前面的废话

             winrar过期了老是弹窗,超恶心,今天也不想去上课,算了ri掉rar吧。

  • 原理

                 winrar有40天的试用期,过了试用期就开始弹窗。因为以前用od调试过,判断试用是否过期的汇编代码是
cmp eax,28h  //用eax存的天数和28h(等于40天)比较 判断是否过期
             //二进制值为 0x83,0xf8,0x28

我们将上面的指令替换为:

   汇编指令      对应二进制值
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;
}




转载于:https://my.oschina.net/cuilili/blog/207326

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值