Skip to content

Latest commit

 

History

History
415 lines (365 loc) · 13.3 KB

pppoe.md

File metadata and controls

415 lines (365 loc) · 13.3 KB

PPPOE

先给出反编译出来的结果

//----- (0805E52B) --------------------------------------------------------
int __usercall DrcomDialExtProtoSendLoginPacket<eax>(int a1<esi>)
{
  int v1; // edi@1
  int v2; // edi@1
  char v3; // dl@1
  int v4; // eax@1
  int v5; // eax@1
  int v6; // eax@1
  int v7; // eax@1
  int v8; // eax@3
  int v9; // edx@6
  int v10; // eax@6
  int v11; // edx@10
  int v12; // eax@12
  int v13; // eax@16
  int v14; // ebx@17
  int v15; // eax@17
  int v16; // edx@18
  int v17; // ebx@18
  int v18; // eax@18
  int v19; // eax@19
  char v21; // [sp+4h] [bp-244h]@19
  int v22; // [sp+18h] [bp-230h]@12
  char v23; // [sp+28h] [bp-220h]@1
  int v24; // [sp+48h] [bp-200h]@1
  int v25; // [sp+228h] [bp-20h]@1
  int *v26; // [sp+22Ch] [bp-1Ch]@1
  unsigned __int8 v27; // [sp+233h] [bp-15h]@1
  unsigned int i; // [sp+234h] [bp-14h]@21
  int *v29; // [sp+238h] [bp-10h]@21

  v25 = (int)&v23;
  v26 = &v24;
  v27 = DRCOM_CLIENT_KERNEL_VER;
  memset(&v23, 0, 0x200u);
  v1 = v25;
  memset((void *)v25, 0, 0x20u);
  v2 = v1 + 32;
  *(_BYTE *)v25 = 7;
  v3 = as[160];
  *(_BYTE *)(v25 + 1) = as[160];
  as[160] = v3 + 1;
  *(_BYTE *)(v25 + 4) = 3;
  v4 = v25 + 6;
  *(_DWORD *)(v25 + 6) = 0;
  *(_WORD *)(v4 + 4) = 0;
  *(_DWORD *)(v25 + 12) = *(_DWORD *)&as[204];
  *(_DWORD *)(v25 + 16) = 512;
  *(_DWORD *)(v25 + 20) = *(_DWORD *)&as[164];
  *(_DWORD *)(v25 + 24) = 20000711;
  *(_DWORD *)(v25 + 28) = 126;
  *(_BYTE *)(v25 + 5) = 0;
  *(_WORD *)(v25 + 2) = *(_BYTE *)(v25 + 5) + 96;
  v5 = (int)((char *)v26 + *(_BYTE *)(v25 + 5));
  *(_DWORD *)v5 = *(_DWORD *)&as[576];
  *(_DWORD *)(v5 + 4) = *(_DWORD *)&as[580];
  *(_DWORD *)(v5 + 8) = *(_DWORD *)&as[584];
  *(_DWORD *)(v5 + 12) = *(_DWORD *)&as[588];
  *(_DWORD *)(v5 + 16) = *(_DWORD *)&as[592];
  *(_DWORD *)(v5 + 20) = *(_DWORD *)&as[596];
  *(_DWORD *)(v5 + 24) = *(_DWORD *)&as[600];
  *(_DWORD *)(v5 + 28) = *(_DWORD *)&as[604];
  *(_DWORD *)(v5 + 32) = *(_DWORD *)&as[608];
  *(_DWORD *)(v5 + 36) = *(_DWORD *)&as[612];
  *(_DWORD *)(v5 + 40) = *(_DWORD *)&as[616];
  *(_DWORD *)(v5 + 44) = *(_DWORD *)&as[620];
  *(_DWORD *)(v5 + 48) = *(_DWORD *)&as[624];
  *(_DWORD *)(v5 + 52) = *(_DWORD *)&as[628];
  *(_DWORD *)(v5 + 56) = *(_DWORD *)&as[632];
  *(_DWORD *)(v5 + 60) = *(_DWORD *)&as[636];
  AntiProxyModule_Call(v2, a1, 9);
  v6 = *(_DWORD *)&drcfg[304];
  DebugMessage(
    (unsigned int)"IS_CONFIG_PPPOE_USE_DRCOM_966_SERVER=%d\nas.DrcomPPPoEAuthRetry966Kern=%d\nAntiProxyModule_Call(DRCOMDLL_CHECK_IS_LOADED)=%d\n",
    (v6 & 0x40000) != 0);
  v7 = *(_DWORD *)&drcfg[304];
  if ( (v7 & 0x40000 || *(_DWORD *)&as[680]) && ((v8 = *(_DWORD *)&drcfg[304], !(v8 & 0x40000)) || !*(_DWORD *)&as[680])
    || AntiProxyModule_Call(v2, a1, 9) != 541283667 )
  {
    *(_DWORD *)(v25 + 16) += v27 << 24;
  }
  else
  {
    v9 = *(_DWORD *)(v25 + 16);
    BYTE1(v9) |= 0x62u;
    *(_DWORD *)(v25 + 16) = v9;
    v10 = *(_DWORD *)&drcfg[304];
    if ( !(v10 & 0x80000) )
      *(_DWORD *)(v25 + 16) += v27 << 24;
  }
  if ( *(_DWORD *)&as[676] )
  {
    v11 = *(_DWORD *)(v25 + 16);
    BYTE1(v11) |= 0x80u;
    *(_DWORD *)(v25 + 16) = v11;
  }
  if ( *(_DWORD *)&as[676] <= 5u )
  {
    DebugMessage((unsigned int)"as.IsDrcomDialConnectionFirstActive=%d\n", as[668]);
    if ( *(_DWORD *)&as[668] && *(_DWORD *)&as[672] )
    {
      *(_DWORD *)(v25 + 16) = *(_DWORD *)(v25 + 16);
      if ( !*(_DWORD *)&as[552] )
      {
        v13 = drlang_get_lang((int)&unk_80FCFD4);
        SendMessageToUI(a1, (int)"STM ", v13);
      }
      v14 = *(_DWORD *)(v25 + 16);
      v15 = drlang_get_lang((int)"Dr.COM PPPoE start connect %08X.");
      DebugMessage(v15, v14);
    }
    else
    {
      v16 = *(_DWORD *)(v25 + 16);
      BYTE1(v16) |= 1u;
      *(_DWORD *)(v25 + 16) = v16;
      v17 = *(_DWORD *)(v25 + 16);
      v18 = drlang_get_lang((int)"Dr.COM PPPoE start onlineing %08X.");
      DebugMessage(v18, v17);
    }
    *(_WORD *)(v25 + 2) = 4 * (*(_WORD *)(v25 + 2) + 3) / 4;
    v19 = DrcomCRC32(0, v25, *(_WORD *)(v25 + 2));
    *(_DWORD *)(v25 + 24) = 19680126 * v19;
    *(_DWORD *)(v25 + 28) = 0;
    *(_DWORD *)&as[656] = *(_DWORD *)(v25 + 24);
    if ( *(_DWORD *)&as[668] == 1 )
      *(_DWORD *)&as[660] = *(_DWORD *)(v25 + 24);
    i = 0;
    v29 = (int *)((char *)v26 + *(_BYTE *)(v25 + 5));
    // 下面一段是CRC
    for ( i = 0; i <= 0x3F; ++i )
    {
      a1 = (int)((char *)v29 + i);
      v2 = *((_BYTE *)v29 + i) << (i & 7);
      *((_BYTE *)v29 + i) = v2 + ((signed int)*((_BYTE *)v29 + i) >> (8 - (i & 7)));
    }
    *(_DWORD *)&as[548] = 4;
    *(_DWORD *)&as[24] = 503;
    if ( GetUserStatus(2048) )
      SetUserStatus(512);
    DebugMessage((unsigned int)"Drcom  Dial Ext Proto plugin Send Login CMD.\n", v21);
    v22 = SendAuthCmd(v2, a1);
  }
  else
  {
    v12 = drlang_get_lang((int)&unk_80FCF6C);
    SendMessageToUI(a1, (int)"SYM ERR ", v12);
    v22 = 542265925;
  }
  return v22;
}

再给出某代码:

/*
 * 第3步,发送认证数据
 */
int DrppoePlugin::DrcomDialExtProtoSendLoginPacket() {
	showLog("jni.DrppoePlugin::DrcomDialExtProtoSendChallenge", "第3步,发送认证数据命令...");
	m_SetpCurrent = SetpSendLogin;
    char drcom_dial_ext_login_buff[512];
    unsigned char aChallenge[SEED_LEN];
    bool bIsCrcCheckHandle = false;

    struct _tagDrcomDialExtProtoLoginPacket* drcom_dial_ext_login
        = (struct _tagDrcomDialExtProtoLoginPacket *)drcom_dial_ext_login_buff;

    unsigned char* ptrExtInfoStart = (unsigned char*)(drcom_dial_ext_login_buff + sizeof(struct _tagDrcomDialExtProtoLoginPacket));
    unsigned char ClientCurrVer = m_sDRCOM_CLIENT_KERNEL_VER;

    bzero(drcom_dial_ext_login_buff, sizeof(drcom_dial_ext_login_buff));

    drcom_dial_ext_login->hcode = AUTH_CODE_PPPOE;
    drcom_dial_ext_login->hid =  m_iChallengeID++;
    drcom_dial_ext_login->htype = AUTH_CODE_TYPE_PPPOE_LOGIN;
    memset(drcom_dial_ext_login->mac, 0, 6);
    drcom_dial_ext_login->sip = m_AuthHostIP;
    drcom_dial_ext_login->option = DRCOM_DIAL_PROTO_OPT_DEFAULT;     //2006-9-1      //0;

    // fgx 2013-03-29 修改第三步的校验方式
    memcpy(drcom_dial_ext_login->ChallengeSeed, m_sChallengeSeed, SEED_LEN);
    bIsCrcCheckHandle = GetCrcCheckField(m_sChallengeSeed, SEED_LEN, m_cEncryptionMode, drcom_dial_ext_login->crc, NULL);

    //us.Accout[0] = 0x00;
    drcom_dial_ext_login->uidlength = 0;//strlen(us.Account);
    drcom_dial_ext_login->hlength = sizeof(struct _tagDrcomDialExtProtoLoginPacket)
                                    + drcom_dial_ext_login->uidlength
                                    + sizeof(struct _tagDrcom8021XExtProtoNetWorkInfo) * MAX_DRCOM_8021X_EXT_PROTO_NET_NUM;

    // add by fgx 2012-07-20
    // 修复上传了 169.254 IP段的问题
    void *temp = NULL;
    {

        struct _tagDrcom8021XExtProtoNetWorkInfo* pNewWorkInfo
            = (struct _tagDrcom8021XExtProtoNetWorkInfo*)ptrExtInfoStart + drcom_dial_ext_login->uidlength;
        showLog("qqqq", "pNewWorkInfo1:%p", pNewWorkInfo);
        for (int index = 0; index < MAX_DRCOM_DIAL_EXT_PROTO_NET_NUM; index++)
        {
            if (!is_dhcp_169_ip_addr(m_DrcomDialExtProtoNetInfo[index].sip))
            {
                memcpy(pNewWorkInfo, m_DrcomDialExtProtoNetInfo + index, sizeof(struct _tagDrcomDialExtProtoNetWorkInfo));
                pNewWorkInfo++;
            }
            if(index == 0) {
            	temp = (void *)pNewWorkInfo;
            	temp = temp + 6;
            	showLog("qqqq", "pNewWorkInfo2:%p temp:%p", pNewWorkInfo, temp);
            }
        }

    }

    if(1) {
    	drcom_dial_ext_login->option = drcom_dial_ext_login->option | DRCOM_DIAL_PROTO_OPT_DRCOMDLL_CHECK;
    	if(1) {
    		// 大部分内核版本需要上传版本号,只有少数不需要
    		drcom_dial_ext_login->option = drcom_dial_ext_login->option
    	                                           + (DRCOM_DIAL_PROTO_OPT_ANTI_CLIENT_VER * ClientCurrVer);
    	}
    }
    else {
        drcom_dial_ext_login->option = drcom_dial_ext_login->option
                                       + (DRCOM_DIAL_PROTO_OPT_ANTI_CLIENT_VER * ClientCurrVer);
    }

    if (m_uiAntiProxyResault != 0x00) //2007-11-22
    {
        // pppoe发现代理网关将其踢下线
        drcom_dial_ext_login->option = drcom_dial_ext_login->option | DRCOM_DIAL_PROTO_OPT_ANTI_PROXY_OFFLINE;
    }

    if (m_uiAntiProxyResault > 5)
    {
    	// 请停止使用路由器或代理软件上网,并重新登录,谢谢合作!!!
        return DRCOM_ERR;
    }

    if (m_bIsFirstTimeConnect) {
    	drcom_dial_ext_login->option = drcom_dial_ext_login->option | DRCOM_DIAL_PROTO_OPT_CONNECTION_START;
    	drcom_dial_ext_login->option = 0x1d006200;
    }
    else {
    	drcom_dial_ext_login->option = drcom_dial_ext_login->option | DRCOM_DIAL_PROTO_OPT_CONNECTION_ONLINEING;
    	drcom_dial_ext_login->option = 0x1d006300;
    }

    if (!bIsCrcCheckHandle){
        // 旧版本
        drcom_dial_ext_login->hlength = ((drcom_dial_ext_login->hlength + 3) / 4) * 4;
        drcom_dial_ext_login->crc[0] = DRCOM_DIAL_EXT_PROTO_CRC_CONST *
                                       DrcomCRC32(0, (unsigned char*)drcom_dial_ext_login, drcom_dial_ext_login->hlength);
        drcom_dial_ext_login->crc[1] = 0;
    }

    m_ulDrcomDialExtProtoAuthLastCRC = drcom_dial_ext_login->crc[0];

    if (m_iIsDrcomDialConnectionFirstActive == 0x01) {
    	m_iDrcomDialExtProtoActiveCRC = drcom_dial_ext_login->crc[0];
    }

	int index = 0;
	unsigned char* pcrcstart = (unsigned char*)(ptrExtInfoStart + drcom_dial_ext_login->uidlength); //&drcom_dial_ext_login->netinfo;

	int pcrcLen = (sizeof(struct _tagDrcomDialExtProtoNetWorkInfo) * MAX_DRCOM_DIAL_EXT_PROTO_NET_NUM);
	string log = Arithmetic::AsciiToHexWithSep((const char*)pcrcstart, pcrcLen);
	showLog("jni.DrppoePlugin::DrcomDialExtProtoSendChallenge", "pcrcstart:(%d)加密前 Hex编码:\n%s", pcrcLen, log.c_str());


	for (index = 0; index < pcrcLen; index++)
	{
		pcrcstart[index] =
			(unsigned char)((pcrcstart[index] << (index & 0x07))
							+ (pcrcstart[index] >> (8 - (index & 0x07))));
	}

	log = Arithmetic::AsciiToHexWithSep((const char*)pcrcstart, pcrcLen);
	showLog("jni.DrppoePlugin::DrcomDialExtProtoSendChallenge", "pcrcstart:(%d)加密后 Hex编码:\n%s", pcrcLen, log.c_str());

	if(NULL !=  temp) {
	    char a = 0x40;
	    memcpy((void *)temp, &a, sizeof(a));
	}

	// 正在向服务器确认IP地址,请稍后.....
    return SendAuthCmd((char *)drcom_dial_ext_login, drcom_dial_ext_login->hlength);
}

以下是某代码的头文件

typedef struct _tagDrcomDialExtProtoHeader
{
    unsigned char code;
    unsigned char id;
    unsigned short length;
    unsigned char type;
} PPPOEHEADER;

发起认证请求:

typedef struct _tagDrcomDialExtProtoChallenge {
    PPPOEHEADER header;
    unsigned char other[3];

#define hcode   header.code     //=7
#define hid     header.id
#define hlength header.length
#define htype   header.type     //=1

#ifdef DRCOM_ENCRYPT_PROTO
    unsigned char unused[12];
    unsigned char encrypt_info[32];
#endif
} PPPOECHALLENGE;
#define _tagDrcom8021XExtProtoChallenge _tagDrcomDialExtProtoChallenge

回应请求:

struct _tagDrcomDialExtProtoReturnChallenge {
    PPPOEHEADER header;

#define hcode   header.code     //=7
#define hid     header.id
#define hlength header.length
#define htype   header.type     //=2
    unsigned char other[3];
    unsigned char challenge[SEED_LEN];

#ifdef DRCOM_ENCRYPT_PROTO
unsigned char unused[20+48];
unsigned char encrypt_info[32];
#endif
};

附加网络信息部分:

#define  _tagDrcom8021XExtProtoReturnChallenge _tagDrcomDialExtProtoReturnChallenge
#define MAX_DRCOM_DIAL_EXT_PROTO_NET_NUM 4
#define MAX_DRCOM_8021X_EXT_PROTO_NET_NUM MAX_DRCOM_DIAL_EXT_PROTO_NET_NUM
#define USE_LIMIT_IP (unsigned long)(169+254*256)

struct _tagDrcomDialExtProtoNetWorkInfo
{
    unsigned char mac[6];
    unsigned char netmark;      //dhcp mark
    unsigned char type;     //interface type(ether,ppp)
    unsigned long sip;
    unsigned long smask;
    //ULONG gateway1;
};

#define _tagDrcom8021XExtProtoNetWorkInfo _tagDrcomDialExtProtoNetWorkInfo

发起认证:

struct _tagDrcomDialExtProtoLoginPacket {
    PPPOEHEADER header; // 5 byte

#define hcode   header.code     // PPPoE ext = 0x07
#define hid     header.id		// 自定义,每次不同就可以
#define hlength header.length	// 发送数据包的长度
#define htype   header.type     // PPPoE = 0x03

    unsigned char uidlength;
    unsigned char mac[6];
    unsigned long sip;
    unsigned long option;   //bit0=dhcp, bit1=请求封装, bit2-7(verno)
    //b8=(no first),b9=有tcpipdog.dll, b10-12 选择出口线路 2006-12-18
    //b13(mydll mark2007-2-28), bit14-31 unuse
    //b14(mydll mark b15=find proxy cut line (pppoe模式2007-11-22)
    //bit16-31 unuse

    unsigned char ChallengeSeed[SEED_LEN];
    unsigned long crc[2];

    //account ,len 0
    //struct _tagDrcomDialExtProtoNetWorkInfo netinfo[MAX_DRCOM_DIAL_EXT_PROTO_NET_NUM];
    //unsigned char unused[4];
};

#define _tagDrcom8021XExtProtoLoginPacket _tagDrcomDialExtProtoLoginPacket

认证结果

struct _tagDrcomDialExtProtoLoginResult {
    PPPOEHEADER header;

#define hcode   header.code     //=7
#define hid     header.id
#define hlength header.length
#define htype   header.type     //4=dvpntable, 6=ping return

    unsigned char   pingsec;
    unsigned short  infolength;
    unsigned long   crc[2];  //type==4 crc[1]=0x01,允许代理 ,kernel
};