本帖最后由 fjqisba 于 2022-10-9 23:49 编辑
项目使用C++开发,地址如下:
https://github.com/fjqisba/WeChatStudy
项目介绍:
StudyWechat,Support Version 3.7.6.44
The project is for study only, it is prohibited to use it for illegal purposes.
项目仅供学习参考,禁止用于非法用途。
注意,项目关键点是一个框架,给大家演示了如何去HOOK与调用VX,至于其它功能各位可自行研发。
下面分享一些我对C++逆向的经验:
C++逆向说白了还是对函数和结构体(类)的逆向,本质上和其它语言也没啥太大区别。看到虚函数调用先不慌,动态调试摸清大概流程。遇到this指针也不要急,结构体先建起来。搞清楚了结构体的成员,函数调用之间的关系,代码逻辑自然就容易看了。
C++遇到有RTTI符号的尽量使用classinfomer插件,利用好符号信息。
我们逆向一般都需要向目标注入自己编写的DLL,但编写功能点的时候又要用到对方程序的二进制代码,如何将自己写的代码和对方的二进制代码进行耦合我认为这也是逆向过程中重要且核心的部分。
一般来说,我会把类当成结构体来尽可能还原出来,因为不管类有多复杂,在内存眼里中只有一块缓冲区罢了。如果二进制中类有完整的构造函数,则可以考虑直接调用对方的构造函数,逆出来的结构体不要定义析构函数,因为由于编译器的原因,无法确定结构体是函数体内析构还是体外析构。如果有析构的需求,可以考虑再封装一个类,比如某个类mmString,逆向出来的结构是这样的:
struct mmString
{
public:
mmString();
void assign(const char* src);
void free()
{
if (this->pUnicode) {
delete this->pUnicode;
this->pUnicode = 0x0;
}
this->Mysize = 0x0;
this->Myres = 0x0;
if (this->pUTF8) {
delete this->pUTF8;
this->pUTF8 = 0x0;
}
this->uLen = 0x0;
}
public:
wchar_t* pUnicode;
int Mysize;
int Myres;
char* pUTF8;
int uLen;
};
我们可以这样来构造一个新的类,拿来给自己的代码用:
struct MymmString:public mmString
{
public:
MymmString();
//析构函数
~MymmString()
{
free();
}
};
这样就可以视使用情况灵活选择mmString、MymmString这两种结构体了。
另外,我认为微信也挺适合用来做逆向练手,其优点有以下:
1、C++语言编写,中国人编写,代码思维模式符合国人习惯。
2、上层框架不复杂,单个功能逆向简单,代码体量不大(只有一个核心DLL)。
3、存在RTTI符号和源码级别的日志信息,无反调试,除了部分vmp,无其它保护,逆向友好。
项目中我也封装了一些调用代码库和hook库,基本上可以很方便的去调用或者监控对方的代码。主要还是希望大家能从代码中有所收获。
|