怎么样在hook到以后,调用app内部的一个c++函数呢

我还是在研究那个游戏,因为是联网游戏,他肯定是加密的,然后我就看见了代码里面写死的2个长字符串

通过hookEncrypt函数,发现确实是des加密用到的密钥
image



查看了加密解密函数,参数结构基本上一致。

现在猜测加密发包和解密收包应该是通过不同的密钥来实现的。

客户端只能:解密收到的数据,加密发送的数据。(因为密钥是不同的)
但是我不死心啊,我想hook到加密函数以后。利用加密时传入的数据,执行解密函数,打印出来看看。是否可以通过利用加密的密钥,调用解密的函数(des对称加密的,应该是用同一个密钥的)实现解密,进一步确定,加密和解密的算法是一致的,只是密钥区别。
然后,就有以下代码。

#include <substrate.h>
#import <sys/socket.h>
#import <UIKit/UIKit.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h> // 包含inet_ntoa函数的头文件
#import <Foundation/Foundation.h>

void* (*orig_ChangeState)(char *a1,int a2);

void* new_ChangeState(char *a1,int a2)
{
    // 默认情况下调用原始函数
    if (a2 != 21 && a2 != 16 ){//只有16和21流程可以执行 其他的全部作为14
        a2=14;
    }
    void* ret = orig_ChangeState(a1, a2);
    return ret;
}
int (*orig_MakeEncryptCode)( int *a2);
int new_MakeEncryptCode( int *a2)
{  
    int ret = orig_MakeEncryptCode(a2);
    return ret;
}


int (*orig_encrypt)(char *a1, char *a2, int a3, char *a4, int *a5, int a6);

int new_encrypt(char *a1, char *a2, int a3, char *a4, int *a5, int a6)
{  
    StrNSlog(@"执行加密之前A1",a1);
    StrNSlog(@"执行加密之前A2",a2);
    StrNSlog(@"执行加密之前A4",a4);
    int ret= orig_encrypt(a1,a2,a3,a4,a5,a6);//先执行原流程。保证正常进行流程
    StrNSlog(@"执行加密之后A1",a1);
    StrNSlog(@"执行加密之后A2",a2);
    StrNSlog(@"执行加密之后A4",a4);



    char* olda1=a1;
    char* olda2=a2;
    int  olda3=a3;
    char* olda4=a4;
    int*  olda5=a5;
    int  olda6=a6;
    int(*decryptFunction)(char*, char*, int, char*, int*, int) = (int (*)(char*, char*, int, char*, int*, int))MSFindSymbol(NULL, "__ZN8CEncrypt7decryptEPKciPcRii");
    if (*decryptFunction){
    NSLog(@"地址获取成功");
    NSLog(@"解密函数地址:%p", decryptFunction);
    NSLog(@"解密之前");
    StrNSlog(@"执行解密之前A1",olda1);
    StrNSlog(@"执行解密之前A2",olda2);
    StrNSlog(@"执行解密之前A4",olda4);
    // 调用函数
    NSLog(@"解密完成");
    int ret1=decryptFunction(olda1, olda2,olda3, olda4, olda5,olda6);
    StrNSlog(@"执行解密之后A1",olda1);
    StrNSlog(@"执行解密之后A2",olda2);
    StrNSlog(@"执行解密之后A4",olda4);
    NSLog(@"有没有执行:%d", ret1);
    }
   
    return ret;
}

%ctor {
    void *lpFun = ((void*)MSFindSymbol(NULL, "__ZN11CGameUpdate11ChangeStateEi"));//跳过更新
    if (lpFun) {
        MSHookFunction(lpFun, (void*)new_ChangeState, (void**)&orig_ChangeState);
    }
    void *lpFun4 = ((void*)MSFindSymbol(NULL, "__ZN8CEncrypt7encryptEPKciPcRii"));
    if (lpFun4) {
        MSHookFunction(lpFun4, (void*)new_encrypt, (void**)&orig_encrypt);
    }
}

代码大概是这样的 。


经过大佬的帮助,把代码修改了一下。应该可以基本上证明,加密解密是同一个des算法,没有区别
加密之前是 58 02加密之后是1A C8 4A 2D F0 CF 7D BF C5 73 6C A4 2A FF 15 28 02 0F 76 3F AC D9 99 74 59 74 AF B5 B9 EE E5 05
解密之前是1A C8 4A 2D F0 CF 7D BF C5 73 6C A4 2A FF 15 28 02 0F 76 3F AC D9 99 74 59 74 AF B5 B9 EE E5 05解密以后还是 58 02

实在是不懂,用ai帮忙写的代码,好像是不太成功啊