亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 360antiarp.c

?? 別人逆的居然還有字數限制
?? C
?? 第 1 頁 / 共 3 頁
字號:
	return 0x10001;

quit_hook2:
	
	return ((ARP_RCV_INDICATION_NEW)_ulB)(Handle, Context, Header, HeaderSize,
											Data, DataSize, TotalSize, Unknow1, Unknow2);
}

///////////////////////////////////////////////////////////////////////////////
// Hook: NdisRegisterProtocol

VOID
	HookProc (PNDIS_STATUS Status, PNDIS_HANDLE Handle, 
				PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics, 
				UINT CharacteristicsLength)
{
	UCHAR * p, * pMax;
	ULONG ul;
	KIRQL OldIrql;
	
	p = (UCHAR *)ProtocolCharacteristics->SendCompleteHandler;
	
	if ( !MmIsAddressValid (p) )
		goto quit_hook;
	
	if ((ULONG)p < _ul7)
		goto quit_hook;
	
	if ((ULONG)p > (_ul7+_ul8))
		goto quit_hook;
	
	pMax = p + 0x80;
	for (; p<pMax; p++) {
		if (!MmIsAddressValid(p) || (*p!=0xE8)) continue;
		
		ul = *(PULONG)(p+1);	// get call offset
		ul += (ULONG)p+5;		// goto subproc entry point
		_ulB = ul;
		
		if (!MmIsAddressValid((PVOID)ul)) continue;
		if (_ulB > _ul7) {
			if (_ulB < (_ul7+_ul8)) break;
		}
		
		_ulB = 0;
	}
	
	if (_ulB) {
		KeAcquireSpinLock (&_SpinLock, &OldIrql);
		DisableWriteProtect ();
		
		// Hook & Hook again!
		*(PULONG)(p+1) = (ULONG)HookProc2 - (ULONG)p - 5;
		
		EnableWriteProtect();
		
		KeReleaseSpinLock (&_SpinLock, OldIrql);
		
		p = (UCHAR *)ProtocolCharacteristics->ReceivePacketHandler;
		if (MmIsAddressValid(p)) {
			pMax = p + 0x100;
			
			if (p<pMax) {
			
				for (; p<pMax; p++) {
					if (!MmIsAddressValid(p) || *p!= 0xE8) continue;
					ul = *(PULONG)(p+1);
					ul += (ULONG)p+5;
					
					if (ul == _ulB) break;
				}
				
				KeAcquireSpinLock (&_SpinLock, &OldIrql);
				DisableWriteProtect();
				
				// Hook, Hook & Hook again!!!
				*(PULONG)(p+1) = (ULONG)HookProc2 - (ULONG)p - 5;
				
				EnableWriteProtect();
				
				KeReleaseSpinLock (&_SpinLock, OldIrql);
			}
		}
	}
	// para_1
	_ulA = (ULONG)ExAllocatePool (NonPagedPool, 0x1000);
	_ul9 = 0;
	memset ((PVOID)_ulA, 0, 0x1000);
	
	_ulC = (ULONG)ExAllocatePool (NonPagedPool, 0x6);
	memset ((PVOID)_ulC, 0, 0x6);
	
	if (!MmIsAddressValid ((PVOID)_ul4))
		goto quit_hook;
	
	if (!MmIsAddressValid ((PVOID)_ul6))
		goto quit_hook;
	
	KeAcquireSpinLock (&_SpinLock, &OldIrql);
	DisableWriteProtect();
	*(PULONG)_ul4 = _ul6;
	DisableWriteProtect();
	KeReleaseSpinLock (&_SpinLock, OldIrql);
	
quit_hook:
	((NDIS_REGISTER_PROTOCOL)_ul6)(Status, Handle, ProtocolCharacteristics, 
										CharacteristicsLength);
}




VOID
	MyLoadImageNotifyProc (PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
{
	UCHAR sModuleName[0x0C];
	UCHAR sFunctionName[0x18];
	WCHAR wsBuffer[0x208];
	ULONG vul1, vul2;
	UNICODE_STRING usModPath;
	PUNICODE_STRING pusFullImageName;
	
	KIRQL oldIrql;
	memcpy (sFunctionName, _FunctionName, strlen(_FunctionName));
	memcpy (sModuleName, _Mod1Name, strlen(_Mod1Name));
	
	pusFullImageName = FullImageName;
	
	if (_ul2) return;
	if ((ULONG)ImageInfo->ImageBase < (ULONG)MmUserProbeAddress) return;
	if (!MmIsAddressValid(FullImageName->Buffer)) return;
	
	wcscpy (wsBuffer, pusFullImageName->Buffer);
	if (!wcsstr (_wcsupr(wsBuffer), _Mod2Name)) return;
	
	if ((ImageInfo->ImageBase == NULL) || (ImageInfo->ImageSize == 0)) return;
	
	RtlInitUnicodeString (&usModPath, _ModPath);
	if (!SeekTargetAPI(sFunctionName, sModuleName, &usModPath, &vul1, &vul2)) return;
	
	_ul4 = (ULONG)ImageInfo->ImageBase + vul1*4 + vul2;
	if (!MmIsAddressValid((PVOID)_ul4)) return;
	
	_ul6 = *(PULONG)_ul4;
	KeAcquireSpinLock (&_SpinLock, &oldIrql);
	DisableWriteProtect ();
	*(PULONG)_ul4 = (ULONG)HookProc;
	
	EnableWriteProtect();
	
	KeReleaseSpinLock (&_SpinLock, oldIrql);
	_ul7 = (ULONG)ImageInfo->ImageBase;
	_ul8 = ImageInfo->ImageSize;
	_ul2 = 1;
}


  int   mystrcmp(UCHAR   *s1,   UCHAR *s2)  
  {  
      UCHAR*   p1;  
      UCHAR*   p2;  
      p1= s1;  
      p2=  s2;  
      while((*p1)&&(*p2))  
      {  
          if(*p1==*p2)  
          {  
              p1++;p2++;  
          }else{  
              return   (*p1-*p2);  
          }  
      }  
      return   (*p1-*p2);  
  }  
 




NTSTATUS
HookWriteDispatch(    
                IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
{
	ARPPACKET  ARPBuffer;
        // DbgPrint("hook success\r\n");
        PIO_STACK_LOCATION        pIocurrentstack;
        PFILE_OBJECT pFileObject;
    NTSTATUS ntStatus;
	PVOID OutputBuffer;
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    PVOID lpInOutBuffer;
    ULONG nInBufferSize, nOutBufferSize, dwIoControlCode;
        DbgPrint("DeviceName:%S\r\n",DeviceObject->DriverObject->DriverName.Buffer);
        
        if(KeGetCurrentIrql() != DISPATCH_LEVEL)
		{

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    OutputBuffer = Irp->UserBuffer;
    lpInOutBuffer = Irp->AssociatedIrp.SystemBuffer;
    nInBufferSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
    nOutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

	
	ARPBuffer = *(ARPPACKET *)lpInOutBuffer;
     if (ARPBuffer.ehhdr.eh_type == htons(0x0806)) //數據類型ARP請求或應答
	 {
		 if (ARPBuffer.arphdr.arp_hrd == htons(0x0001))//硬件地址為0x0001表示以太網地址
		 {
             if (ARPBuffer.arphdr.arp_pro == htons(0x0800))  //協議類型字段為0x0800表示IP地址
			 { 
				 if (ARPBuffer.arphdr.arp_hln == 6)
				 { 
					 if (ARPBuffer.arphdr.arp_pln == 4)
					 {
						 if (mystrcmp(ARPBuffer.ehhdr.eh_src,MacGateWay))
						 {Irp->IoStatus.Status=STATUS_INVALID_PARAMETER;
                         IofCompleteRequest(Irp,0);
                         return 0;
						 }
					 }
				 }
			 }
		 }
	 }


}

		

        return RealWriteDispatch(DeviceObject,Irp);;        
}
NTSTATUS
HookIoCreateDevice(
                IN PDRIVER_OBJECT DriverObject,
                IN ULONG DeviceExtensionSize,
                IN PUNICODE_STRING DeviceName OPTIONAL,
                IN DEVICE_TYPE DeviceType,
                IN ULONG DeviceCharacteristics,
                IN BOOLEAN Exclusive,
                OUT PDEVICE_OBJECT *DeviceObject
                )
{
   NTSTATUS NtStatus;
   ULONG Temp_Addr = 0;
   char buff[1024];
   HANDLE handle = 0;
   PUNICODE_STRING unistr = (PUNICODE_STRING)&buff[0];
   ULONG ReturnLength = 0;
   PDEVICE_OBJECT DeviceObjectTemp;
   DbgPrint("==>Hook IoCreateDevice()");

   NtStatus = OldIoCreateDevice(
       DriverObject,
       DeviceExtensionSize,
       DeviceName OPTIONAL,
       DeviceType,
       DeviceCharacteristics,
       Exclusive,
       DeviceObject
       );
   if(!NT_SUCCESS(NtStatus))
   {
       DbgPrint("m_IoCreateDevice() fail");
       return NtStatus;
   }

   //ObOpenObjectByPointer來打開進程(創建并返回進程句柄)    
   if(ObOpenObjectByPointer(DriverObject, 0, NULL, 0, 0, KernelMode, &handle))
   {
       DbgPrint("ObOpenObjectByPointer() Success and return");
       return STATUS_SUCCESS;
   }
   /*
   NTSTATUS ZwQueryObject(
   IN HANDLE ObjectHandle,
   IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
   OUT PVOID ObjectInformation,
   IN ULONG ObjectInformationLength,
   OUT PULONG ReturnLength OPTIONAL
   );
   
   ObjectHandle是我們想要獲取有關信息的句柄,ObjectInformationClass是信息類型,
   保存在以字節計算長度為ObjectInformationLength的緩沖區ObjectInformation中。
   我們對OBJECT_INFORMATION_CLASS使用的類是ObjectNameInformation和ObjectAllTypesInformation。
   ObjectNameInfromation類在緩沖區中返回OBJECT_NAME_INFORMATION結構,
   而ObjectAllTypesInformation類返回OBJECT_ALL_TYPES_INFORMATION結構。
   */
   
   ZwQueryObject(handle, 1, buff, 256, &ReturnLength);
   if(!unistr->Buffer)
   {
       ZwClose(handle);
       return STATUS_SUCCESS;
   }
   if(wcsncmp(unistr->Buffer, L"\\Device\\NPF_",wcslen(L"\\Device\\NPF_"))!=0 )
   {
       ZwClose(handle);
       return STATUS_SUCCESS;
   }

   DeviceObjectTemp = *DeviceObject;
   DbgPrint("DriverObject:%X, *DeviceObject->DriverObject:%x\nDriverObject->MajorFunction[IRP_MJ_CREATE]:%x,HookWriteDispatch:%x\n",
       DriverObject,
       DeviceObjectTemp->DriverObject,
       (ULONG)DriverObject->MajorFunction[IRP_MJ_WRITE],
       HookWriteDispatch);    

   //hook IRP_MJ_CREATE
   Temp_Addr = (ULONG)DriverObject->MajorFunction[IRP_MJ_WRITE];
   if(Temp_Addr == (ULONG)HookWriteDispatch)
       return STATUS_SUCCESS;
   
   RealWriteDispatch = (ProxyDispatch)Temp_Addr;
   DriverObject->MajorFunction[IRP_MJ_WRITE] = HookWriteDispatch;
    (*DeviceObject)->DriverObject->MajorFunction[IRP_MJ_WRITE] = HookWriteDispatch;

   return NtStatus;
}

char * MyStrchr(const char *str, int ch)

{

   while (*str && *str != (char)ch)

        str++;

   if (*str == (char)ch)

        return((char *)str);

   return(NULL);

}
PCHAR MyGetModuleBaseAddress( PCHAR pModuleName )
{
    PSYSTEM_MODULE_INFORMATION    pSysModule;    

    ULONG            uReturn;
    ULONG            uCount;
    PCHAR            pBuffer = NULL;
    PCHAR            pName    = NULL;
    NTSTATUS        status;
    UINT            ui;

    CHAR            szBuffer[BASEADDRLEN];
    PCHAR            pBaseAddress;
    
    status = ZwQuerySystemInformation( SystemModuleInformation, szBuffer, BASEADDRLEN, &uReturn );

    pBuffer = ( PCHAR )ExAllocatePool( NonPagedPool, uReturn );

    if ( pBuffer )
    {
        status = ZwQuerySystemInformation( SystemModuleInformation, pBuffer, uReturn, &uReturn );

        if( status == STATUS_SUCCESS )
        {
            uCount = ( ULONG )*( ( ULONG * )pBuffer );
            pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );

            for ( ui = 0; ui < uCount; ui++ )
            {
                pName = MyStrchr( pSysModule->ImageName, '\\' );

                if ( !pName )
                {
                    pName = pSysModule->ImageName;
                }

                else {
                    pName++;
                }

                if( !_stricmp( pName, pModuleName ) )
                {
                    pBaseAddress = ( PCHAR )pSysModule->Base;
                    ExFreePool( pBuffer );
                    return pBaseAddress;
                }

                pSysModule ++;
            }
        }

        ExFreePool( pBuffer );
    }

    return NULL;
}


FARPROC HookFunction( PCHAR pModuleBase, PCHAR HookFunName, FARPROC HookFun )
{
    PIMAGE_DOS_HEADER         pDosHdr;
    PIMAGE_NT_HEADERS         pNtHdr;
    PIMAGE_SECTION_HEADER     pSecHdr;
    PIMAGE_EXPORT_DIRECTORY  pExtDir;

    UINT                    ui,uj;
    PCHAR                    FunName;
    DWORD                    *dwAddrName;
    DWORD                    *dwAddrFun;
	DWORD                    *dwOldAddrFun;
	PVOID                    dwOldAddr;
    FARPROC                    pOldFun;
    ULONG                    uAttrib;
    UNICODE_STRING functionName;
	ANSI_STRING aStr;
	 RtlInitAnsiString(&aStr, HookFunName);
RtlAnsiStringToUnicodeString(&functionName, &aStr, TRUE);
dwOldAddr=MmGetSystemRoutineAddress( &functionName );
/*
小小修改了1下 原來的HookFunction貌似獲取的函數地址不對
偶采用先MmGetSystemRoutineAddress獲得地址 再做比較的辦法
不過只能用在ntoskrnl.exe和win32k.sys的hook


  */


    pDosHdr = ( PIMAGE_DOS_HEADER )pModuleBase;

    if ( IMAGE_DOS_SIGNATURE == pDosHdr->e_magic )
    {
        pNtHdr = ( PIMAGE_NT_HEADERS )( pModuleBase + pDosHdr->e_lfanew );

        if( IMAGE_NT_SIGNATURE  == pNtHdr->Signature ||    IMAGE_NT_SIGNATURE1 == pNtHdr->Signature )
        {
            pSecHdr = ( PIMAGE_SECTION_HEADER )( pModuleBase + pDosHdr->e_lfanew + sizeof( IMAGE_NT_HEADERS ) );

            for ( ui = 0; ui < (UINT)pNtHdr->FileHeader.NumberOfSections; ui++ )
            {
                if ( !strcmp( pSecHdr->Name, ".edata" ) )
                {                
                    pExtDir = ( PIMAGE_EXPORT_DIRECTORY )( pModuleBase + pSecHdr->VirtualAddress );
                    dwAddrName = ( PDWORD )(pModuleBase + pExtDir->AddressOfNames );
                    dwAddrFun = ( PDWORD )(pModuleBase + pExtDir->AddressOfFunctions );

                    for ( uj = 0; uj < (UINT)pExtDir->NumberOfFunctions; uj++ )
                    {
                        FunName = pModuleBase + *dwAddrName;

                        if( (DWORD)dwOldAddr==*dwAddrFun )
                        {
                            DbgPrint(" HOOK  %s()\n",FunName);
                            DisableWriteProtect(  );
                            pOldFun = ( FARPROC )( pModuleBase + *dwAddrFun );
                            *dwAddrFun = ( PCHAR )HookFun - pModuleBase;
                            EnableWriteProtect(  );
                            return pOldFun;
                        }

                      dwAddrName ++;
                      dwAddrFun ++;
                    }
                }

                pSecHdr++;
            }
        }
    }

    return NULL;
}

int HOOKIoConXXX()
{

    NTSTATUS        status;
    HANDLE          hHandle;
    PCHAR            pModuleAddress;
    int                i;
	pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");
    if ( pModuleAddress == NULL)
    {
        DbgPrint(" MyGetModuleBaseAddress()\n");
        return 0;
    }

    OldIoCreateDevice = (IoCreateDeviceXXX)HookFunction( pModuleAddress, "IoCreateDevice",(IoCreateDeviceXXX)HookIoCreateDevice);
    if ( OldIoCreateDevice == NULL)
    {
        DbgPrint(" HOOK FAILED\n");
        return 0;
    }

    DbgPrint("HOOK SUCCEED\n");
	return 1;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
一区二区三区在线高清| 欧美片在线播放| 国产性色一区二区| 亚洲成人中文在线| 色婷婷狠狠综合| 成人欧美一区二区三区白人| 国产精品91xxx| 久久综合久久久久88| 全部av―极品视觉盛宴亚洲| 日韩欧美在线观看一区二区三区| 日韩福利电影在线| 日韩午夜精品视频| 欧美a一区二区| 精品国产乱码久久久久久1区2区| 精品亚洲porn| 欧美国产日韩a欧美在线观看 | 六月丁香婷婷久久| 日韩美女天天操| 久久er99精品| 精品美女在线观看| 国产主播一区二区三区| 久久久综合视频| 91丨九色丨蝌蚪丨老版| 精品免费一区二区三区| 福利一区二区在线观看| 99精品视频一区二区| 91精品国产麻豆国产自产在线| 51久久夜色精品国产麻豆| 欧美大片日本大片免费观看| 中文字幕乱码日本亚洲一区二区| 亚洲一区在线看| 视频一区国产视频| 在线精品视频小说1| 久久久久青草大香线综合精品| 中文字幕高清一区| 日本不卡1234视频| 色视频成人在线观看免| 日韩一二三区视频| 亚洲午夜在线观看视频在线| 不卡电影免费在线播放一区| 久久影院电视剧免费观看| 日韩av电影天堂| 欧美视频一二三区| 一区二区三区不卡在线观看| 国产成人99久久亚洲综合精品| 久久久精品免费免费| 精品一区二区三区影院在线午夜| 欧美人成免费网站| 偷拍一区二区三区| 日韩亚洲欧美在线观看| 精品在线观看免费| 国产欧美一区二区三区沐欲| 成人黄色小视频在线观看| 国产精品乱码人人做人人爱| 高清日韩电视剧大全免费| 国产精品成人在线观看| 欧美在线观看一区二区| 午夜精品爽啪视频| 2欧美一区二区三区在线观看视频| 精品午夜久久福利影院| 亚洲国产高清在线| 欧美日韩中文一区| 国产高清久久久| 性感美女久久精品| wwww国产精品欧美| 色综合一个色综合| 看电视剧不卡顿的网站| 成人免费在线视频| 日韩免费福利电影在线观看| 99热这里都是精品| 久久99精品久久久久久动态图| 久久精品视频免费观看| 欧美日韩成人一区二区| 国产成人午夜视频| 欧美aa在线视频| 亚洲精品菠萝久久久久久久| 精品日韩一区二区三区免费视频| 精品国产乱码久久久久久闺蜜| 91久久一区二区| 成人网页在线观看| 激情五月激情综合网| 亚洲国产一区视频| 依依成人综合视频| 亚洲视频小说图片| 亚洲国产精品国自产拍av| 69成人精品免费视频| 在线观看三级视频欧美| 成人禁用看黄a在线| 狠狠色丁香久久婷婷综合_中| 亚洲成a天堂v人片| 首页国产丝袜综合| 性感美女极品91精品| 亚洲已满18点击进入久久| 亚洲女性喷水在线观看一区| 中文字幕制服丝袜一区二区三区 | 国产精品69毛片高清亚洲| 蜜臀国产一区二区三区在线播放| 一区二区三区蜜桃| 亚洲v日本v欧美v久久精品| 一区二区三区四区在线播放| 一区二区在线观看免费视频播放| 欧美精品1区2区3区| 欧美一二三区在线| 久久这里只有精品6| 国产欧美精品一区| 一区二区三区毛片| 日本欧美加勒比视频| 久久99国产精品久久99果冻传媒| 免费在线看成人av| 国产精品亚洲第一| 91福利国产成人精品照片| 欧美精品自拍偷拍| 国产视频一区不卡| 天天综合网 天天综合色| 激情综合网av| 92精品国产成人观看免费| 欧美无乱码久久久免费午夜一区| 欧美日韩一区二区三区免费看| 欧美一二三四区在线| 日韩久久一区二区| 久久国产麻豆精品| 91美女片黄在线观看91美女| 欧美一区中文字幕| 自拍偷自拍亚洲精品播放| 秋霞成人午夜伦在线观看| 成人高清视频在线观看| 日韩欧美亚洲一区二区| 一片黄亚洲嫩模| 成人晚上爱看视频| 精品国产三级a在线观看| 亚洲黄色录像片| 97久久精品人人做人人爽| 精品日韩一区二区三区| 日韩av电影免费观看高清完整版| 国产成人综合亚洲网站| 欧美一级久久久| 三级欧美在线一区| 在线视频欧美精品| 国产精品大尺度| 高清久久久久久| 国产拍欧美日韩视频二区| 精品一区二区免费视频| 7777精品伊人久久久大香线蕉经典版下载| 成人欧美一区二区三区黑人麻豆 | 日韩午夜在线播放| 日韩国产一二三区| 欧美日韩精品系列| 亚洲一区二区三区四区在线免费观看| 国产99精品视频| 国产午夜亚洲精品羞羞网站| 美女视频黄频大全不卡视频在线播放 | 91精品国产麻豆| 青青草成人在线观看| 欧美一区二区三区的| 无码av中文一区二区三区桃花岛| 在线观看亚洲a| 日韩精品电影在线观看| 精品日韩99亚洲| 国产精品香蕉一区二区三区| 日本一区二区三区高清不卡| 大陆成人av片| 亚洲电影在线免费观看| 制服丝袜中文字幕一区| 国产麻豆欧美日韩一区| 国产精品久久久久久久午夜片| 一本久久综合亚洲鲁鲁五月天 | 精品日本一线二线三线不卡| 国产乱理伦片在线观看夜一区| 国产日韩欧美精品在线| 色欧美日韩亚洲| 国产在线播放一区二区三区| 亚洲欧洲在线观看av| 日韩欧美国产综合| 不卡的电影网站| 日日噜噜夜夜狠狠视频欧美人 | 国产精品国产三级国产aⅴ原创| 成人免费看视频| 午夜一区二区三区视频| 久久综合国产精品| 欧美最猛黑人xxxxx猛交| 狠狠色综合色综合网络| 亚洲婷婷综合久久一本伊一区| 欧美日韩欧美一区二区| 国产在线不卡一卡二卡三卡四卡| 亚洲人成人一区二区在线观看 | 国产亚洲欧美中文| 7777精品久久久大香线蕉 | 一区二区三区欧美久久| 欧美日韩精品免费观看视频| 懂色av一区二区在线播放| 午夜久久久久久久久| 久久久午夜精品| 国产午夜精品福利| 欧美日韩精品三区| 91丨国产丨九色丨pron| 国产在线不卡一区| 久久国产精品色婷婷| 美女网站视频久久| 青青青伊人色综合久久| 亚洲一区二区视频在线|