转载

三种方式轻松绕过Windows App Certification Kit (WACK)的API检测(UWP, C++)

微软在UWP中提供了一组丰富的API能够满足99%的应用的需求

(棒读)

,然而在那剩下1%的情况下找不到桌面API的替代品是很棘手的,正如我上一篇文章里提到的CreateFile,就不属于微软在UWP中允许使用的API。

实际上WACK的API检测是个没什么用的东西,因为它是通过读取PE导入表,以及 .NET程序的P/Invoke签名的方法来判断一个App是否使用了不允许使用的API。因此只要调用LoadLibrary就能轻松绕过。

问题在于LoadLibrary(Ex)本身不被允许调用,微软表示替代品是LoadPackagedLibrary,而这个API在调用时会检测路径是否在appx内,如果不在就直接报错。(

太愚蠢了

)因此首先我们要设法获得LoadLibraryEx的地址,在此之前先获取kernel32.dll或kernelbase.dll的地址。

方法1:使用VirtualQuery获取

MEMORY_BASIC_INFORMATION info = {};   if (VirtualQuery(VirtualQuery, &info, sizeof(info)))   {     auto kernelAddr = (HMODULE)info.AllocationBase;     auto loadlibraryPtr = GetProcAddress(kernelAddr, "LoadLibraryExW");     // load your library here ... } 

方法2:使用Thread Environment Block获取

首先定义结构

typedef struct _PEB_LDR_DATA   {     ULONG Length;     UCHAR Initialized;     PVOID SsHandle;     LIST_ENTRY InLoadOrderModuleList;     LIST_ENTRY InMemoryOrderModuleList;     LIST_ENTRY InInitializationOrderModuleList;     PVOID EntryInProgress; } PEB_LDR_DATA, *PPEB_LDR_DATA;  typedef struct _PEB   {     BYTE Reserved1[2];     BYTE BeingDebugged;     BYTE Reserved2[1];     PVOID Reserved3[2];     PPEB_LDR_DATA Ldr;     PVOID ProcessParameters;     PVOID Reserved4[3];     PVOID AtlThunkSListPtr;     PVOID Reserved5;     ULONG Reserved6;     PVOID Reserved7;     ULONG Reserved8;     ULONG AtlThunkSListPtr32;     PVOID Reserved9[45];     BYTE Reserved10[96];     PVOID PostProcessInitRoutine;     BYTE Reserved11[128];     PVOID Reserved12[1];     ULONG SessionId; } PEB, *PPEB;  typedef struct _TEB   {     PVOID Reserved1[12];     PPEB ProcessEnvironmentBlock;     PVOID Reserved2[399];     BYTE Reserved3[1952];     PVOID TlsSlots[64];     BYTE Reserved4[8];     PVOID Reserved5[26];     PVOID ReservedForOle;  // Windows 2000 only     PVOID Reserved6[4];     PVOID TlsExpansionSlots; } TEB, *PTEB; 

然后计算地址

auto teb = NtCurrentTeb();   auto peb = teb->ProcessEnvironmentBlock;   auto pebldr = peb->Ldr;   auto ioml = *(DWORD*)pebldr->InInitializationOrderModuleList.Flink;   auto kernelAddr = (HMODULE)*(DWORD*)(ioml + 8);   auto loadlibraryPtr = GetProcAddress(kernelAddr, "LoadLibraryExW");   // load your library here ... 

方法3:直接搜索(方法来自 XDA )

HMODULE SearchKernelAddress()   {     char *Tmp = (char*)GetTickCount64;     Tmp = (char*)((~0xFFF)&(DWORD_PTR)Tmp);      while (Tmp)     {         __try         {             if (Tmp[0] == 'M' && Tmp[1] == 'Z')                 break;         }         __except (EXCEPTION_EXECUTE_HANDLER)         {         }         Tmp -= 0x1000;     }      if (Tmp == 0)         return nullptr;     else          return (HMODULE)Tmp; } 

上述方法不仅适用于UWP,还适用于Windows Phone 8/8.1应用,以及Windows 8/8.1的应用。

个人最推荐的方式是VirtualQuery,它使用的全是公开的API和结构,而使用TEB获取的方式里使用了私有结构,因此将来的系统更新可能会导致兼容性出现问题。

项目示例与源码: https://github.com/hjc4869/WACKBypass

原文  http://hjc.im/3-ways-to-bypass-wack/
正文到此结束
Loading...