GetQrcodeImage.cpp 3.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
#include "pch.h"

#define SwitchQrcodeLoginCall1Offset 0x372AA0
#define SwitchQrcodeLoginCall2Offset 0x5177D0

#define SaveQrcodeImageHookOffset 0x2815DA
#define SaveQrcodeImageNextCallOffset 0x76F660

static DWORD SaveQrcodeImageHookAddr;
static DWORD SaveQrcodeImageNextCall;
static DWORD SaveQrcodeImageJmpBackAddress;

static bool SaveQrcodeImageHooked = false;
static char SaveQrcodeImageOldAsmCode[5] = {0};
static DWORD SignalThreadId = 0;

struct QrcodeStruct
{
    unsigned char *image = NULL;
    int size = 0;
    void update(unsigned char *buf, int len)
    {
        this->free();
        this->image = new unsigned char[len + 1];
        memcpy(this->image, buf, len);
        this->size = len;
    }
    void free()
    {
        if (this->image != NULL)
        {
            delete[] this->image;
            this->image = NULL;
        }
        this->size = 0;
    }
    ~QrcodeStruct()
    {
        this->free();
    }
};

static unique_ptr<QrcodeStruct> qc(new QrcodeStruct);

void SaveQrcodeImage(unsigned char *src, int size)
{
    qc->update(src, size);
L
ljc545w 已提交
48
    SIGNAL(SignalThreadId, WM_WAIT_HOOK_DATA);
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
}

_declspec(naked) void dealQrcodeImage()
{
    __asm {
        pushad;
        pushfd;
        push dword ptr[eax + 4];
        push dword ptr[eax];
        call SaveQrcodeImage;
        add esp, 0x8;
        popfd;
        popad;
        call SaveQrcodeImageNextCall;
        jmp SaveQrcodeImageJmpBackAddress;
    }
}

void HookQrcodeImage()
{
    if (SaveQrcodeImageHooked)
        return;
    DWORD WeChatWinBase = GetWeChatWinBase();
    SaveQrcodeImageHookAddr = WeChatWinBase + SaveQrcodeImageHookOffset;
    SaveQrcodeImageNextCall = WeChatWinBase + SaveQrcodeImageNextCallOffset;
    SaveQrcodeImageJmpBackAddress = SaveQrcodeImageHookAddr + 0x5;
    HookAnyAddress(SaveQrcodeImageHookAddr, (LPVOID)dealQrcodeImage, SaveQrcodeImageOldAsmCode);
    SaveQrcodeImageHooked = true;
}

void UnHookQrcodeImage()
{
    if (!SaveQrcodeImageHooked)
        return;
    UnHookAnyAddress(SaveQrcodeImageHookAddr, SaveQrcodeImageOldAsmCode);
    SaveQrcodeImageHooked = false;
}

BOOL __stdcall SwitchToQrcodeLogin()
{
    qc->free();
    DWORD WeChatWinBase = GetWeChatWinBase();
    DWORD SwitchQrcodeLoginCall1 = WeChatWinBase + SwitchQrcodeLoginCall1Offset;
    DWORD SwitchQrcodeLoginCall2 = WeChatWinBase + SwitchQrcodeLoginCall2Offset;
    int isSuccess = 0;
    __asm {
        pushad;
        pushfd;
        call SwitchQrcodeLoginCall1;
        mov ecx,eax;
        call SwitchQrcodeLoginCall2;
        movzx eax,al;
        mov isSuccess,eax;
        popfd;
        popad;
    }
    return isSuccess == 1;
}

#ifndef USE_SOCKET
DWORD GetQrcodeImageRemote()
{
    if (isWxLogin())
        return 0;
    if (!SaveQrcodeImageHooked)
        HookQrcodeImage();
L
ljc545w 已提交
115
    WxSignal sg(WM_WAIT_HOOK_DATA, SignalThreadId);
116 117 118 119 120 121 122 123 124 125 126
    SwitchToQrcodeLogin();
    sg.wait(5000);
    return (DWORD)qc.get();
}
#else
BYTE *__stdcall GetQrcodeImage(int &size)
{
    if (isWxLogin())
        return NULL;
    if (!SaveQrcodeImageHooked)
        HookQrcodeImage();
L
ljc545w 已提交
127
    WxSignal sg(WM_WAIT_HOOK_DATA, SignalThreadId);
128 129 130 131 132 133 134 135 136
    SignalThreadId = sg.GetThreadId();
    SwitchToQrcodeLogin();
    sg.wait(5000);
    size = qc->size;
    if (qc->size == 0)
        return NULL;
    return qc->image;
}
#endif