宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

智能终端设备维修查询系统注册会员邮箱认证须知!
查看: 2088|回复: 0

[转载] 内核级HOOK的几种实现与应用2

[复制链接]
  • TA的每日心情
    开心
    2024-12-9 18:45
  • 签到天数: 124 天

    [LV.7]常住居民III

    admin 发表于 2009-12-12 23:06:58 | 显示全部楼层 |阅读模式

    欢迎您注册加入!这里有您将更精采!

    您需要 登录 才可以下载或查看,没有账号?注册

    x
    3、 HOOK PE 方法
         这种方法对于拦截、分析其他内核驱动的函数调用来说用的比较多。原理
    是根据替换 PE 格式导出表中的相应函数来实现的。此方法中需要用到一些小
    技巧。如内核模式并没有直接提供类似应用层的 GetModuleHandl()、GetProcAddress() 等函数来获得模块的地址。那么我们就需要自己来编写,这
    里用到了一个未公开的函数与结构。ZwQuerySystemInformation 与 SYSTEM_MODULE_INFORMATION 来实现得到模块的基地址。这样我们就可以根据
    PE 格式来枚举导出表中的函数来替换了。但这又引出了一个问题,那就是从
    WINDOWS 2000 后内核数据的页属性都是只读的,不能更改。内核模式也没有
    提供类似应用层的 VirtualProtectEx() 等函数来修改页面属性。那么也需要
    我们自己来编写。因为我们是在内核模式所以我们可以通过修改 cr0 寄存器的
    的写保护位来达到我们的目的。这样我们所期望的拦截内核模式函数的功能便
    得以实现。此方法需要你对 PE 格式有一定的基础。下面的程序演示了这一过程。



    1. /*****************************************************************
    2. 文件名         : WssHookPE.c
    3. 描述           : 拦截内核函数
    4. 作者           : sinister
    5. 最后修改日期   : 2002-11-02
    6. *****************************************************************/

    7. #include "ntddk.h"
    8. #include "windef.h"


    9. typedef enum _SYSTEM_INFORMATION_CLASS {
    10.      SystemBasicInformation,
    11.      SystemProcessorInformation,
    12.      SystemPerformanceInformation,
    13.      SystemTimeOfDayInformation,
    14.      SystemNotImplemented1,
    15.      SystemProcessesAndThreadsInformation,
    16.      SystemCallCounts,
    17.      SystemConfigurationInformation,
    18.      SystemProcessorTimes,
    19.      SystemGlobalFlag,
    20.      SystemNotImplemented2,
    21.      SystemModuleInformation,
    22.      SystemLockInformation,
    23.      SystemNotImplemented3,
    24.      SystemNotImplemented4,
    25.      SystemNotImplemented5,
    26.      SystemHandleInformation,
    27.      SystemObjectInformation,
    28.      SystemPagefileInformation,
    29.      SystemInstructionEmulationCounts,
    30.      SystemInvalidInfoClass1,
    31.      SystemCacheInformation,
    32.      SystemPoolTagInformation,
    33.      SystemProcessorStatistics,
    34.      SystemDpcInformation,
    35.      SystemNotImplemented6,
    36.      SystemLoadImage,
    37.      SystemUnloadImage,
    38.      SystemTimeAdjustment,
    39.      SystemNotImplemented7,
    40.      SystemNotImplemented8,
    41.      SystemNotImplemented9,
    42.      SystemCrashDumpInformation,
    43.      SystemExceptionInformation,
    44.      SystemCrashDumpStateInformation,
    45.      SystemKernelDebuggerInformation,
    46.      SystemContextSwitchInformation,
    47.      SystemRegistryQuotaInformation,
    48.      SystemLoadAndCallImage,
    49.      SystemPrioritySeparation,
    50.      SystemNotImplemented10,
    51.      SystemNotImplemented11,
    52.      SystemInvalidInfoClass2,
    53.      SystemInvalidInfoClass3,
    54.      SystemTimeZoneInformation,
    55.      SystemLookasideInformation,
    56.      SystemSetTimeSlipEvent,
    57.      SystemCreateSession,
    58.      SystemDeleteSession,
    59.      SystemInvalidInfoClass4,
    60.      SystemRangeStartInformation,
    61.      SystemVerifierInformation,
    62.      SystemAddVerifier,
    63.      SystemSessionProcessesInformation
    64. } SYSTEM_INFORMATION_CLASS;


    65. typedef struct tagSYSTEM_MODULE_INFORMATION {
    66.      ULONG Reserved[2];
    67.      PVOID Base;
    68.      ULONG Size;
    69.      ULONG Flags;
    70.      USHORT Index;
    71.      USHORT Unknown;
    72.      USHORT LoadCount;
    73.      USHORT ModuleNameOffset;
    74.      CHAR ImageName[256];
    75. } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

    76. #define IMAGE_DOS_SIGNATURE         0x5A4D       // MZ
    77. #define IMAGE_NT_SIGNATURE       0x50450000   // PE00
    78. #define IMAGE_NT_SIGNATURE1         0x00004550     // 00EP

    79. typedef struct _IMAGE_DOS_HEADER {       // DOS .EXE header
    80.      WORD   e_magic;                     // Magic number
    81.      WORD   e_cblp;                       // Bytes on last page of file
    82.      WORD   e_cp;                         // Pages in file
    83.      WORD   e_crlc;                       // Relocations
    84.      WORD   e_cparhdr;                   // Size of header in paragraphs
    85.      WORD   e_minalloc;                   // Minimum extra paragraphs needed
    86.      WORD   e_maxalloc;                   // Maximum extra paragraphs needed
    87.      WORD   e_ss;                         // Initial (relative) SS value
    88.      WORD   e_sp;                         // Initial SP value
    89.      WORD   e_csum;                       // Checksum
    90.      WORD   e_ip;                         // Initial IP value
    91.      WORD   e_cs;                         // Initial (relative) CS value
    92.      WORD   e_lfarlc;                     // File address of relocation table
    93.      WORD   e_ovno;                       // Overlay number
    94.      WORD   e_res[4];                     // Reserved words
    95.      WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    96.      WORD   e_oeminfo;                   // OEM information; e_oemid specific
    97.      WORD   e_res2[10];                   // Reserved words
    98.      LONG   e_lfanew;                     // File address of new exe header
    99.    } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;


    100. typedef struct _IMAGE_FILE_HEADER {
    101.      WORD     Machine;
    102.      WORD     NumberOfSections;
    103.      DWORD   TimeDateStamp;
    104.      DWORD   PointerToSymbolTable;
    105.      DWORD   NumberOfSymbols;
    106.      WORD     SizeOfOptionalHeader;
    107.      WORD     Characteristics;
    108. } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

    109. typedef struct _IMAGE_DATA_DIRECTORY {
    110.      DWORD   VirtualAddress;
    111.      DWORD   Size;
    112. } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

    113. #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES     16

    114. //
    115. // Optional header format.
    116. //

    117. typedef struct _IMAGE_OPTIONAL_HEADER {
    118.      //
    119.      // Standard fields.
    120.      //

    121.      WORD     Magic;
    122.      BYTE     MajorLinkerVersion;
    123.      BYTE     MinorLinkerVersion;
    124.      DWORD   SizeOfCode;
    125.      DWORD   SizeOfInitializedData;
    126.      DWORD   SizeOfUninitializedData;
    127.      DWORD   AddressOfEntryPoint;
    128.      DWORD   BaseOfCode;
    129.      DWORD   BaseOfData;

    130.      //
    131.      // NT additional fields.
    132.      //

    133.      DWORD   ImageBase;
    134.      DWORD   SectionAlignment;
    135.      DWORD   FileAlignment;
    136.      WORD     MajorOperatingSystemVersion;
    137.      WORD     MinorOperatingSystemVersion;
    138.      WORD     MajorImageVersion;
    139.      WORD     MinorImageVersion;
    140.      WORD     MajorSubsystemVersion;
    141.      WORD     MinorSubsystemVersion;
    142.      DWORD   Win32VersionValue;
    143.      DWORD   SizeOfImage;
    144.      DWORD   SizeOfHeaders;
    145.      DWORD   CheckSum;
    146.      WORD     Subsystem;
    147.      WORD     DllCharacteristics;
    148.      DWORD   SizeOfStackReserve;
    149.      DWORD   SizeOfStackCommit;
    150.      DWORD   SizeOfHeapReserve;
    151.      DWORD   SizeOfHeapCommit;
    152.      DWORD   LoaderFlags;
    153.      DWORD   NumberOfRvaAndSizes;
    154.      IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
    155. } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

    156. typedef struct _IMAGE_NT_HEADERS {
    157.      DWORD Signature;
    158.      IMAGE_FILE_HEADER FileHeader;
    159.      IMAGE_OPTIONAL_HEADER32 OptionalHeader;
    160. } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

    161. typedef IMAGE_NT_HEADERS32                   IMAGE_NT_HEADERS;
    162. typedef PIMAGE_NT_HEADERS32                 PIMAGE_NT_HEADERS;

    163. //
    164. // Section header format.
    165. //

    166. #define IMAGE_SIZEOF_SHORT_NAME               8

    167. typedef struct _IMAGE_SECTION_HEADER {
    168.      BYTE     Name[IMAGE_SIZEOF_SHORT_NAME];
    169.      union {
    170.              DWORD   PhysicalAddress;
    171.              DWORD   VirtualSize;
    172.      } Misc;
    173.      DWORD   VirtualAddress;
    174.      DWORD   SizeOfRawData;
    175.      DWORD   PointerToRawData;
    176.      DWORD   PointerToRelocations;
    177.      DWORD   PointerToLinenumbers;
    178.      WORD     NumberOfRelocations;
    179.      WORD     NumberOfLinenumbers;
    180.      DWORD   Characteristics;
    181. } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

    182. #define IMAGE_SIZEOF_SECTION_HEADER           40
    183. //
    184. // Export Format
    185. //

    186. typedef struct _IMAGE_EXPORT_DIRECTORY {
    187.      DWORD   Characteristics;
    188.      DWORD   TimeDateStamp;
    189.      WORD     MajorVersion;
    190.      WORD     MinorVersion;
    191.      DWORD   Name;
    192.      DWORD   Base;
    193.      DWORD   NumberOfFunctions;
    194.      DWORD   NumberOfNames;
    195.      DWORD   AddressOfFunctions;     // RVA from base of image
    196.      DWORD   AddressOfNames;         // RVA from base of image
    197.      DWORD   AddressOfNameOrdinals;   // RVA from base of image
    198. } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

    199. #define BASEADDRLEN 10

    200. NTSYSAPI
    201. NTSTATUS
    202. NTAPI
    203. ZwQuerySystemInformation(
    204.      IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    205.      IN OUT PVOID SystemInformation,
    206.      IN ULONG SystemInformationLength,
    207.      OUT PULONG ReturnLength OPTIONAL
    208.      );


    209. typedef NTSTATUS (* ZWCREATEFILE)(
    210.    OUT PHANDLE FileHandle,
    211.    IN ACCESS_MASK DesiredAccess,
    212.    IN POBJECT_ATTRIBUTES ObjectAttributes,
    213.    OUT PIO_STATUS_BLOCK IoStatusBlock,
    214.    IN PLARGE_INTEGER AllocationSize   OPTIONAL,
    215.    IN ULONG FileAttributes,
    216.    IN ULONG ShareAccess,
    217.    IN ULONG CreateDisposition,
    218.    IN ULONG CreateOptions,
    219.    IN PVOID EaBuffer   OPTIONAL,
    220.    IN ULONG EaLength
    221.    );

    222. ZWCREATEFILE     OldZwCreateFile;

    223. static NTSTATUS   MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
    224. VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);
    225. VOID DisableWriteProtect( PULONG pOldAttr);
    226. VOID EnableWriteProtect( ULONG ulOldAttr );
    227. FARPROC HookFunction(     PCHAR pModuleBase, PCHAR pHookName, FARPROC pHookFunc );

    228. NTSTATUS  
    229. HookNtCreateFile(
    230.    OUT PHANDLE FileHandle,
    231.    IN ACCESS_MASK DesiredAccess,
    232.    IN POBJECT_ATTRIBUTES ObjectAttributes,
    233.    OUT PIO_STATUS_BLOCK IoStatusBlock,
    234.    IN PLARGE_INTEGER AllocationSize   OPTIONAL,
    235.    IN ULONG FileAttributes,
    236.    IN ULONG ShareAccess,
    237.    IN ULONG CreateDisposition,
    238.    IN ULONG CreateOptions,
    239.    IN PVOID EaBuffer   OPTIONAL,
    240.    IN ULONG EaLength
    241.    );



    242. PCHAR MyGetModuleBaseAddress( PCHAR pModuleName )
    243. {
    244.      PSYSTEM_MODULE_INFORMATION     pSysModule;   

    245.      ULONG             uReturn;
    246.      ULONG             uCount;
    247.      PCHAR             pBuffer = NULL;
    248.      PCHAR             pName     = NULL;
    249.      NTSTATUS         status;
    250.      UINT             ui;

    251.      CHAR             szBuffer[BASEADDRLEN];
    252.      PCHAR             pBaseAddress;
    253.    
    254.      status = ZwQuerySystemInformation( SystemModuleInformation, szBuffer, BASEADDRLEN, &uReturn );

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

    256.      if ( pBuffer )
    257.      {
    258.          status = ZwQuerySystemInformation( SystemModuleInformation, pBuffer, uReturn, &uReturn );

    259.          if( status == STATUS_SUCCESS )
    260.          {
    261.              uCount = ( ULONG )*( ( ULONG * )pBuffer );
    262.              pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );

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

    266.                  if ( !pName )
    267.                  {
    268.                      pName = pSysModule->ImageName;
    269.                  }

    270.                  else {
    271.                      pName++;
    272.                  }

    273.                  if( !_stricmp( pName, pModuleName ) )
    274.                  {
    275.                      pBaseAddress = ( PCHAR )pSysModule->Base;
    276.                      ExFreePool( pBuffer );
    277.                      return pBaseAddress;
    278.                  }

    279.                  pSysModule ++;
    280.              }
    281.          }

    282.          ExFreePool( pBuffer );
    283.      }

    284.      return NULL;
    285. }


    286. FARPROC HookFunction( PCHAR pModuleBase, PCHAR HookFunName, FARPROC HookFun )
    287. {
    288.      PIMAGE_DOS_HEADER         pDosHdr;
    289.      PIMAGE_NT_HEADERS         pNtHdr;
    290.      PIMAGE_SECTION_HEADER     pSecHdr;
    291.      PIMAGE_EXPORT_DIRECTORY   pExtDir;

    292.      UINT                     ui,uj;
    293.      PCHAR                     FunName;
    294.      DWORD                     *dwAddrName;
    295.      DWORD                     *dwAddrFun;
    296.      FARPROC                     pOldFun;
    297.      ULONG                     uAttrib;


    298.      pDosHdr = ( PIMAGE_DOS_HEADER )pModuleBase;

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

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

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

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

    315.                          if( !strcmp( FunName, HookFunName ) )
    316.                          {
    317.                              DbgPrint(" HOOK   %s()\n",FunName);
    318.                              DisableWriteProtect( &uAttrib );
    319.                              pOldFun = ( FARPROC )( pModuleBase + *dwAddrFun );
    320.                              *dwAddrFun = ( PCHAR )HookFun - pModuleBase;
    321.                              EnableWriteProtect( uAttrib );
    322.                              return pOldFun;
    323.                          }

    324.                        dwAddrName ++;
    325.                        dwAddrFun ++;
    326.                      }
    327.                  }

    328.                  pSecHdr++;
    329.              }
    330.          }
    331.      }

    332.      return NULL;
    333. }


    334. // 驱动入口
    335. NTSTATUS   DriverEntry( IN PDRIVER_OBJECT DriverObject,   IN PUNICODE_STRING RegistryPath )
    336. {
    337.    
    338.      UNICODE_STRING   nameString, linkString;
    339.      PDEVICE_OBJECT   deviceObject;
    340.      NTSTATUS         status;
    341.      HANDLE           hHandle;
    342.      PCHAR             pModuleAddress;
    343.      int                 i;
    344.    

    345.      //卸载驱动
    346.      DriverObject->DriverUnload = DriverUnload;

    347.      //建立设备
    348.      RtlInitUnicodeString( &nameString, L"\\Device\\WssHookPE" );
    349.    
    350.      status = IoCreateDevice( DriverObject,
    351.                              0,
    352.                              &nameString,
    353.                              FILE_DEVICE_UNKNOWN,
    354.                              0,
    355.                              TRUE,
    356.                              &deviceObject
    357.                            );
    358.                            

    359.      if (!NT_SUCCESS( status ))
    360.          return status;
    361.    

    362.      RtlInitUnicodeString( &linkString, L"\\DosDevices\\WssHookPE" );

    363.      status = IoCreateSymbolicLink (&linkString, &nameString);

    364.      if (!NT_SUCCESS( status ))
    365.      {
    366.          IoDeleteDevice (DriverObject->DeviceObject);
    367.          return status;
    368.      }   
    369.    
    370.      pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");
    371.      if ( pModuleAddress == NULL)
    372.      {
    373.          DbgPrint(" MyGetModuleBaseAddress()\n");
    374.          return 0;
    375.      }

    376.      OldZwCreateFile = (ZWCREATEFILE)HookFunction( pModuleAddress, "ZwCreateFile",(ZWCREATEFILE)HookNtCreateFile);
    377.      if ( OldZwCreateFile == NULL)
    378.      {
    379.          DbgPrint(" HOOK FAILED\n");
    380.          return 0;
    381.      }

    382.      DbgPrint("HOOK SUCCEED\n");

    383.      for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)     {

    384.            DriverObject->MajorFunction[i] = MydrvDispatch;
    385.      }

    386.        DriverObject->DriverUnload = DriverUnload;
    387.      
    388.    return STATUS_SUCCESS;
    389. }



    390. //处理设备对象操作

    391. static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    392. {
    393.      Irp->IoStatus.Status = STATUS_SUCCESS;
    394.      Irp->IoStatus.Information = 0L;
    395.      IoCompleteRequest( Irp, 0 );
    396.      return Irp->IoStatus.Status;
    397.    
    398. }



    399. VOID DriverUnload (IN PDRIVER_OBJECT     pDriverObject)
    400. {
    401.      UNICODE_STRING   nameString;
    402.      PCHAR             pModuleAddress;

    403.      pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");
    404.      if ( pModuleAddress == NULL)
    405.      {
    406.          DbgPrint("MyGetModuleBaseAddress()\n");
    407.          return ;
    408.      }

    409.      OldZwCreateFile = (ZWCREATEFILE)HookFunction( pModuleAddress, "ZwCreateFile",(ZWCREATEFILE)OldZwCreateFile);
    410.      if ( OldZwCreateFile == NULL)
    411.      {
    412.          DbgPrint(" UNHOOK FAILED!\n");
    413.          return ;
    414.      }

    415.      DbgPrint("UNHOOK SUCCEED\n");

    416.      RtlInitUnicodeString( &nameString, L"\\DosDevices\\WssHookPE" );   
    417.      IoDeleteSymbolicLink(&nameString);
    418.      IoDeleteDevice(pDriverObject->DeviceObject);

    419.      return;
    420. }

    421. NTSTATUS  
    422. HookNtCreateFile(
    423.    OUT PHANDLE FileHandle,
    424.    IN ACCESS_MASK DesiredAccess,
    425.    IN POBJECT_ATTRIBUTES ObjectAttributes,
    426.    OUT PIO_STATUS_BLOCK IoStatusBlock,
    427.    IN PLARGE_INTEGER AllocationSize   OPTIONAL,
    428.    IN ULONG FileAttributes,
    429.    IN ULONG ShareAccess,
    430.    IN ULONG CreateDisposition,
    431.    IN ULONG CreateOptions,
    432.    IN PVOID EaBuffer   OPTIONAL,
    433.    IN ULONG EaLength
    434.    )
    435. {
    436.      NTSTATUS     status;

    437.      DbgPrint("Hook ZwCreateFile()\n");

    438.      status = ((ZWCREATEFILE)(OldZwCreateFile))(
    439.                FileHandle,
    440.                DesiredAccess,
    441.                ObjectAttributes,
    442.                IoStatusBlock,
    443.                AllocationSize,
    444.                FileAttributes,
    445.                ShareAccess,
    446.                CreateDisposition,
    447.                CreateOptions,
    448.                EaBuffer,
    449.                EaLength
    450.                );

    451.      return status;
    452. }


    453. VOID DisableWriteProtect( PULONG pOldAttr)
    454. {

    455.      ULONG uAttr;

    456.      _asm
    457.      {
    458.            push eax;
    459.            mov   eax, cr0;
    460.            mov   uAttr, eax;
    461.            and   eax, 0FFFEFFFFh; // CR0 16 BIT = 0
    462.            mov   cr0, eax;
    463.            pop   eax;
    464.      };

    465.      *pOldAttr = uAttr; //保存原有的 CRO 属性

    466. }

    467. VOID EnableWriteProtect( ULONG uOldAttr )
    468. {

    469.    _asm
    470.    {
    471.        push eax;
    472.        mov   eax, uOldAttr; //恢复原有 CR0 属性
    473.        mov   cr0, eax;
    474.        pop   eax;
    475.    };

    476. }
    复制代码
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    免责声明

    本站中所有被研究的素材与信息全部来源于互联网,版权争议与本站无关。本站所发布的任何软件编程开发或软件的逆向分析文章、逆向分析视频、补丁、注册机和注册信息,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习编程开发技术或逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。所以您如果喜欢某程序,请购买注册正版软件,获得正版优质服务!不得将上述内容私自传播、销售或者用于商业用途!否则,一切后果请用户自负!

    QQ|Archiver|手机版|小黑屋|联系我们|宝峰科技 ( 滇公网安备 53050202000040号 | 滇ICP备09007156号-2 )

    Copyright © 2001-2023 Discuz! Team. GMT+8, 2025-5-8 14:21 , File On Powered by Discuz! X3.49

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