首页
社区
课程
招聘
[原创]某聊天app的音视频通话逆向
发表于: 2020-7-13 15:00 10743

[原创]某聊天app的音视频通话逆向

2020-7-13 15:00
10743

目录

来自看雪3W班6月题
该聊天app主要使用c++开发,本题主要考察c++逆向

先尝试找日志类,打开日志信息

首先找到这里

package com.xxxxx.mm.sdk.platformtools;
public class ad

    public interface a {
        void appenderClose();

        void appenderFlush(boolean z);

        int getLogLevel();

        void logD(String str, String str2, String str3, int i, int i2, long j, long j2, String str4);

        void logE(String str, String str2, String str3, int i, int i2, long j, long j2, String str4);

        void logF(String str, String str2, String str3, int i, int i2, long j, long j2, String str4);

        void logI(String str, String str2, String str3, int i, int i2, long j, long j2, String str4);

        void logV(String str, String str2, String str3, int i, int i2, long j, long j2, String str4);

        void logW(String str, String str2, String str3, int i, int i2, long j, long j2, String str4);

        void moveLogsFromCacheDirToLogDir();
    }

查找该interface的实现,找到了Xlog类, 可以看到输出日志的是native函数的logWrite2

package com.xxxxx.mars.xlog;

public class Xlog implements ad.a 
    public static native void logWrite(XLoggerInfo xLoggerInfo, String str);

    public static void open(boolean z, int i, int i2, String str, String str2, String str3, int i3) {
    if (z) {
        System.loadLibrary("xxxxxxlog");
    }
    AppenderOpen(i, i2, str, str2, str3, i3);
    }

    public static native void logWrite2(int i, String str, String str2, String str3, int i2, int i3, long j, long j2, String str4);

    public void logV(String str, String str2, String str3, int i, int i2, long j, long j2, String str4) {
        logWrite2(0, decryptTag(str), str2, str3, i, i2, j, j2, str4);
    }

    public void logD(String str, String str2, String str3, int i, int i2, long j, long j2, String str4) {
        logWrite2(1, decryptTag(str), str2, str3, i, i2, j, j2, LogLogic.appendMemLog(str4));
    }

    public void logI(String str, String str2, String str3, int i, int i2, long j, long j2, String str4) {
        logWrite2(2, decryptTag(str), str2, str3, i, i2, j, j2, LogLogic.appendMemLog(str4));
    }

    public void logW(String str, String str2, String str3, int i, int i2, long j, long j2, String str4) {
        logWrite2(3, decryptTag(str), str2, str3, i, i2, j, j2, LogLogic.appendMemLog(str4));
    }

    public void logE(String str, String str2, String str3, int i, int i2, long j, long j2, String str4) {
        logWrite2(4, decryptTag(str), str2, str3, i, i2, j, j2, LogLogic.appendMemLog(str4));
    }

    public void logF(String str, String str2, String str3, int i, int i2, long j, long j2, String str4) {
        logWrite2(5, decryptTag(str), str2, str3, i, i2, j, j2, str4);
    }

查找Xlog的引用,找到isLogcatOpen, 总之先把这个变量置为true试试

package com.xxxxx.mm.xlog.app;

public class XLogSetup {
    public static Boolean isLogcatOpen;
    ...
}

frida代码:

function hook_java(){
    Java.perform(function () {
        var XLogSetup = Java.use("com.xxxxx.mm.xlog.app.XLogSetup");

        var Xlog = Java.use("com.xxxxx.mars.xlog.Xlog");
        Xlog.setConsoleLogOpen(true);
    });
}

通话过程分析

尝试发起通话请求,此时可以看到一些日志:

keyword: MicroMsg.Voip
2020-06-26 10:57:24.948 15584-15584/? I/MicroMsg.Voip.VoipService: [, , 15584]:startVoiceCall, toUser:wxid_XXXXXXXXXXXX
2020-06-26 10:57:24.949 15584-15584/? I/MicroMsg.Voip.VoipService: [, , 15584]:start VideoActivity in foreground,true
2020-06-26 10:57:34.141 15584-15648/? I/MicroMsg.Voip.AudioPlayer: [, , 15648]:m_iLefSamples value is 640 and iPos value is 3840
2020-06-26 10:57:34.149 15584-15647/? I/MicroMsg.Voip.VoipDeviceHandler: [, , 15647]:[629]amyfwang,first record
2020-06-26 10:57:34.164 15584-15648/? I/MicroMsg.Voip.AudioPlayer: [, , 15648]:m_iLefSamples value is 640 and iPos value is 4160
2020-06-26 10:57:34.187 15584-15648/? I/MicroMsg.Voip.AudioPlayer: [, , 15648]:m_iLefSamples value is 640 and iPos value is 4480

由于通话请求并没有走http,所以尝试hook了一下send

function hook_native() {
    var send_ptr = Module.findExportByName("libc.so", "send");
    console.log("send: ");
    Interceptor.attach(send_ptr, {
        onEnter: function (args) {
            console.log("calling send: ", send_ptr, args[0], args[1], args[2],  args[3]); 
            console.log("send_hex:", hexdump(ptr(args[1]), {length : parseInt(args[2])}));

            console.log("open" + ' called from:\n' +
            Thread.backtrace(this.context, Backtracer.ACCURATE)
                .map(DebugSymbol.fromAddress).join('\n') + '\n');

        }, onLeave: function (retval) {

        }
  });
}

发起通话请求后,可以看到如下日志

[Pixel::com.xxxxx.mm]-> calling send:  0xe6d327e3 0x124 0xfffa8ad0 0x18 0x0
send_hex:            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
fffa8ad0  18 00 00 00 16 00 01 01 00 00 00 00 00 00 00 00  ................
fffa8ae0  00 00 00 00 00 00 00 00                          ........
open called from:
0xbf0e0f71 libvoipComm.so!_Z10getifaddrsPP7ifaddrs+0x54

通话请求接通后,刷出如下日志

calling send:  0xe6d327e3 0x121 0xfffa92d0 0x18 0x0
send_hex:            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
fffa92d0  18 00 00 00 16 00 01 01 00 00 00 00 00 00 00 00  ................
fffa92e0  00 00 00 00 00 00 00 00                          ........
open called from:
0xbf0e0f71 libvoipComm.so!_Z10getifaddrsPP7ifaddrs+0x54

calling send:  0xe6d327e3 0x148 0xbd90afe0 0x9d 0x0
send_hex:            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
bd90afe0  47 45 54 20 2f 64 79 6e 64 65 76 2f 75 75 69 64  GET /dyndev/uuid
bd90aff0  3a 30 34 34 30 61 39 63 65 2d 65 61 36 36 2d 30  :0440a9ce-ea66-0
bd90b000  34 34 30 2d 61 39 63 65 2d 65 61 36 36 30 30 30  440-a9ce-ea66000
bd90b010  30 31 63 35 38 20 48 54 54 50 2f 31 2e 31 0d 0a  01c58 HTTP/1.1..
bd90b020  48 6f 73 74 3a 20 31 39 32 2e 31 36 38 2e 31 38  Host: 192.168.18
bd90b030  38 2e 31 3a 35 34 33 31 0d 0a 43 6f 6e 6e 65 63  8.1:5431..Connec
bd90b040  74 69 6f 6e 3a 20 43 6c 6f 73 65 0d 0a 55 73 65  tion: Close..Use
bd90b050  72 2d 41 67 65 6e 74 3a 20 4f 53 2f 31 2e 30 2c  r-Agent: OS/1.0,
bd90b060  20 55 50 6e 50 2f 31 2e 31 2c 20 57 65 63 68 61   UPnP/1.1, Wecha
bd90b070  74 55 50 6e 50 2f 31 2e 30 0d 0a 0d 0a           tUPnP/1.0....
calling send:  0xe6d327e3 0x14a 0xfffa9380 0x18 0x0
send_hex:            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
fffa9380  18 00 00 00 16 00 01 01 00 00 00 00 00 00 00 00  ................
fffa9390  00 00 00 00 00 00 00 00                          ........
open called from:
0xbf0e0f71 libvoipComm.so!_Z10getifaddrsPP7ifaddrs+0x54

open called from:
0xbf0db47b libvoipComm.so!_ZN9MMTinyLib11MMTSockSendEiPKvPlj+0xe
0xbf0dcf27 libvoipComm.so!_ZN9MMTinyLib10MMTIoqueue24DispatchTcpWritableEventEPNS_14AsyncTCPSocketEb+0xda
0xbf0dd601 libvoipComm.so!_ZN9MMTinyLib10MMTIoqueue4PollENS_10MMTTimeValE+0x298
0xbbaaf8f7 libvoipChannel.so!_ZN19MultiMediaComponent10CoreThread4PollEv+0xe
0xbbac6753 libvoipChannel.so!_ZN19MultiMediaComponent8CHttpMgr11HttpOpenSynERKNS_12CHttpRequestERiPi+0x8a
0xbbab5777 libvoipChannel.so!_ZN19MultiMediaComponent13CNatPunchUpnp12HttpOpenSyncERKNSt6__ndk112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_S9_RS7_+0xce
0xbbab5387 libvoipChannel.so!_ZN19MultiMediaComponent13CNatPunchUpnp16CheckValidDeviceERNS_8CUPNPDevE+0x3e
0xbbab5227 libvoipChannel.so!_ZN19MultiMediaComponent13CNatPunchUpnp13OnFoundDeviceERKNSt6__ndk112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_S9_+0x4a6
0xbbab4d29 libvoipChannel.so!_ZN19MultiMediaComponent13CNatPunchUpnp10OnRecvFromEiPKhlPN9MMTinyLib20mmt_sockaddr_storageE+0x164
0xbbab4bbd libvoipChannel.so!_ZN19MultiMediaComponent13CNatPunchUpnp10OnRecvfromEiPKhlPN9MMTinyLib20mmt_sockaddr_storageEPv+0xc
0xbbaaf5df libvoipChannel.so!_ZThn4_N19MultiMediaComponent10CoreThread10onRecvfromEPN9MMTinyLib14AsyncUDPSocketEPNS1_20mmt_sockaddr_storageEPKvl+0x30
0xbf0dd533 libvoipComm.so!_ZN9MMTinyLib10MMTIoqueue4PollENS_10MMTTimeValE+0x1ca
0xbbaaf8f7 libvoipChannel.so!_ZN19MultiMediaComponent10CoreThread4PollEv+0xe
0xbbab43c1 libvoipChannel.so!_ZN19MultiMediaComponent13CNatPunchUpnp4InitEjb+0x8c
0xbbab77e7 libvoipChannel.so!_ZN19MultiMediaComponent13CNatPunchUpnp20_StartAddPortMappingEjtPFvijtPvEbS1_+0x66
0xbbab7771 libvoipChannel.so!_ZN19MultiMediaComponent13CNatPunchUpnp20StartAddPortMapTimerERN9MMTinyLib10MMTTimeValERiPv+0x24

但是该类型的日志,在通话建立完成以后就不再刷出了,于是尝试用wireshark抓了一下手机的包,可以看到大量的UDP报文,怀疑这堆UDP报文是传输的语音消息
于是尝试hook sendto

var sendto_ptr = Module.findExportByName("libc.so", "sendto");
Interceptor.attach(sendto_ptr, {
        onEnter: function (args) {
            console.log("calling sendto: ", send_ptr, args[0], args[1], args[2],  args[3]); 
            console.log("sendto_hex:", hexdump(ptr(args[1]), {length : parseInt(args[2])}));

            console.log("sendto open" + ' called from:\n' +
            Thread.backtrace(this.context, Backtracer.ACCURATE)
                .map(DebugSymbol.fromAddress).join('\n') + '\n');

        }, onLeave: function (retval) {

        }
  });

此时建立通话连接以后一直有hook日志输出,且语音通话的声音消失

calling sendto:  0xe6d327e3 0x23 0xbdaf5600 0x51 0x0
sendto_hex:            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
bdaf5600  75 2c 22 00 00 00 00 06 a0 fc 94 01 76 2a da 70  u,".........v*.p
bdaf5610  32 7e 52 aa 71 d9 55 32 da 6a 0b b3 92 2f 53 b7  2~R.q.U2.j.../S.
bdaf5620  8f 0c 3a 0a 25 2a f4 78 ea 26 b2 ac 36 d7 3b 55  ..:.%*.x.&..6.;U
bdaf5630  b4 6c 4e af 9f 54 56 20 57 d3 79 73 c3 b5 61 62  .lN..TV W.ys..ab
bdaf5640  74 62 dd 34 90 f8 a5 08 bd 8b fe 7c 2f b3 1e 65  tb.4.......|/..e
bdaf5650  98                                               .
sendto open called from:
0xb9e24577 libvoipComm.so!_ZN9MMTinyLib13MMTSockSendtoEiPKvljPKNS_20mmt_sockaddr_storageEPNSt6__ndk13mapIS2_S2_NS5_4lessIS2_EENS5_9allocatorINS5_4pairIS3_S2_EEEEEEi+0xe2
0xb9e24573 libvoipComm.so!_ZN9MMTinyLib13MMTSockSendtoEiPKvljPKNS_20mmt_sockaddr_storageEPNSt6__ndk13mapIS2_S2_NS5_4lessIS2_EENS5_9allocatorINS5_4pairIS3_S2_EEEEEEi+0xde
0xb9e26a03 libvoipComm.so!_ZN9MMTinyLib10MMTIoqueue21DispatchWritableEventEPNS_14AsyncUDPSocketE+0xf2
0xb9e2664d libvoipComm.so!_ZN9MMTinyLib10MMTIoqueue4PollENS_10MMTTimeValE+0x2e4
0xb70a8689 libvoipChannel.so!_ZN19MultiMediaComponent10CoreThread17WorkingThreadFuncEv+0x40
0xb70a993f libvoipChannel.so!_ZNSt6__ndk114__thread_proxyINS_5tupleIJNS_10unique_ptrINS_15__thread_structENS_14default_deleteIS3_EEEEMN19MultiMediaComponent10CoreThreadEFvvEPS8_EEEEEPvSD_+0x28
0xe6d59ee7 libc.so!0x47ee7
0xe6d2d1d9 libc.so!0x1b1d9

首先根据通话接通后就一直刷出的日志:I/MicroMsg.Voip.AudioPlayer: [, , 15648]:m_iLefSamples value is 640 and iPos value is 4800搜索,可找到如下函数, 其功能是创建一个线程循环的请求,直到通话结束才会退出循环

public final int dRU() {
    ...
    this.xdx = new b() {
        public final String getKey() {
            return "AudioPlayer_play";
        }

        public final void run() {
            int i;
            int Q;
            AppMethodBeat.i(114813);
            Process.setThreadPriority(-19);
            ad.d("MicroMsg.Voip.AudioPlayer", "AudioPlayer enter  to start....");
            int i2 = 0;
            while (c.this.zfx && c.this.aUg != null && c.this.aUg.getPlayState() != 1 && !c.this.zfI.get()) {
                try {
                    i = c.this.aUg.getPlaybackHeadPosition();
                } catch (Exception e2) {
                    ad.w("MicroMsg.Voip.AudioPlayer", "getPlaybackHeadPosition: ", e2);
                    int unused = c.this.zgf = 7;
                    i = 0;
                }
                long currentTimeMillis = System.currentTimeMillis();
                int unused2 = c.this.zfR = c.this.zfO - i;
                ad.i("MicroMsg.Voip.AudioPlayer", "m_iLefSamples value is %s and iPos value is %s", Integer.valueOf(c.this.zfR), Integer.valueOf(i));
                ...
}

又根据sendto的trace堆栈,找到了通话接通时创建的线程函数

std::__ndk1 *__fastcall MultiMediaComponent::CoreThread::StartThread(MultiMediaComponent::CoreThread *this)
{
  int v1; // r8
  MultiMediaComponent::CoreThread *v2; // r4
  std::__ndk1::__thread_struct *v3; // r5
  std::__ndk1::__thread_struct **v4; // r0
  std::__ndk1 *result; // r0
  const char *v6; // r2
  int v7; // [sp+0h] [bp-18h]
  int v8; // [sp+4h] [bp-14h]
  int v9; // [sp+8h] [bp-10h]

  v9 = v1;
  v2 = this;
  *((_BYTE *)this + 136) = 0;
  v3 = (std::__ndk1::__thread_struct *)operator new(4u);
  std::__ndk1::__thread_struct::__thread_struct(v3);
  v4 = (std::__ndk1::__thread_struct **)operator new(0x10u);
  *v4 = v3;
  v4[1] = (std::__ndk1::__thread_struct *)MultiMediaComponent::CoreThread::WorkingThreadFunc;
  v4[2] = 0;
  v4[3] = v2;
  result = (std::__ndk1 *)pthread_create(
                            (pthread_t *)&v7,
                            0,
                            (void *(*)(void *))std::__ndk1::__thread_proxy<std::__ndk1::tuple<std::__ndk1::unique_ptr<std::__ndk1::__thread_struct,std::__ndk1::default_delete<std::__ndk1::__thread_struct>>,void (MultiMediaComponent::CoreThread::*)(void),MultiMediaComponent::CoreThread*>>,
                            v4);
  ...

hook 该函数,再次打印调用堆栈

    var base_libvoipChannel = Module.findBaseAddress("libvoipChannel.so");
    //73FFC MultiMediaComponent::Connector::StartCoreThread
    if (base_libvoipChannel) {
        var sub_00073FFC  = base_libvoipChannel.add(0x00073FFC  + 1);
        Interceptor.attach(sub_00073FFC , {
            onEnter: function (args) {
                //this.arg2 = args[2];    //result
                console.log("sub_00073FFC  onEnter:");
                console.log("sub_00073FFC" + ' called from:\n' +
                Thread.backtrace(this.context, Backtracer.ACCURATE)
                    .map(DebugSymbol.fromAddress).join('\n') + '\n');
            }, onLeave: function (ret) {
                console.log("sub_00073FFC  onLeave:");
            }
        });
    }
sub_00073FFC  onEnter:
sub_00073FFC called from:
0xb7066e3f libvoipChannel.so!_ZN19MultiMediaComponent17CTransportChannel10AddNewConnERKNS_18DirectConnAttrInfoE+0x9a
0xb6fc5ec9 libvoipMain.so!AddNewDirectConns+0x65c
0xb6fb8ae7 libvoipMain.so!Java_com_xxxxx_mm_plugin_voip_model_v2protocal_AddNewDirectConns+0x22
0xc4f9a8bb base.odex!oatexec+0x9018bb

sub_00073FFC  onLeave:

找到Java层调用的函数libvoipMain.soJava_com_xxxxx_mm_plugin_voip_model_v2protocal_AddNewDirectConns

 

所以语音过程是这样的:
Java_com_xxxxx_mm_plugin_voip_model_v2protocal_AddNewDirectConns--->
创建线程,建立连接--->
语音的获取--->
通过libvoipComm.soMMTinyLib::MMTSockSendto,UDP发送数据--->
通过libvoipComm.soMMTinyLib::MMTSockRecvfrom,UDP接收数据

追溯sendto的数据产生来源

//_ZN9MMTinyLib10MMTIoqueue21DispatchWritableEventEPNS_14AsyncUDPSocketE
int __fastcall MMTinyLib::MMTIoqueue::DispatchWritableEvent(MMTinyLib::CPoller *a1, int *a2) {
    ...
    a3 = a2;
    v6 = (_DWORD *)a3[40];
    v7 = (void *)v6[36];
    buff = v7;
    MMTinyLib::MMTSockSendto(*a3, buff, v44, 0, v4, v47, v14);
    ...
}
//可还原出函数定义
int MMTIoqueue::DispatchWritableEvent( AsyncUDPSocket* pAsyncUDPSocket)

在该函数中找到赋值点

int __fastcall MMTinyLib::MMTIoqueue::Poll(_DWORD *a1){
    ...
    pAsyncUDPSocket = *((_DWORD *)v14 - 2);
    MMTinyLib::MMTSockRecvfrom(*(struct sockaddr **)pAsyncUDPSocket);
    ...
    MMTinyLib::MMTIoqueue::DispatchWritableEvent((MMTinyLib::CPoller *)v1, *((int **)v14 - 2));
}

//对应汇编
.text:0001B38E                 ADD.W           R0, R4, #0x2C ; this
.text:0001B392                 STR             R0, [SP,#0x2C0+var_2AC]
.text:0001B3A6                 ADD.W           R8, SP, #0x2C0+var_2A0
.text:0001B646                 LDR.W           R1, [R8,#-8]
.text:0001B64A                 MOV             R0, R4
.text:0001B64C                 BLX             j__ZN9MMTinyLib10MMTIoqueue21DispatchWritableEventEPNS_14AsyncUDPSocketE ; MMTinyLib::MMTIoqueue::DispatchWritableEvent(MMTinyLib::AsyncUDPSocket *)

综上,得到对应结构体偏移

class MMTIoqueue {
    char[8];
    AsyncUDPSocket* pAsyncUDPSocket;
    ...
}

struct AsyncUDPSocket {
    char[40*sizeof(int)];
    UserData* pUserData;
    ...
}

struct UserData {
    char[36*sizeof(int)];
    char* buff;
    ...
}

找到MMTinyLib::MMTIoqueue中疑似构造AsyncUDPSocket结构体的函数

.text:0001A930 ; MMTinyLib::MMTIoqueue::RecreateUdpSocket(MMTinyLib::AsyncUDPSocket *)

.text:0001A1BC ; int __fastcall MMTinyLib::MMTIoqueue::CreateUdpSocket

hook试试

var base_libvoipComm = Module.findBaseAddress("libvoipComm.so");

    if (base_libvoipComm) {
        ////1A930   MMTinyLib::MMTIoqueue::RecreateUdpSocket(MMTinyLib::AsyncUDPSocket *)
        var sub_0001A930  = base_libvoipComm.add(0x0001A930  + 1);
        Interceptor.attach(sub_0001A930 , {
            onEnter: function (args) {
                //this.arg2 = args[2];    //result
                console.log("RecreateUdpSocket  onEnter:");
                console.log("RecreateUdpSocket" + ' called from:\n' +
                Thread.backtrace(this.context, Backtracer.ACCURATE)
                    .map(DebugSymbol.fromAddress).join('\n') + '\n');
            }, onLeave: function (ret) {
                console.log("RecreateUdpSocket  onLeave:");
            }
        });

        //1A1BC  int __fastcall MMTinyLib::MMTIoqueue::CreateUdpSocket
        var sub_0001A1BC  = base_libvoipComm.add(0x0001A1BC  + 1);
        Interceptor.attach(sub_0001A1BC , {
            onEnter: function (args) {
                //this.arg2 = args[2];    //result
                console.log("CreateUdpSocket  onEnter:");
                console.log("CreateUdpSocket" + ' called from:\n' +
                Thread.backtrace(this.context, Backtracer.ACCURATE)
                    .map(DebugSymbol.fromAddress).join('\n') + '\n');
            }, onLeave: function (ret) {
                console.log("CreateUdpSocket  onLeave:");
            }
        });
    }

得到结果

[Pixel::com.xxxxx.mm]-> CreateUdpSocket  onEnter:
CreateUdpSocket called from:
0xb70a8cb9 libvoipChannel.so!_ZN19MultiMediaComponent10CoreThread19CreateCoreSocketNewERN9MMTinyLib20mmt_sockaddr_storageEPNS_21CoreUdpSocketCallbackEPvj+0xdc
0xb707a1d9 libvoipChannel.so!_ZN19MultiMediaComponent8RelayMgr16GetNewCoreSocketEPNS_9RelayRoomEiNSt6__ndk112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE+0x140
0xb707ad8b libvoipChannel.so!_ZN19MultiMediaComponent8RelayMgr12RelayCheckInEPNS_9RelayRoomE+0x10e
0xb707aae9 libvoipChannel.so!_ZN19MultiMediaComponent8RelayMgr13OpenRelayConnEPNS_8ConnInfoEPKNS_19conn_private_data_tE+0x7c
0xb70676db libvoipChannel.so!_ZN19MultiMediaComponent17CTransportChannel10AddNewConnERKNS_17RelayConnAttrInfoE+0x126
0xb6fc5785 libvoipMain.so!AddNewRelayConns+0x7c0
0xb6fb8aa7 libvoipMain.so!Java_com_xxxxx_mm_plugin_voip_model_v2protocal_AddNewRelayConns+0x22
0xc4f9a8bb base.odex!oatexec+0x9018bb

CreateUdpSocket  onLeave:

所以构造AsyncUDPSocket结构体的是CreateUdpSocket


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-7-13 15:03 被咸鱼炒白菜编辑 ,原因:
收藏
免费 5
支持
分享
最新回复 (8)
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
企鹅聊天?
2020-7-13 16:17
0
雪    币: 605
活跃值: (1672)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
3
hook一下 我们给对方放一首歌
2020-7-13 16:31
0
雪    币: 4471
活跃值: (3884)
能力值: ( LV8,RANK:138 )
在线值:
发帖
回帖
粉丝
4
保存一下发送和接收的数据,可以搞个通话“录音”?
2020-7-13 16:40
0
雪    币: 3937
活跃值: (3327)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
666
2020-7-13 19:25
0
雪    币: 1430
活跃值: (1240)
能力值: ( LV3,RANK:23 )
在线值:
发帖
回帖
粉丝
6
zhighest 保存一下发送和接收的数据,可以搞个通话“录音”?
send,recv 格式解析多麻烦,抓 Audio 流 简单,另外本地应该需要与麦克风流进行合成
2020-7-14 15:15
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
这个是微信的吧  要是语音信息是存放在本地的  之前弄过聊天记录这种,不过要是语音通话那肯定就没存了
2020-7-15 12:25
0
雪    币: 997
活跃值: (420)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
厉害了菜菜大佬
2020-7-18 16:35
0
雪    币: 221
活跃值: (4240)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
我从Audiorecord替换pcm流比较简单点,前提录制好的音频码率什么的要对上
2020-11-12 09:47
0
游客
登录 | 注册 方可回帖
返回
//