Quantcast
Channel: Essence Sharing | 干货分享 - iOSRE
Viewing all articles
Browse latest Browse all 301

如何Hook别人的dylib

$
0
0

@tinkl wrote:

前言

做逆向的童鞋都肯定遇到很多一些怎么去调用破解别人写的dylib,对于一些简单的%hook这里我就不再阐述了,今天我主要说说关于C++和Lua结合使用的dylib,看怎么一步一步突破它们。

教程

第一步:解包deb

dpkg-deb -x 文件名 路径

----- WeChatRed.dylib 咋们要分析的dylib
----- WeChatBundle 是二进制设置文件

第二步:Hopper 用的正版V4.0.30


一般做微信红包外挂的作者都会做一定的反外挂处理,所以3k作者也不例外。基本核心初始化函数和数据函数都是C/C++函数处理。那么怎么Hook FQ_verify(NSString*, int)这个函数呢?
两种办法:
第一种:fackbook的fishhook.c处理hook
第二种:MSHookFunction(MSFindSymbol(image, "_Z9FQverifyP8NSStringi"), (void*)hook_Class, (void**)&oldClass) 如果在其他函数里则需要函数:MSGetImageByName去获取该MSImageRef的image如:
MSImageRef image;
image = MSGetImageByName("/Library/PreferenceBundles/你猜");

C++ Hook实现如下:
void(*oldClass)(NSString*,int);
void hook_Class(NSString* s,int inxxx){
NSLog(@" getStrNs(NSString*) : \n %@ ", s);
oldClass(s,inxxx);
}

第三步:进入核心破解逻辑:

每一种挂或者deb基本都会用到系统核心加密库,如CCCryptor 、 MD5、newstrstr、str操作、jsoncpp等,那么一般都是UDID+激活码+产品名称去服务器验证并返回是否已经授权,是否是当前这个设备,激活码是否存在等信息。
通过FlexLoader和GDB调试可以看到验证逻辑时,dylib有大致调用以下信息:
[Base64codeFunc DESEncrypt:WithKey:]以及对CCCrypt的引用!!!
那么找到对方判断逻辑,如下:

Base64codeFunc里的信息hook之后发现没有找到关键逻辑,继续往下深入:

MSHookFunction(strstr,newstrstr , &oldstrstr);
MSHookFunction(strrchr,newstrrchr , &oldstrrchr);
MSHookFunction(CCCrypt,newCCCrypt , &oldCCCrypt);
MSHookFunction(atoi,newatoi , &oldatoi);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

CCCryptorStatus
(*oldCCCrypt)(
CCOperation , /* kCCEncrypt, etc. */
CCAlgorithm , /* kCCAlgorithmAES128, etc. */
CCOptions , /* kCCOptionPKCS7Padding, etc. */
const void *,
size_t ,
const void , / optional initialization vector */
const void , / optional per op and alg */
size_t ,
void , / data RETURNED here */
size_t ,
size_t *);

CCCryptorStatus
newCCCrypt(
CCOperation op, /* kCCEncrypt, etc. */
CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */
CCOptions options, /* kCCOptionPKCS7Padding, etc. */
const void *key,
size_t keyLength,
const void iv, / optional initialization vector */
const void dataIn, / optional per op and alg */
size_t dataInLength,
void dataOut, / data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved){

if(iv == NULL){
	return oldCCCrypt(op,alg,options,key,keyLength,iv,dataIn,dataInLength,dataOut,dataOutAvailable,dataOutMoved);
}else{
 	NSData * ivd = [NSData dataWithBytes:iv length:100];
	NSLog(@"iv : %@ %@", ivd,[[NSString alloc] initWithData:ivd encoding:(NSUTF8StringEncoding)]);
}

NSLog(@"key:%@  inValue:%@",[NSData dataWithBytes:key length:keyLength],[NSData dataWithBytes:dataIn length:dataInLength]);
NSString * keysss = [[NSString alloc] initWithBytes:key length:keyLength encoding:(NSUTF8StringEncoding)];    

if (keysss){
	//这里是数据返回key 直接返回OK
	//int value 
	//NSData * valueOK = [@"你猜猜这里是什么" dataUsingEncoding:(NSUTF8StringEncoding)];    	
	//oldCCCrypt(op,alg,options,key,keyLength,iv,dataIn,dataInLength,dataOut,dataOutAvailable,dataOutMoved);    	
	//oldCCCrypt(op,alg,options,key,keyLength,iv,valueOK.bytes,valueOK.length,dataOut,dataOutAvailable,dataOutMoved);    	
}

CCCryptorStatus st = oldCCCrypt(op,alg,options,key,keyLength,iv,dataIn,dataInLength,dataOut,dataOutAvailable,dataOutMoved);

NSString * datainValue = [[NSString alloc] initWithBytes:dataIn length:dataInLength encoding:(NSUTF8StringEncoding)];
NSString * value = [[NSString alloc] initWithBytes:dataOut length:dataOutAvailable encoding:(NSUTF8StringEncoding)];

if (op == kCCEncrypt){
	NSLog(@" ------------ CCCrypt 加密  Key:%@ datainValue :%@  outValue:%@ ------------------ ",keysss,datainValue,value);

	//这里获取UDID
	if(datainValue && [datainValue containsString:@"udid"]){
		//并且不包含time
		if(datainValue && ![datainValue containsString:@"time"]){     		
    		NSString * udid = @"江可泽民亦可赛艇";
		 这里基本是授权的关键信息 udid、time、key
		}
}
    }else{
    	NSLog(@" ------------ CCCrypt 解密  Key:%@  datainValue :%@  outValue:%@ ------------------ ",keysss,datainValue,value);
    	if(keysss && keysss.length == 8){   //write down 授权key}
    NSData * datainValue = [NSData dataWithBytes:dataIn length:dataInLength];
   NSString * valuesss = [[NSString alloc] initWithBytes:dataOut length:dataOutAvailable encoding:(NSUTF8StringEncoding)];	        
   NSLog(@"key : %@ 结果:%@ |||| %@",keysss,[datainValue base64EncodedStringWithOptions:4],valuesss);
    } 
	return st; 
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

完结

具体日志我没有分享出来,以为时隔很久,只有经过挂届的传说才会明白其中的惊心动魄。

Posts: 18

Participants: 4

Read full topic


Viewing all articles
Browse latest Browse all 301

Trending Articles