#前言
做逆向的童鞋都肯定遇到很多一些怎么去调用破解别人写的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, “__Z9FQ_verifyP8NSStringi”), (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; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
完结
具体日志我没有分享出来,以为时隔很久,只有经过挂届的传说才会明白其中的惊心动魄。