吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2429|回复: 2
收起左侧

[会员申请] 申请会员ID:存钱买板子【申请通过】

[复制链接]
吾爱游客  发表于 2021-2-22 21:13
1.申请ID:存钱买板子
2.个人邮箱:yuan6900956@163.com
3.原创技术文章:PE导入表注入DLL

分享一下32位PE文件如何利用导入表注入DLL,以及原创C代码。

1.原理:
     当一个程序启动的时候,它所依赖的各种DLL也会被加载,而当一个DLL加载或者销毁的时候,系统会调用这个DLL的DllMain函数
     而这些个需要加载的DLL都是什么,都提供了哪些函数,都被记录在了导入表里面。所以我们可以在导入表里面新加一个要被注入的DLL信息,以此达到我们的目的。


2.实现步骤:
       1>把PE文件加载到FileBuffer:       2>遍历一下原来有多少个DLL,后面复制的时候会它求尺寸:注意:一个PE文件可能有多个导入表结构,最后有一个全0结构标志结束
       3>新增一个节:注意:新增节必须有可执行的属性
     4>给DLL名字字符串和导入函数名字字符串赋值:(注意:不要忘了字符串末尾的0
     5>给_IMAGE_THUNK_DATA32结构(INT表和IAT所指向的)赋值(这个结构最高位为1说明是以序号导出,否则以名字导出,此时为IMAGE_IMPORT_BY_NAME结构的RVA):
     6>拷贝原导入表到新增节:(注意:不要忘了最后那个全0结构
     7>给新导入表赋值:(注意:这里面的地址都为RVA
     8>修正目录项第二个的RVA:
     9>存盘

        注入后新增节的内存图:
注入后内存图.png

3.注入后效果:


       把加载时弹窗的DLL注入到CE里效果:
效果图.jpg


4.完整C代码:(VS2010)
Inject.cpp:
[C++] 纯文本查看 复制代码
#include "InjectH.h"
#define InPutPath "E:\\测试区\\ce.exe"                                                //输入文件目录
#define OutPutPath "E:\\测试区\\ce_new.exe"                                        //输出文件目录
#define SizeOfNewSection 0x1000                                                                //新增节尺寸

_PIMAGE_DOS_HEADER DosHeader = NULL;                                                        //DOS头指针
_PIMAGE_NT_HEADER NtHeader = NULL;                                                                //NT头指针
_PIMAGE_FILE_HEADER FileHeader = NULL;                                                        //标准PE头指针
_PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;                                        //可选PE头指针 
_PIMAGE_SECTION_HEADER pSectionHeader = NULL;                                        //节表指针
_PIMAGE_IMPORT_DESCRIPTOR pImportDesriptor = NULL;                                //导入表指针

BYTE DllName[] = "InjectDll.dll";                        //要注入的DLL名字
BYTE ImportFunName[] = "ExportFunction";        //DLL中函数名
BYTE NewSectionName[] = "Fly";                                //新增节名字

//加载PE,加载到FileBuffer
size_t LoadPE(STR Path , PBYTE* Buffer)
{
        //打开文件
        FILE* fp = fopen(Path,"rb");
        if(!fp)
        {
                printf("文件打开失败\n");
                return 0;
        }

        //获取文件尺寸
        fseek(fp,0,SEEK_END);
        size_t FileSize = ftell(fp);
        fseek(fp,0,SEEK_SET);

        //申请文件缓冲区
        BYTE* pFileBuffer = (BYTE*)malloc(FileSize);
        if( !pFileBuffer )
        {
                printf("内存申请失败!\n");
                fclose(fp);
                return 0;
        }
        //内存拷贝
        memset(pFileBuffer,0,FileSize);

        if(!fread(pFileBuffer,FileSize,1,fp))
        {
                printf("写入缓冲区失败!\n");
                free(pFileBuffer);
                fclose(fp);
                return 0;
        }
        *Buffer = pFileBuffer;

        //判断是否是PE文件
        if(*((WORD*)pFileBuffer) != 0x5A4D)
        {
                printf("不是有效的MZ标志\n");
                free(pFileBuffer);
                fclose(fp);
                return 0;
        }
        DosHeader = (_PIMAGE_DOS_HEADER)pFileBuffer;
        pFileBuffer = pFileBuffer + ((_PIMAGE_DOS_HEADER)pFileBuffer)->e_lfanew;        //偏移到NT头
        if(((_PIMAGE_NT_HEADER)pFileBuffer)->Signature != 0x4550)
        {
                printf("不是有效的PE标志\n");
                free(*Buffer);
                fclose(fp);
                return 0;
        }
        NtHeader = (_PIMAGE_NT_HEADER)pFileBuffer;        //获取NT头
        pFileBuffer = pFileBuffer + 0x4;        //偏移到标准PE头
        FileHeader = (_PIMAGE_FILE_HEADER)pFileBuffer;        //获取标准PE头
        pFileBuffer = pFileBuffer + 0x14;        //偏移到可选PE头
        OptionalHeader = (_PIMAGE_OPTIONAL_HEADER)pFileBuffer;        //获取可选PE头
        pFileBuffer = pFileBuffer + FileHeader->SizeOfOptionalHeader;        //偏移到节表
        pSectionHeader = (_PIMAGE_SECTION_HEADER)pFileBuffer;        //获取节表

        fclose(fp);
        return FileSize;
}

//获取对齐后的值
int Align(int Value,int align)
{
        if(Value % align == 0)
        {
                return Value;
        }
        return ((Value / align) + 1) * align;
}

//RVA->FOA
DWORD RvaToFoa(DWORD dwRva)
{
        DWORD dwFoa = 0;

        //判断是否在头+节表中
        if(dwRva <= OptionalHeader->SizeOfHeaders)
        {
                dwFoa = dwRva;
                return dwFoa;
        }
        
        //判断在是否在节中
        int i;
        for(i = 0; i < FileHeader->NumberOfSections; i++)
        {
                if(dwRva >= pSectionHeader[i].VirtualAddress && dwRva <= (pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData))
                {
                        dwFoa = dwRva - pSectionHeader[i].VirtualAddress;
                        return dwFoa + pSectionHeader[i].PointerToRawData;
                }
        }
}

//FOA->RVA
DWORD FoaToRva(DWORD dwFoa)
{
        DWORD dwRva = 0;

        //判断是否在头+节表中
        if(dwFoa <= OptionalHeader->SizeOfHeaders)
        {
                dwRva = dwFoa;
                return dwRva;
        }
        
        //判断是否在节中
        int i = 0;
        for(i = 0; i < FileHeader->NumberOfSections; i++)
        {
                if(dwFoa >= pSectionHeader[i].PointerToRawData && dwFoa <= (pSectionHeader[i].PointerToRawData + pSectionHeader[i].SizeOfRawData))
                {
                        dwRva = dwFoa - pSectionHeader[i].PointerToRawData;
                        return dwRva + pSectionHeader[i].VirtualAddress;
                }
        }
}

// 存盘
STAUS SaveData(PBYTE buffer,STR Path,size_t FileSize)
{
        FILE* fp = fopen(Path,"wb+");
        if(!fp)
        {
                printf("文件打开失败\n");
                return FALSE;
        }

        //写入文件
        if(!fwrite(buffer,FileSize,1,fp))
        {
                printf("文件写入失败!\n");
                return FALSE;
        }

        fclose(fp);
        return TRUE;
}

//提升所有头+节表
STAUS PromoteHeaders(PBYTE FileBuffer)
{
        PBYTE pFileBuffer = FileBuffer;
        DWORD SizeOfCopy = (DWORD)(&pSectionHeader[FileHeader->NumberOfSections]) - (DWORD)(FileBuffer + DosHeader->e_lfanew);
        DWORD FillSize = (DWORD)(&pSectionHeader[FileHeader->NumberOfSections]) - (DWORD)FileBuffer - 0x40 - SizeOfCopy;
        //拷贝所有头+节表
        for(DWORD i = 0; i < SizeOfCopy; i++)
        {
                (FileBuffer + 0x40)[i] = (FileBuffer + DosHeader->e_lfanew)[i];
        }
        //填充
        memset((FileBuffer + 0x40 + SizeOfCopy),0x0,FillSize);
        //修正e_lfanew
        DosHeader->e_lfanew = 0x40;
        //重新修正所有头+节表指针
        pFileBuffer = pFileBuffer + DosHeader->e_lfanew;        //偏移到NT头
        NtHeader = (_PIMAGE_NT_HEADER)pFileBuffer;        //获取NT头
        pFileBuffer = pFileBuffer + 0x4;        //偏移到标准PE头
        FileHeader = (_PIMAGE_FILE_HEADER)pFileBuffer;        //获取标准PE头
        pFileBuffer = pFileBuffer + 0x14;        //偏移到可选PE头
        OptionalHeader = (_PIMAGE_OPTIONAL_HEADER)pFileBuffer;        //获取可选PE头
        pFileBuffer = pFileBuffer + FileHeader->SizeOfOptionalHeader;        //偏移到节表
        pSectionHeader = (_PIMAGE_SECTION_HEADER)pFileBuffer;        //获取节表
        return TRUE;
}

//新增节
STAUS AddSectionPlus(PBYTE FileBuffer,PBYTE* NewBuffer,size_t FileSize)
{
        //申请一块新的FileBuffer
        *NewBuffer = (BYTE*)malloc(FileSize + SizeOfNewSection);
        memset(*NewBuffer,0x0,SizeOfNewSection + FileSize);
        //把原来的内容拷贝过来
        for(int i = 0; i < FileSize; i++)
                (*NewBuffer)[i] = FileBuffer[i];
        //更新所有指针
        PBYTE pNewBuffer = *NewBuffer;
        DosHeader = (_PIMAGE_DOS_HEADER)pNewBuffer;        //获取DOS头
        pNewBuffer = pNewBuffer + DosHeader->e_lfanew;        //偏移到NT头
        NtHeader = (_PIMAGE_NT_HEADER)pNewBuffer;        //获取NT头
        pNewBuffer = pNewBuffer + 0x4;        //偏移到标准PE头
        FileHeader = (_PIMAGE_FILE_HEADER)pNewBuffer;        //获取标准PE头
        pNewBuffer = pNewBuffer + 0x14;        //偏移到可选PE头
        OptionalHeader = (_PIMAGE_OPTIONAL_HEADER)pNewBuffer;        //获取可选PE头
        pNewBuffer = pNewBuffer + FileHeader->SizeOfOptionalHeader;        //偏移到节表
        pSectionHeader = (_PIMAGE_SECTION_HEADER)pNewBuffer;        //获取节表
        //判断节表空间是否充足
        if( OptionalHeader->SizeOfHeaders - (DWORD)(&(pSectionHeader[FileHeader->NumberOfSections]) - (DWORD)(*NewBuffer)) < 0x50 )
        {
                printf("节表空间不足!\n");
                PromoteHeaders(*NewBuffer);        //提升所有头+节表
        }
        //偏移到要添加节表的位置
        pNewBuffer = *NewBuffer + (DWORD)(&pSectionHeader[FileHeader->NumberOfSections]) - (DWORD)(*NewBuffer);
        //后面填充一个全0结构
        memset(pNewBuffer + 0x28,0x0,0x28);
        //设置节表内容
        for(int i = 0; i< strlen((char*)NewSectionName); i++)        //设置节表名字
                ((PBYTE)((_PIMAGE_SECTION_HEADER)pNewBuffer)->Name)[i] = NewSectionName[i];
        ((PBYTE)((_PIMAGE_SECTION_HEADER)pNewBuffer)->Name)[strlen((char*)NewSectionName)] = 0x0;
        ((_PIMAGE_SECTION_HEADER)pNewBuffer)->Misc.VirtualSize = (DWORD)SizeOfNewSection;        //设置内存中大小
        DWORD MaxSize = pSectionHeader[FileHeader->NumberOfSections - 1].SizeOfRawData > pSectionHeader[FileHeader->NumberOfSections - 1].Misc.VirtualSize ? 
                pSectionHeader[FileHeader->NumberOfSections - 1].SizeOfRawData : pSectionHeader[FileHeader->NumberOfSections - 1].Misc.VirtualSize;
        DWORD SizeOfData = Align(MaxSize,OptionalHeader->SectionAlignment);
        ((_PIMAGE_SECTION_HEADER)pNewBuffer)->VirtualAddress = pSectionHeader[FileHeader->NumberOfSections - 1].VirtualAddress + SizeOfData;        //设置内存中偏移
        ((_PIMAGE_SECTION_HEADER)pNewBuffer)->SizeOfRawData = SizeOfNewSection;        //设置文件中大小
        ((_PIMAGE_SECTION_HEADER)pNewBuffer)->PointerToRawData = pSectionHeader[FileHeader->NumberOfSections - 1].PointerToRawData + SizeOfData;        //设置文件中偏移
        for(int i = 0; i < FileHeader->NumberOfSections - 1; i++)
        {
                ((_PIMAGE_SECTION_HEADER)pNewBuffer)->Characteristics = ((_PIMAGE_SECTION_HEADER)pNewBuffer)->Characteristics | pSectionHeader[i].Characteristics;        //设置属性
        }
        //修改节表的数量
        FileHeader->NumberOfSections++;
        //设置节的内容
        memset(*NewBuffer + pSectionHeader[FileHeader->NumberOfSections - 1].PointerToRawData,0x7,SizeOfNewSection);
        //修改SizeOfImage
        OptionalHeader->SizeOfImage = OptionalHeader->SizeOfImage + SizeOfNewSection;
        return TRUE;
}

//取字符串长度(不包括0)
int strlen(char* s)
{
        int ret = 0;
        while(*s++) ret++;
        return ret;
}        

//导入表注入
STAUS ImportInject()
{
        int flag = 1;        //标记所有导入表结束
        int sum = 0;        //统计DLL个数时候用
        PBYTE pTemp = NULL;                //游走指针
        PBYTE poTemp = NULL;
        PBYTE BeginOfNewSection = NULL;        //新增节开始位置
        PBYTE BeginOfINT = NULL;        //INT表开始位置
        PBYTE BeginOfImportName = NULL;        //名字导入结构开始位置
        PBYTE BeginOfDLLName = NULL;        //DLL名字开始位置
        DWORD NewBeginAddr = 0;                //保存新节开始位置
        int NumberOfImport = 0;                //记录原来的导入表个数
        
        //加载PE文件
        PBYTE FileBuffer = NULL;
        PBYTE NewBuffer = NULL;
        size_t FileSize = LoadPE(InPutPath,&FileBuffer);
        if( !FileSize )
        {
                printf("加载PE文件失败!\n");
                return FALSE;
        }
        //统计一共有多少个DLL
        pTemp = (PBYTE)(RvaToFoa(OptionalHeader->DataDirectory[1].VirtualAddress) + (DWORD)FileBuffer);
        while(flag)
        {
                flag = 0;
                //判断导入表结束
                for(int j = 0; j < sizeof(_IMAGE_IMPORT_DESCRIPTOR); j++)
                {
                        if(  ((PBYTE)pTemp)[j] != 0 )
                        {
                                flag = 1;
                                break;
                        }
                }
                if( sum == 0x14 )
                {
                        NumberOfImport++;
                        sum = 0;
                }
                sum++;
                pTemp++;
        }
        //新增一个节
        if( !AddSectionPlus(FileBuffer , &NewBuffer , FileSize) )
        {
                printf("新增节失败!\n");
                return FALSE;
        }
        BeginOfNewSection = NewBuffer + pSectionHeader[FileHeader->NumberOfSections - 1].PointerToRawData;        //获取新增节开始位置
        //获取导入表指针
        pImportDesriptor = (_PIMAGE_IMPORT_DESCRIPTOR)(RvaToFoa(OptionalHeader->DataDirectory[1].VirtualAddress) + (DWORD)NewBuffer);
        pTemp = (PBYTE)BeginOfNewSection;
        //先拷贝DLL名字
        BeginOfDLLName = pTemp;
        for(int i = 0; i < strlen((char*)DllName); i++)
        {
                *(pTemp + i) = DllName[i];
        }
        *(pTemp + strlen((char*)DllName)) = 0x0;
        //再拷贝导入名字结构(前俩字节为0)
        pTemp = pTemp + strlen((char*)DllName) + 0x1;
        BeginOfImportName = pTemp;
        *((PWORD)pTemp) = 0x0;
        for(int i = 0; i < strlen((char*)ImportFunName); i++)
        {
                *(pTemp + 0x2 + i) = ImportFunName[i];
        }
        *(pTemp + 0x2 + strlen((char*)ImportFunName)) = 0x0;
        //再拷贝INT表和IAT表所指向的那个结构
        pTemp = pTemp + strlen((char*)ImportFunName) + 0x2 + 0x1;
        BeginOfINT = pTemp ;
        *((PDWORD)BeginOfINT) = FoaToRva( (DWORD)BeginOfImportName - (DWORD)NewBuffer);        //指向名字导出位置
        *((PDWORD)BeginOfINT + 1) = 0x0;        //后四个字节为0
        //再拷贝原导入表到新增节
        pTemp = pTemp + 0x8;
        NewBeginAddr = (DWORD)pTemp;
        for(int i = 0; i < (NumberOfImport + 2) * 0x14; i++)
        {
                pTemp[i] = ((PBYTE)pImportDesriptor)[i];
        }
        //先把pTemp指针偏移到全0结构
        flag = 1;
        while(flag)
        {
                flag = 0;
                //判断导入表结束
                for(int j = 0; j < sizeof(_IMAGE_IMPORT_DESCRIPTOR); j++)
                {
                        if(  ((PBYTE)pTemp)[j] != 0 )
                        {
                                flag = 1;
                                break;
                        }
                }
                pTemp++;
        }
        //全0结构,后40个字节再补充全0结构
        memset(pTemp + 0x14,0x0,0x14);
        //填充新增导入表
        ((_PIMAGE_IMPORT_DESCRIPTOR)pTemp)->OriginalFirstThunk = FoaToRva( BeginOfINT - NewBuffer );
        ((_PIMAGE_IMPORT_DESCRIPTOR)pTemp)->TimeDateStamp = 0x0;        
        ((_PIMAGE_IMPORT_DESCRIPTOR)pTemp)->ForwarderChain = 0x0;        
        ((_PIMAGE_IMPORT_DESCRIPTOR)pTemp)->Name = FoaToRva( BeginOfDLLName - NewBuffer );        
        ((_PIMAGE_IMPORT_DESCRIPTOR)pTemp)->FirstThunk = FoaToRva( BeginOfINT - NewBuffer );
        //修改目录项
        OptionalHeader->DataDirectory[1].VirtualAddress = FoaToRva( (DWORD)NewBeginAddr - (DWORD)NewBuffer );
        //存盘
        SaveData(NewBuffer,OutPutPath,pSectionHeader[FileHeader->NumberOfSections - 1].PointerToRawData + SizeOfNewSection);
        return TRUE;
}

int main(int argc, char* argv[])
{
        if( ImportInject() )
        {
                printf("导入表注入成功!\n");
        }

        getchar();
        return 0;
}

InjectH.h:
[C++] 纯文本查看 复制代码
#include<stdio.h>
#include <stdlib.h>
#include <string.h>

#if !defined(AFX_GLOBE_H__9815AEC8_DF43_478B_8D19_5BAB2B5BD840__INCLUDED_)
#define AFX_GLOBE_H__9815AEC8_DF43_478B_8D19_5BAB2B5BD840__INCLUDED_

#define WORD unsigned short
#define DWORD unsigned int
#define BYTE unsigned char
#define STR char*
#define PWORD unsigned short*
#define PDWORD unsigned int*
#define PBYTE unsigned char*
#define IMAGE_SIZEOF_SHORT_NAME                8
#define STAUS int
#define TRUE 1
#define FALSE 0


//DOS头结构
typedef struct dos
{
        WORD        e_magic;        //MZ标志
        WORD        e_cblp;
        WORD         e_cp;
        WORD         e_crlc;
        WORD         e_cparhdr;
        WORD         e_minalloc;
        WORD         e_maxalloc;
        WORD         e_ss;
        WORD         e_sp;
        WORD         e_csum;        
        WORD         e_ip;
        WORD         e_cs;
        WORD         e_lfarlc;
        WORD         e_ovno;
        WORD         e_res[4];
        WORD         e_oemid;
        WORD         e_oeminfo;
        WORD         e_res2[10];
        DWORD         e_lfanew;        //真正PE起始点
}_IMAGE_DOS_HEADER,*_PIMAGE_DOS_HEADER;

//目录项结构
typedef struct dataDirectory
{
        DWORD VirtualAddress;
        DWORD Size;
}_IMAGE_DATA_DIRECTORY,_PIMAGE_DATA_DIRECTORY;

//标准PE头结构
typedef struct filePE
{
        WORD         Machine;
        WORD        NumberOfSections;
        DWORD        TimeDataStamp;
        DWORD        PointerToSymbolTable;
        DWORD        NumberOfSymbols;
        WORD        SizeOfOptionalHeader;
        WORD        Characteristics;
}_IMAGE_FILE_HEADER,*_PIMAGE_FILE_HEADER;

//可选PE头结构
typedef struct optionalPE
{
        WORD        Magic;
        BYTE        MajrLinkerVersion;
        BYTE        MinorLinkerVersion;
        DWORD        SizeOfCode;
        DWORD        SizeOfInitializedData;
        DWORD        SizeOfUninitializedData;
        DWORD        AddressOfEntryPoint;
        DWORD        BaseOfCode;
        DWORD        BaseOfData;
        DWORD        ImageBase;
        DWORD        SectionAlignment;
        DWORD        FileAlignment;
        WORD        MajorOperatingSystemVersion;
        WORD        MinorOperatingSystemVersion;
        WORD        MajorImageVersion;
        WORD        MinorImageVersion;
        WORD        MajorSubsystemVersion;
        WORD        MinorSubsystemVersion;
        DWORD        Win32VersionValue;
        DWORD        SizeOfImage;
        DWORD        SizeOfHeaders;
        DWORD        CheckSum;
        WORD        Subsystem;
        WORD        DllCharacteristics;
        DWORD        SizeOfStackReserve;
        DWORD        SizeOfStackCommit;
        DWORD        SizeOfHeapReserve;
        DWORD        SizeOfHeapCommit;
        DWORD        LoaderFlags;
        DWORD        NumberOfRvaAndSizes;
        _IMAGE_DATA_DIRECTORY DataDirectory[16];
}_IMAGE_OPTIONAL_HEADER,*_PIMAGE_OPTIONAL_HEADER;

//NT头结构
typedef struct nt
{
        DWORD Signature;
        _IMAGE_FILE_HEADER FileHeader;
        _IMAGE_OPTIONAL_HEADER OptionalHeader;
        
}_IMAGE_NT_HEADER,*_PIMAGE_NT_HEADER;

//节表结构
typedef struct section
{                                        
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];                                        
    union {                                        
            DWORD   PhysicalAddress;                                        
            DWORD   VirtualSize;                                        
    } Misc;                                        
    DWORD   VirtualAddress;                                        
    DWORD   SizeOfRawData;                                        
    DWORD   PointerToRawData;                                        
    DWORD   PointerToRelocations;                                        
    DWORD   PointerToLinenumbers;                                        
    WORD    NumberOfRelocations;                                        
    WORD    NumberOfLinenumbers;                                        
    DWORD   Characteristics;                                        
}_IMAGE_SECTION_HEADER, *_PIMAGE_SECTION_HEADER;

//导入表结构
typedef struct import_descriptor {                                
    union {                                
        DWORD   Characteristics;                                           
        DWORD   OriginalFirstThunk;                                         
    };                                
    DWORD   TimeDateStamp;                                               
    DWORD   ForwarderChain;                                              
    DWORD   Name;                                
    DWORD   FirstThunk;                                                 
}_IMAGE_IMPORT_DESCRIPTOR,*_PIMAGE_IMPORT_DESCRIPTOR;                

//函数以名字导出结构
typedef struct import_by_name {                                        
    WORD    Hint;                                        
    BYTE    Name[1];                                        
}_IMAGE_IMPORT_BY_NAME, *_PIMAGE_IMPORT_BY_NAME;                                                                                        

#endif // !defined(AFX_GLOBE_H__9815AEC8_DF43_478B_8D19_5BAB2B5BD840__INCLUDED_)


4.用到的DLL:


                链接:https://pan.baidu.com/s/10eJc1cTJa2GPZ23aPt1-GQ
                 提取码:ru18

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2021-2-23 15:03
I D:存钱买板子
邮箱:yuan6900956@163.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。
存钱买板子 发表于 2021-2-24 09:24
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-10 02:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表