@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