#include "../runtime/common.h"#include "../runtime/crypto.h"#include "../core/objects.h"#include "../core/osutils.h"#include "../core/streams.h"#include "../core/core.h"#include "../core/files.h"#include "../core/processors.h"#include "../core/pefile.h"#include "../core/packer.h"#include "../third-party/lzma/LzmaDecode.h"#ifdef DEMO#include "../core/win_runtime32demo.dll.inc"#include "../core/win_runtime64demo.dll.inc"#else#include "../core/win_runtime32.dll.inc"#include "../core/win_runtime64.dll.inc"#endif#ifdef VMP_GNU#include <stdlib.h>#endifTEST(PEFileTest, OpenEXE){// Test: read header of Win32/Intel file. Read should finish successfully.PEFile pf(NULL);ASSERT_EQ(pf.Open("test-binaries/win32-app-test1-i386", foRead), osSuccess);// Check architectures.ASSERT_EQ(pf.count(), 1ul);PEArchitecture *arch = pf.arch_pe();EXPECT_EQ(arch->name().compare("i386"), 0);EXPECT_EQ(arch->owner()->format_name().compare("PE"), 0);EXPECT_EQ(arch->cpu_address_size(), osDWord);EXPECT_EQ(arch->image_base(), 0x400000ull);EXPECT_EQ(arch->entry_point(), 0x401000ull);// Check segments.ISectionList *segment_list = arch->segment_list();ASSERT_EQ(segment_list->count(), 3ul);EXPECT_EQ(segment_list->item(0)->name().compare(".text"), 0);EXPECT_EQ(segment_list->item(1)->name().compare(".rdata"), 0);EXPECT_EQ(segment_list->item(2)->name().compare(".data"), 0);EXPECT_EQ((int)segment_list->item(0)->memory_type(), (mtReadable | mtExecutable));EXPECT_EQ((int)segment_list->item(1)->memory_type(), mtReadable);EXPECT_EQ((int)segment_list->item(2)->memory_type(), (mtReadable | mtWritable));// Check imports.IImportList *imp = arch->import_list();ASSERT_EQ(imp->count(), 3ul);EXPECT_EQ(imp->item(0)->name().compare("user32.dll"), 0);ASSERT_EQ(imp->item(0)->count(), 6ul);EXPECT_EQ(imp->item(0)->item(0)->name().compare("SetFocus"), 0);EXPECT_EQ(imp->item(0)->item(0)->address(), 0x402028ull);EXPECT_EQ(imp->item(0)->item(1)->name().compare("MessageBoxA"), 0);EXPECT_EQ(imp->item(0)->item(1)->address(), 0x40202cull);EXPECT_EQ(imp->item(0)->item(2)->name().compare("GetDlgItemTextA"), 0);EXPECT_EQ(imp->item(0)->item(2)->address(), 0x402030ull);EXPECT_EQ(imp->item(0)->item(3)->name().compare("GetDlgItem"), 0);EXPECT_EQ(imp->item(0)->item(3)->address(), 0x402034ull);EXPECT_EQ(imp->item(0)->item(4)->name().compare("EndDialog"), 0);EXPECT_EQ(imp->item(0)->item(4)->address(), 0x402038ull);EXPECT_EQ(imp->item(0)->item(5)->name().compare("DialogBoxIndirectParamA"), 0);EXPECT_EQ(imp->item(0)->item(5)->address(), 0x40203cull);EXPECT_EQ(imp->item(1)->name().compare("kernel32.dll"), 0);ASSERT_EQ(imp->item(1)->count(), 5ul);EXPECT_EQ(imp->item(1)->item(0)->name().compare("MultiByteToWideChar"), 0);EXPECT_EQ(imp->item(1)->item(0)->address(), 0x402010ull);EXPECT_EQ(imp->item(1)->item(1)->name().compare("GlobalFree"), 0);EXPECT_EQ(imp->item(1)->item(1)->address(), 0x402014ull);EXPECT_EQ(imp->item(1)->item(2)->name().compare("ExitProcess"), 0);EXPECT_EQ(imp->item(1)->item(2)->address(), 0x402018ull);EXPECT_EQ(imp->item(1)->item(3)->name().compare("GetModuleHandleA"), 0);EXPECT_EQ(imp->item(1)->item(3)->address(), 0x40201cull);EXPECT_EQ(imp->item(1)->item(4)->name().compare("GlobalAlloc"), 0);EXPECT_EQ(imp->item(1)->item(4)->address(), 0x402020ull);EXPECT_EQ(imp->item(2)->name().compare("VMProtectSDK32.dll"), 0);ASSERT_EQ(imp->item(2)->count(), 3ul);EXPECT_EQ(imp->item(2)->item(0)->name().compare("VMProtectDecryptStringA"), 0);EXPECT_EQ(imp->item(2)->item(0)->address(), 0x402000ull);EXPECT_EQ(imp->item(2)->item(1)->name().compare("VMProtectEnd"), 0);EXPECT_EQ(imp->item(2)->item(1)->address(), 0x402004ull);EXPECT_EQ(imp->item(2)->item(2)->name().compare("VMProtectBegin"), 0);EXPECT_EQ(imp->item(2)->item(2)->address(), 0x402008ull);// Check fixups.IFixupList *fixup_list = arch->fixup_list();EXPECT_EQ(fixup_list->count(), 0ul);// Check resources.IResourceList *resource_list = arch->resource_list();EXPECT_EQ(resource_list->count(), 0ul);// Check lists were cleared.pf.Close();EXPECT_EQ(pf.count(), 0ul);}TEST(PEFileTest, OpenDLL){PEFile pf(NULL);ASSERT_EQ(pf.Open("test-binaries/win32-dll-test1-i386", foRead), osSuccess);// Check architectures.ASSERT_EQ(pf.count(), 1ul);PEArchitecture *arch = pf.arch_pe();// Check exports.IExportList *exp = arch->export_list();EXPECT_EQ(exp->name().compare("ShimEng.dll"), 0);ASSERT_EQ(exp->count(), 11ul);EXPECT_EQ(exp->item(0)->name().compare("SE_DllLoaded"), 0);EXPECT_EQ(exp->item(0)->forwarded_name().compare("APPHELP.SE_DllLoaded"), 0);EXPECT_EQ(exp->item(0)->address(), 0x3ff31257ull);EXPECT_EQ(exp->item(10)->name().compare("SE_ProcessDying"), 0);EXPECT_EQ(exp->item(10)->forwarded_name().compare("APPHELP.SE_ProcessDying"), 0);EXPECT_EQ(exp->item(10)->address(), 0x3ff31358ull);// Check fixups.IFixupList *fixup_list = arch->fixup_list();ASSERT_EQ(fixup_list->count(), 12ul);EXPECT_EQ(fixup_list->item(0)->address(), 0x3ff3103aull);EXPECT_EQ(fixup_list->item(0)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(1)->address(), 0x3ff31042ull);EXPECT_EQ(fixup_list->item(1)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(2)->address(), 0x3ff3104dull);EXPECT_EQ(fixup_list->item(2)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(3)->address(), 0x3ff31089ull);EXPECT_EQ(fixup_list->item(3)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(4)->address(), 0x3ff310a2ull);EXPECT_EQ(fixup_list->item(4)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(5)->address(), 0x3FF310AEull);EXPECT_EQ(fixup_list->item(5)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(6)->address(), 0x3FF310B6ull);EXPECT_EQ(fixup_list->item(6)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(7)->address(), 0x3FF310BEull);EXPECT_EQ(fixup_list->item(7)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(8)->address(), 0x3FF310CAull);EXPECT_EQ(fixup_list->item(8)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(9)->address(), 0x3FF310E0ull);EXPECT_EQ(fixup_list->item(9)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(10)->address(), 0x3FF310E8ull);EXPECT_EQ(fixup_list->item(10)->type(), ftHighLow);EXPECT_EQ(fixup_list->item(11)->address(), 0x3ff310f0ull);EXPECT_EQ(fixup_list->item(11)->type(), ftHighLow);// Check resources.IResourceList *resource_list = arch->resource_list();ASSERT_EQ(resource_list->count(), 1ul);EXPECT_EQ(resource_list->item(0)->type(), rtVersionInfo);ASSERT_EQ(resource_list->item(0)->count(), 1ul);EXPECT_EQ(resource_list->item(0)->item(0)->name(), "1");EXPECT_EQ(resource_list->item(0)->item(0)->count(), 1ul);EXPECT_EQ(resource_list->item(0)->item(0)->item(0)->name(), "1033");EXPECT_EQ(resource_list->item(0)->item(0)->item(0)->address(), 0x3ff33060ull);EXPECT_EQ(resource_list->item(0)->item(0)->item(0)->size(), 0x3acul);// Check lists were cleared.pf.Close();EXPECT_EQ(pf.count(), 0ul);}TEST(PEFileTest, Clone){PEFile pf(NULL);ASSERT_EQ(pf.Open("test-binaries/win32-app-test1-i386", foRead), osSuccess);PEFile *f = pf.Clone(pf.file_name().c_str());EXPECT_EQ(pf.count(), f->count());PEArchitecture &src = *pf.arch_pe();PEArchitecture &dst = *f->arch_pe();EXPECT_EQ(src.owner()->format_name().compare(dst.owner()->format_name()), 0);EXPECT_EQ(src.name().compare(dst.name()), 0);EXPECT_EQ(src.cpu_address_size(), dst.cpu_address_size());EXPECT_EQ(src.entry_point(), dst.entry_point());EXPECT_EQ(src.command_list()->count(), dst.command_list()->count());EXPECT_EQ(src.segment_list()->count(), dst.segment_list()->count());EXPECT_EQ(src.import_list()->count(), dst.import_list()->count());EXPECT_EQ(src.fixup_list()->count(), dst.fixup_list()->count());EXPECT_EQ(src.export_list()->count(), dst.export_list()->count());EXPECT_EQ(src.resource_list()->count(), dst.resource_list()->count());delete f;}TEST(PEFileTest, Runtime_x32){PEFile file(NULL);ASSERT_TRUE(file.OpenResource(win_runtime32_dll_file, sizeof(win_runtime32_dll_file), true));ASSERT_EQ(file.count(), 1ul);PEArchitecture *arch = file.arch_pe();Buffer buffer(&win_runtime32_dll_code[0]);arch->ReadFromBuffer(buffer);EXPECT_GT(arch->export_list()->count(), 0ul);EXPECT_GT(arch->function_list()->count(), 0ul);}TEST(PEFileTest, Runtime_x64){PEFile file(NULL);ASSERT_TRUE(file.OpenResource(win_runtime64_dll_file, sizeof(win_runtime64_dll_file), true));ASSERT_EQ(file.count(), 1ul);PEArchitecture *arch = file.arch_pe();Buffer buffer(&win_runtime64_dll_code[0]);arch->ReadFromBuffer(buffer);EXPECT_GT(arch->export_list()->count(), 0ul);EXPECT_GT(arch->function_list()->count(), 0ul);}TEST(PEFileTest, Compile_x32){PEFile pf(NULL);size_t i;ASSERT_EQ(pf.Open("test-binaries/win32-app-delphi-i386", foRead), osSuccess);PEArchitecture *arch = pf.arch_pe();for (i = 0; i < arch->map_function_list()->count(); i++) {MapFunction *map_function = arch->map_function_list()->item(i);if (map_function->type() == otString || map_function->type() == otAPIMarker || map_function->type() == otMarker)arch->function_list()->AddByAddress(map_function->address(), ctVirtualization, 0, true, NULL);}ASSERT_EQ(arch->function_list()->count(), 4ul);std::string file_name = pf.file_name()+".exe";PEFile *f = pf.Clone(file_name.c_str());CompileOptions options;options.flags = cpMaximumProtection;options.section_name = ".vmp";ASSERT_TRUE(f->Compile(options));delete f;PEFile pf2(NULL);ASSERT_EQ(pf2.Open(file_name.c_str(), foRead | foHeaderOnly), osSuccess);ASSERT_EQ(pf2.count(), pf.count());PEArchitecture &src = *pf.arch_pe();PEArchitecture &dst = *pf2.arch_pe();for (i = 0; i < src.fixup_list()->count(); i++) {IFixup *src_fixup = src.fixup_list()->item(i);IFixup *dst_fixup = src.fixup_list()->GetFixupByAddress(src_fixup->address());EXPECT_EQ(src_fixup->address(), dst_fixup->address());EXPECT_EQ(src_fixup->type(), dst_fixup->type());EXPECT_EQ(src_fixup->size(), dst_fixup->size());}if (options.flags & cpResourceProtection) {EXPECT_EQ(dst.resource_list()->count(), 4ul);} else {EXPECT_EQ(src.resource_list()->count(), dst.resource_list()->count());for (i = 0; i < src.resource_list()->count(); i++) {PEResource *src_resource = src.resource_list()->item(i);PEResource *dst_resource = dst.resource_list()->item(i);EXPECT_EQ(src_resource->count(), dst_resource->count());EXPECT_EQ(src_resource->address(), dst_resource->address());EXPECT_EQ(src_resource->size(), dst_resource->size());EXPECT_EQ(src_resource->type(), dst_resource->type());EXPECT_EQ(src_resource->name(), dst_resource->name());}}// check AV bufferASSERT_EQ(dst.segment_list()->count(), 13ul);ASSERT_TRUE(dst.AddressSeek(dst.segment_list()->item(10)->address()));uint32_t sum = 0;for (i = 0; i < 64; i++) {sum += dst.ReadDWord();}EXPECT_EQ(sum, 0xB7896EB5);// delete file from diskpf2.Close();remove(file_name.c_str());}TEST(PEFileTest, Compile_DLL){PEFile pf(NULL);ASSERT_EQ(pf.Open("test-binaries/win32-dll-test1-i386", foRead), osSuccess);std::string file_name = pf.file_name()+".dll";PEFile *f = pf.Clone(file_name.c_str());CompileOptions options;options.flags = cpPack;options.section_name = ".vmp";ASSERT_TRUE(f->Compile(options));delete f;PEFile pf2(NULL);ASSERT_EQ(pf2.Open(file_name.c_str(), foRead | foHeaderOnly), osSuccess);ASSERT_EQ(pf2.count(), pf.count());PEArchitecture &src = *pf.arch_pe();PEArchitecture &dst = *pf2.arch_pe();size_t i;for (i = 0; i < src.fixup_list()->count(); i++) {IFixup *src_fixup = src.fixup_list()->item(i);IFixup *dst_fixup = src.fixup_list()->GetFixupByAddress(src_fixup->address());EXPECT_EQ(src_fixup->address(), dst_fixup->address());EXPECT_EQ(src_fixup->type(), dst_fixup->type());EXPECT_EQ(src_fixup->size(), dst_fixup->size());}ASSERT_EQ(src.resource_list()->count(), dst.resource_list()->count());for (i = 0; i < src.resource_list()->count(); i++) {PEResource *src_resource = src.resource_list()->item(i);PEResource *dst_resource = dst.resource_list()->item(i);EXPECT_EQ(src_resource->count(), dst_resource->count());EXPECT_EQ(src_resource->address(), dst_resource->address());EXPECT_EQ(src_resource->size(), dst_resource->size());EXPECT_EQ(src_resource->type(), dst_resource->type());EXPECT_EQ(src_resource->name(), dst_resource->name());}ASSERT_EQ(src.export_list()->count(), dst.export_list()->count());for (i = 0; i < src.export_list()->count(); i++) {PEExport *src_export = src.export_list()->item(i);PEExport *dst_export = dst.export_list()->item(i);EXPECT_EQ(src_export->name(), dst_export->name());EXPECT_EQ(src_export->ordinal(), dst_export->ordinal());if (src_export->forwarded_name().empty()) {EXPECT_EQ(src_export->address(), dst_export->address());} else {EXPECT_EQ(src_export->forwarded_name(), dst_export->forwarded_name());}}// check AV bufferASSERT_EQ(dst.segment_list()->count(), 7ul);ASSERT_TRUE(dst.AddressSeek(dst.segment_list()->item(4)->address()));uint32_t sum = 0;for (i = 0; i < 64; i++) {sum += dst.ReadDWord();}EXPECT_EQ(sum, 0xB7896EB5);// delete file from diskpf2.Close();remove(file_name.c_str());}TEST(PEFileTest, Compile_x64){PEFile pf(NULL);ASSERT_EQ(pf.Open("test-binaries/win64-app-msvc-amd64", foRead), osSuccess);PEArchitecture *arch = pf.arch_pe();size_t i;for (i = 0; i < arch->map_function_list()->count(); i++) {MapFunction *map_function = arch->map_function_list()->item(i);if (map_function->type() == otString)arch->function_list()->AddByAddress(map_function->address(), ctVirtualization, 0, true, NULL);}ASSERT_EQ(arch->function_list()->count(), 2ul);std::string file_name = pf.file_name()+".exe";PEFile *f = pf.Clone(file_name.c_str());CompileOptions options;options.flags = cpMaximumProtection;options.section_name = ".vmp";ASSERT_TRUE(f->Compile(options));delete f;PEFile pf2(NULL);ASSERT_EQ(pf2.Open(file_name.c_str(), foRead | foHeaderOnly), osSuccess);ASSERT_EQ(pf2.count(), pf.count());PEArchitecture &src = *pf.arch_pe();PEArchitecture &dst = *pf2.arch_pe();for (i = 0; i < src.fixup_list()->count(); i++) {IFixup *src_fixup = src.fixup_list()->item(i);IFixup *dst_fixup = src.fixup_list()->GetFixupByAddress(src_fixup->address());EXPECT_EQ(src_fixup->address(), dst_fixup->address());EXPECT_EQ(src_fixup->type(), dst_fixup->type());EXPECT_EQ(src_fixup->size(), dst_fixup->size());}if (options.flags & cpResourceProtection) {EXPECT_EQ(dst.resource_list()->count(), 1ul);} else {ASSERT_EQ(src.resource_list()->count(), dst.resource_list()->count());for (i = 0; i < src.resource_list()->count(); i++) {PEResource *src_resource = src.resource_list()->item(i);PEResource *dst_resource = dst.resource_list()->item(i);EXPECT_EQ(src_resource->count(), dst_resource->count());EXPECT_EQ(src_resource->address(), dst_resource->address());EXPECT_EQ(src_resource->size(), dst_resource->size());EXPECT_EQ(src_resource->type(), dst_resource->type());EXPECT_EQ(src_resource->name(), dst_resource->name());}}// check AV bufferASSERT_EQ(dst.segment_list()->count(), 9ul);ASSERT_TRUE(dst.AddressSeek(dst.segment_list()->item(6)->address()));uint32_t sum = 0;for (i = 0; i < 64; i++) {sum += dst.ReadDWord();}EXPECT_EQ(sum, 0xB7896EB5);// delete file from diskpf2.Close();remove(file_name.c_str());}TEST(PEFileTest, Pack){PEFile pf(NULL);ASSERT_EQ(pf.Open("test-binaries/win32-app-delphi-i386", foRead), osSuccess);PEArchitecture *arch = pf.arch_pe();PESegment *section = arch->segment_list()->item(0);Data data, props;Packer packer;size_t data_size = static_cast<size_t>(section->physical_size());ASSERT_TRUE(packer.WriteProps(&props));ASSERT_TRUE(arch->AddressSeek(section->address()));ASSERT_TRUE(packer.Code(arch, data_size, &data));Byte *dst = new Byte[data_size];CLzmaDecoderState state;EXPECT_EQ(LzmaDecodeProperties(&state.Properties, props.data(), (unsigned)props.size()), LZMA_RESULT_OK);state.Probs = (CProb *)new Byte[LzmaGetNumProbs(&state.Properties) * sizeof(CProb)];SizeT src_processed_size;SizeT dst_processed_size;EXPECT_EQ(LzmaDecode(&state, data.data(), -1, &src_processed_size, dst, -1, &dst_processed_size), LZMA_RESULT_OK);delete [] state.Probs;ASSERT_EQ(dst_processed_size, data_size);arch->AddressSeek(section->address());for (size_t i = 0; i < data_size; i++) {EXPECT_EQ(dst[i], arch->ReadByte());}delete [] dst;}TEST(PEFileTest, CalcCheckSum){uint32_t sum;ASSERT_TRUE(os::FileGetCheckSum("test-binaries/win32-app-delphi-i386", &sum));EXPECT_EQ(sum, 0x000e4490ul);ASSERT_TRUE(os::FileGetCheckSum("test-binaries/win64-app-msvc-amd64", &sum));EXPECT_EQ(sum, 0x0000b8c9ul);}#ifndef DEMO#ifndef __APPLE__static bool execFile(const std::string &fileName, DWORD &exitCode){exitCode = 0xFFFFFFF;#ifdef VMP_GNUint ret = system(("wine " + fileName).c_str());if (ret != -1){exitCode = DWORD(ret);return true;}return false;#elsePROCESS_INFORMATION processInformation = { };STARTUPINFOW startupInfo = { };startupInfo.cb = sizeof(startupInfo);os::unicode_string unicodeName = os::FromUTF8(fileName);BOOL result = CreateProcessW(NULL, const_cast<wchar_t *>(unicodeName.c_str()),NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,NULL, NULL, &startupInfo, &processInformation);if (!result)return false;WaitForSingleObject(processInformation.hProcess, 10000);result = GetExitCodeProcess(processInformation.hProcess, &exitCode);if (exitCode == STILL_ACTIVE)TerminateProcess(processInformation.hProcess, 0xFFFFFFFF);CloseHandle(processInformation.hProcess);CloseHandle(processInformation.hThread);return (result && (exitCode != STILL_ACTIVE));#endif}/* seh.cpp:#include <windows.h>#include "VMProtectSDK.h"__declspec(noinline) void try1(){printf("try 1\n");try {throw 1;}catch (int) {printf("catch 1\n");throw;}printf("end 1\n\n");}__declspec(noinline) void try2(){printf("try 2\n");PEXCEPTION_POINTERS info = NULL;__try {if (*reinterpret_cast<char *>(0xFACE) == 0)return;}__except (info = GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) {printf("throw at %p\n", info->ExceptionRecord->ExceptionAddress);}printf("end 2\n\n");}int main(){if (VMProtectIsDebuggerPresent(true))printf("debugger detected\n");if (VMProtectIsVirtualMachinePresent())printf("virtual machine detected\n");printf("try main\n");try {try1();}catch (...) {printf("catch main\n");}printf("end main\n");try2();return 0;}*/TEST(PEFileTest, SEH_x32){PEFile pf(NULL);ASSERT_EQ(pf.Open("test-binaries/seh-x86", foRead), osSuccess);PEArchitecture *arch = pf.arch_pe();arch->function_list()->AddByAddress(0x00401130, ctVirtualization, 0, true, NULL); // mainarch->function_list()->AddByAddress(0x00401000, ctUltra, 0, true, NULL); // try1arch->function_list()->AddByAddress(0x00401070, ctMutation, 0, true, NULL); // try2std::string file_name = pf.file_name() + ".exe";PEFile *f = pf.Clone(file_name.c_str());CompileOptions options;options.flags = cpMaximumProtection;options.section_name = ".vmp";ASSERT_TRUE(f->Compile(options));delete f;DWORD ret;ASSERT_TRUE(execFile(file_name, ret));ASSERT_EQ(ret, 0u);}#endif#ifndef VMP_GNUTEST(PEFileTest, SEH_x64){PEFile pf(NULL);ASSERT_EQ(pf.Open("test-binaries/seh-x64", foRead), osSuccess);PEArchitecture *arch = pf.arch_pe();arch->function_list()->AddByAddress(0x00000001400010A0, ctVirtualization, 0, true, NULL); // mainarch->function_list()->AddByAddress(0x0000000140001000, ctUltra, 0, true, NULL); // try1arch->function_list()->AddByAddress(0x0000000140001040, ctMutation, 0, true, NULL); // try2std::string file_name = pf.file_name() + ".exe";PEFile *f = pf.Clone(file_name.c_str());CompileOptions options;options.flags = cpMaximumProtection;options.section_name = ".vmp";ASSERT_TRUE(f->Compile(options));delete f;DWORD ret;ASSERT_TRUE(execFile(file_name, ret));ASSERT_EQ(ret, 0u);}#endif#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。