337p人体粉嫩胞高清图片,97人妻精品一区二区三区在线 ,日本少妇自慰免费完整版,99精品国产福久久久久久,久久精品国产亚洲av热一区,国产aaaaaa一级毛片,国产99久久九九精品无码,久久精品国产亚洲AV成人公司
網(wǎng)易首頁 > 網(wǎng)易號 > 正文 申請入駐

游戲性能優(yōu)化與逆向分析技術(shù)

0
分享至


【USparkle專欄】如果你深懷絕技,愛“搞點研究”,樂于分享也博采眾長,我們期待你的加入,讓智慧的火花碰撞交織,讓知識的傳遞生生不息!

這是侑虎科技第1878篇文章,感謝作者其樂陶陶供稿。歡迎轉(zhuǎn)發(fā)分享,未經(jīng)作者授權(quán)請勿轉(zhuǎn)載。如果您有任何獨到的見解或者發(fā)現(xiàn)也歡迎聯(lián)系我們,一起探討。(QQ群:793972859)

作者主頁:

https://www.zhihu.com/people/jun-yan-76-80

一、前言

一直以來性能優(yōu)化的工作,非常依賴于工具,從結(jié)果反推過程,采集產(chǎn)品運行時信息,反推生產(chǎn)環(huán)節(jié)中的問題,性能問題的定位其實就是在做各種逆向。

不同的工具有不同的檢測面,一般會按照由粗及細(xì)的順序使用,直到找到問題的答案。

  • 粗粒度的工具,可大致定位到問題是出在哪個硬件上,比如發(fā)熱問題,可能的負(fù)載點在于CPU、GPU、其它硬件(屏幕、傳感器、網(wǎng)絡(luò)),一般應(yīng)該是系統(tǒng)級的工具,常用的有Perfetto、Xcode、GamePerf、PerfDog。

  • 細(xì)粒度的工具,檢測面較窄,但能提供更深入的信息,比如:定位到是CPU的問題時,可使用Unity Profiler、Simpleperf看問題堆棧;當(dāng)定位到是GPU的問題時,則使用RenderDoc、SnapdragonProfiler、Arm Graphics Analyzer截幀。

打個比喻,粗粒度的工具好比地鐵,能帶你到大致的區(qū)域范圍,更細(xì)粒度的工具幫你解決最后一公里路,在實際情況中,“打通”一公里的問題往往是卡點,通用性質(zhì)的工具可能滿足不了需求,常常做一些定制化的東西,通過一定積累,形成強大的工具鏈以應(yīng)對各種突發(fā)問題,本文主要對于這些底層的技術(shù)棧做一些總結(jié)。

二、動態(tài)庫注入

Android系統(tǒng)的數(shù)據(jù)基本都能通過讀各種文件實現(xiàn)(統(tǒng)計線程,讀取CPU利用率/頻率),但有嚴(yán)格的權(quán)限限制,非root環(huán)境下,只能讀取自己進程相關(guān)的文件、內(nèi)存信息。

我們注入到目標(biāo)進程的動態(tài)庫,就好像我們派出的“間諜”一樣,利用目標(biāo)進程的身份執(zhí)行我們自己的代碼。

使用JDWP Shellifier是最常用的方式,我們用C++在NDK環(huán)境下編寫一個動態(tài)庫so文件,這個腳本利用Java調(diào)試服務(wù)加載我們自己的庫。這也是RenderDoc、?LoliProfiler、Matrix用的方式,需要應(yīng)用Debug權(quán)限,或者root開全局調(diào)試,或者使用APKTool,解包修改AndroidManifest文件的Debug權(quán)限。


https://github.com/IOActive/jdwp-shellifier

這個腳本用Python封裝了注入過程,在onCreate函數(shù)觸發(fā)時,加載我們的庫。

jdwp_start("127.0.0.1", 500, "android.app.Activity.onCreate", None, libname)


控制臺輸出顯示注入成功

當(dāng)動態(tài)庫注入成功時,C++側(cè)入口函數(shù)JNI_OnLoad會被執(zhí)行,我們就可以干自己想干的事情了,這只是打開大門的第一步。

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {     (void)reserved;     LOGI("JNI_OnLoad");     JNIEnv *env;     LOGI("------------------ 4000 : %d", (int)JNI_VERSION_1_6);     if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK)     {         LOGI("JNI version not supported");         return JNI_ERR; // JNI version not supported.     }     else     {         LOGI("JNI init complete");     } }

下一步介紹Hook技術(shù),俗稱鉤子,能對特定函數(shù)劫持,兩種常見Hook手段為PLT Hook、Inline Hook。

三、PLT Hook

先大概講一下程序調(diào)用動態(tài)鏈接庫中函數(shù)的流程,以libunity.so中調(diào)用libc.so的Open函數(shù)為例子:會先訪問PLT(Procedure Linkage Table),第一次訪問它會使用動態(tài)連接器查找libc.so中Open函數(shù)的地址,然后地址保存到GOT(Global Offset Table)地址表,之后的調(diào)用就直接查GOT表了,如下:


所謂的PLT Hook就是在這個過程做文章、鉆空子,比如xHook就是修改GOT表的函數(shù)地址為我們的自定義函數(shù)實現(xiàn)攔截,xHook是一個常用的庫,較多運用于各種工具底層實現(xiàn),我們可以直接使用它,同時它也是開源的,我們可以參考它里面的很多代碼。


https://github.com/iqiyi/xHookgithub.com/iqiyi/xHook

PLT Hook比較適合去Hook一些公用庫的調(diào)用,不管上層怎么變,IO的行為最終落地到對Open、Close、Read、Wirte的調(diào)用,實際項目中主要用于IO、內(nèi)存分配、線程、網(wǎng)絡(luò)等行為的監(jiān)控,但它的局限性在于不能Hook內(nèi)部函數(shù),比如引擎內(nèi)部的函數(shù)調(diào)用。

四、實戰(zhàn):打印引擎啟動時的IO調(diào)用

隨便創(chuàng)建一個空的Demo,打包APK,將下面C++代碼通過NDK編譯成動態(tài)庫后,使用JDWP注入運行。

這里在JNI_OnLoad函數(shù)創(chuàng)建一個新的線程,延遲3秒后再執(zhí)行Hook的動作,是因為時機太早libunity.so未加載會導(dǎo)致失敗(據(jù)說xHook的作者后續(xù)開發(fā)了一個新的庫叫bHook,改進了這一點)。

     "xhook/xhook.h"         int MyOpen(const char *pathname, int flags, mode_t mode) {     int ret = open(pathname, flags, mode);     __android_log_print(ANDROID_LOG_INFO, "TestHook", "unity open %s %d", pathname, ret);     return ret; } void TestHook() {     // 延遲3秒,等待Unity加載完成     std::this_thread::sleep_for(std::chrono::seconds(3));     // 對Open函數(shù)Hook注冊     xhook_register("libunity.so", "open", (void *)MyOpen, nullptr);     // 執(zhí)行Hook     xhook_refresh(0); } JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {     JNIEnv *env;     if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK)     {         return JNI_ERR; // JNI version not supported.     }     std::thread(TestHook).detach();     return JNI_VERSION_1_6; }

這樣我們可以觀察到Unity啟動時加載的一些東西:

正在加載obb文件


正在加載il2cpp.so

五、Inline Hook

前面提到,PLT Hook不能Hook到庫內(nèi)部的函數(shù)調(diào)用,這個時候就應(yīng)該輪到Inline Hook出場,它是通過對目標(biāo)函數(shù)地址插入跳轉(zhuǎn)指令實現(xiàn),理論上可以Hook住任意內(nèi)部函數(shù),功能更為強大,由于涉及到在不同CPU架構(gòu)上的運行狀態(tài)機器碼修改,看起來很復(fù)雜,其實一點也不簡單,雖兼容性不如PLT Hook,不推薦在生產(chǎn)環(huán)境使用,但作為測試環(huán)境中的性能工具還是很強的。

ShadowHook是我常用的庫,可以將它的C++源碼下載下來,和自己庫一起編譯。


https://github.com/bytedance/android-inline-hook

如果Hook的目標(biāo)庫是帶符號表的,可以通過函數(shù)名hook,像這樣:

stub = shadowhook_hook_sym_name(                "libart.so",                "_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc",                (void *)proxy,                (void **)&orig);

但是我們常見的libunity.so、libil2cpp.so的符號表是分離的,可以嘗試用llvm-objcopy合并回去,這里更推薦另一種做法,ShadowHook也可以直接通過函數(shù)地址進行Hook

void *shadowhook_hook_func_addr(     void *func_addr,     void *new_addr,     void **orig_addr);

這里的func_addr函數(shù)地址是絕對地址,為動態(tài)庫基地址、函數(shù)偏移地址之和,找到這兩個地址加起來就行。

動態(tài)庫基地址每次進程啟動都不一樣,需要我們在程序中動態(tài)獲取,可以通過dl_iterate_phdr(Android 5.0以上)獲取,也可以讀/proc/self/maps實現(xiàn)(Android 4.0版本以上),之前介紹的xHook有源碼可以抄一下。


/proc/self/maps能查詢到動態(tài)庫基地址

而函數(shù)的偏移地址可以使用NDK下llvm-readelf -s指令,讀取符號表獲取到:


readelf讀取出的引擎內(nèi)部函數(shù)地址

接下來,對函數(shù)Hook后,需要對參數(shù)進行內(nèi)存分析提取里面的有用信息,如果有源碼,就是開卷考試,按照其內(nèi)存布局定義出來;沒源碼,我們也可以通過一些技巧把信息提取出來,下面以實戰(zhàn)說明一下。

六、實戰(zhàn):統(tǒng)計引擎內(nèi)部調(diào)用

我曾經(jīng)在《使用Simpleperf+Timeline診斷游戲卡頓》[1]這一篇文章中提到過,一些常見的卡頓歸因,能通過Simpleperf識別,但我們只知道觸發(fā)堆棧,今天我們更進一步。

這里以AddComponent函數(shù)為例,做一個Demo,然后嘗試使用Hook把觸發(fā)的GameObject、組件名字都打印出來,C# 測試代碼如下:

// New Game Object節(jié)點添加一些Unity內(nèi)置組件 var go = newGameObject(); go.AddComponent (); go.AddComponent (); go.AddComponent (); // 相機節(jié)點添加一個自定義腳本組件 gameObjet.AddComponent ();

通過Simpleperf鎖定我們的目標(biāo)函數(shù)為AddComponent(GameObject&, Unity::Type const*, ScriptingClassPtr, core::basic_string >*)


Simpleperf-Timeline查看命中的native函數(shù)

接下來通過llvm-readelf -s指令,查詢函數(shù)在符號表中的位置,名字稍微和Simpleperf中的顯示形式有點區(qū)別,但是我們還是能認(rèn)出它,它的地址就是0x5126a4。


搜索符號表內(nèi)AddComponent函數(shù)地址

接下來,我們需要在代理函數(shù)里面,對函數(shù)參數(shù)做一些解析,從函數(shù)簽名可以看到,參數(shù)有4個:void *go、void *unitytype、void *scriptclassptr和void *error。

我們的目標(biāo)是獲取節(jié)點名和組件名,解析前3個就行,主要有兩種方案:

1. 在符號表里多收集一些工具函數(shù)地址,比如獲取GameObject名字的方法0x435010,這個方法傳入GameObject對象指針作為參數(shù),返回名字字符串,所以可以把這個函數(shù)地址存起來,直接調(diào)用,我管這叫“他山之石,可以攻玉”。


獲取GameObject名字的方法地址能輕易搜索到

2. 針對另外兩個參數(shù),可以將結(jié)構(gòu)直接定義出來使用,比如ScriptClass前兩個參數(shù)是指針,第三個就是C字符串。這些工作,在有相關(guān)源碼的情況下會容易很多,如果沒有的話,只能通過LLDB無源碼動態(tài)調(diào)試之類的手段來獲取其內(nèi)存布局,會涉及到一些二進制分析手段、工具。

有了這些準(zhǔn)備工作,就可以開始編碼了:

     "shadowhook.h"          classScriptclass {     public:         void *placeholder1;         void *placeholder2;         constchar *name; }; classUnityType {     public:         void *placeholder1;         void *placeholder2;         constchar *name; }; uintptr_t baseaddr = 0; int callback(struct dl_phdr_info *info, size_t size, void *data) {     constchar *target = (constchar *)data;     // Check if the current shared library is the target library     if (strstr(info->dlpi_name, target))     {         __android_log_print(ANDROID_LOG_INFO, "TestHook", "Base address of %s: 0x%lx\n", target, (unsigned long)info->dlpi_addr);         baseaddr = info->dlpi_addr;         return1; // Return 1 to stop further iteration     }     return0; // Continue iteration } void *old_AddComponent = nullptr; typedef void *(*AddComponentFunc)(void *go, void *unitytype, void *scriptclassptr, void *error); typedef constchar*(*GameObjectGetNameFunc)(void *ptr); void *MyAddComponent(void *go, void *unitytype, void *scriptclassptr, void *error) {     constchar *goName = nullptr;     constchar *typeName = nullptr;     if(go != nullptr)     {         // 計算GameObjectGetName的地址         uintptr_t addr = baseaddr + 0x435010;          // 調(diào)用GameObjectGetName獲取名稱         GameObjectGetNameFunc func = (GameObjectGetNameFunc)(addr);         goName = func(go);     }     if (scriptclassptr != nullptr)     {         Scriptclass *t = (Scriptclass *)scriptclassptr;         typeName = t->name;     }     elseif (unitytype != nullptr)     {         UnityType *t = (UnityType *)unitytype;         typeName = t->name;     }     if(goName == nullptr)         goName = "null";     if(typeName == nullptr)         typeName = "null";     __android_log_print(ANDROID_LOG_INFO, "TestHook", "UnityAddComponent: %s %s\n", goName, typeName);     return ((AddComponentFunc)old_AddComponent)(go, unitytype, scriptclassptr, error); } void TestHook() {     // 延遲3秒,等待Unity加載完成     std::this_thread::sleep_for(std::chrono::seconds(3));     // 查詢libunity的基地址     constchar *library_name = "libunity.so";     dl_iterate_phdr(callback, (void *)library_name);     // 計算AddComponent的函數(shù)地址     uintptr_t addr = baseaddr + 0x5126a4;     // 執(zhí)行Hook并保存原函數(shù)地址到old_AddComponent     void *stub = shadowhook_hook_func_addr((void *)addr, (void *)MyAddComponent, (void **)&old_AddComponent);     if (stub == nullptr)     {         int err_num = shadowhook_get_errno();         constchar *err_msg = shadowhook_to_errmsg(err_num);         __android_log_print(ANDROID_LOG_INFO, "TestHook", "hook error %d - %s\n", err_num, err_msg);     }     else     {         __android_log_print(ANDROID_LOG_INFO, "TestHook", "hook success\n");     } } JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {     JNIEnv *env;     if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK)     {         return JNI_ERR; // JNI version not supported.     }     // 初始化Shadowhook     int ret = shadowhook_init(SHADOWHOOK_MODE_UNIQUE, true);     if (ret != 0)     {         constchar *err_msg = shadowhook_to_errmsg(shadowhook_get_init_errno());         __android_log_print(ANDROID_LOG_INFO, "TestHook", "init error %d - %s\n", shadowhook_get_init_errno(), err_msg);     }     else     {         __android_log_print(ANDROID_LOG_INFO, "TestHook", "init success\n");     }     std::thread(TestHook).detach();     return JNI_VERSION_1_6; }

和前面PLT Hook的例子一樣,使用JDWP注入執(zhí)行,最終可以輸出Demo中調(diào)用AddComponet的參數(shù)詳情,利用這些信息,接下來就可以做很多事情了,我們現(xiàn)在可以幾乎Hook任意函數(shù)!


控制臺最終能正常輸出節(jié)點、組件名

七、棧回溯

在棧上每個函數(shù)都有自己的儲存空間,被稱之為棧幀(Frame),上面保存了部分參數(shù)、局部變量。當(dāng)調(diào)用其它函數(shù)時,會將這個函數(shù)返回后的下一行指令地址也保存在棧幀,棧回溯就是分析這些棧上面函數(shù)地址,還原函數(shù)運行軌跡的過程。


函數(shù)A調(diào)用函數(shù)B,0x40056a是函數(shù)B結(jié)束后返回的地址

棧回溯經(jīng)常和Hook一起配合,當(dāng)Hook住某個函數(shù)后,輸出它的調(diào)用棧,能更進一步分析問題歸因,如果對性能要求不高,可以直接使用libunwind庫,它在不需要開-fno-omit-frame-pointer編譯選項、dwarf調(diào)試信息的情況下,也能輸出函數(shù)地址,然后我們通過符號表將函數(shù)名解析出來。

    // 棧回溯上下文結(jié)構(gòu) struct BacktraceState {     void **current;     void **end; }; static _Unwind_Reason_Code UnwindCallback(struct _Unwind_Context *context, void *arg) {     BacktraceState *state = static_cast (arg);     uintptr_t pc = _Unwind_GetIP(context);     if (pc)     {         if (state->current == state->end)         {             return _URC_END_OF_STACK;         }         else         {             *state->current++ = reinterpret_cast

 (pc);         }     }     return _URC_NO_REASON; } size_t CaptureBacktrace(void **buffer, size_t max) {     BacktraceState state = {buffer, buffer + max};     _Unwind_Backtrace(UnwindCallback, &state);     return state.current - buffer; } void DumpBacktrace(std::ostream &os, void **buffer, size_t count) {     for (size_t idx = 0; idx < count; ++idx)     {         constvoid *addr = buffer[idx];         constchar *symbol = "";         Dl_info info;         if (dladdr(addr, &info) && info.dli_sname)         {             symbol = info.dli_sname;         }         // 這里將函數(shù)的絕對地址轉(zhuǎn)換為相對地址         uintptr_t relative = (uintptr_t)addr - (uintptr_t)info.dli_fbase;         os << "  #" << std::setw(2) << idx << ": " << info.dli_fname << " " << (void *)relative << "\n";     } } // 經(jīng)封裝后的打印函數(shù) void PrintStacktrace(const size_t count) {     void* buffer[count];     std::ostringstream oss;     DumpBacktrace(oss, buffer, CaptureBacktrace(buffer, count));     __android_log_print(ANDROID_LOG_INFO, "TestHook", oss.str().c_str()); }

棧回溯的步驟雖然看起來繁瑣,但只要經(jīng)過封裝后,使用起來其實和在C# 里面一樣方便,下一步我們來試一下。

八、實戰(zhàn):為IO調(diào)用加入棧統(tǒng)計

沿用之前的PLT Hook的例子,這次我們將調(diào)用堆棧打印出來:


調(diào)用封裝好的PrintStacktrace


現(xiàn)在打印日志里多了調(diào)用棧函數(shù)地址

使用NDK目錄下的addr2line.exe對這些地址進行解析,最終得到我們想要的結(jié)果。

LocalFileSystemPosix::Open(FileEntryData&, FilePermission, FileAutoBehavior) zip::CentralDirectory::Enumerate(bool (*)(FileSystemEntry const&, FileAccessor&, char const*, zip::CDFD const&, void*), void*) VerifyAndMountObb(char const*) MountObbs() UnityPause(int) UnityPlayerLoop() nativeRender(_JNIEnv*, _jobject*)

九、結(jié)語

本文從以性能優(yōu)化分析目的入手,介紹了常用的逆向分析手段 —— 注入、Hook、堆棧回溯,這里只是淺顯地聊了一下運用場景,事實上每一個坑都能挖到很深,比如注入與反注入,如何對競品進行注入,Hook的相關(guān)調(diào)試方法、內(nèi)存分析、更高性能的棧回溯、聚合顯示(火焰圖)等等。

之所以總結(jié)此文,是因為我在近期的工作中感覺到,了解一點逆向分析的知識,對性能優(yōu)化、程序調(diào)試方面很有好處,也不局限于游戲開發(fā)領(lǐng)域,技多不壓身。

參考

[1] 使用Simpleperf+Timeline診斷游戲卡頓


https://zhuanlan.zhihu.com/p/666443120

文末,再次感謝其樂陶陶 的分享, 作者主頁:https://www.zhihu.com/people/jun-yan-76-80, 如果您有任何獨到的見解或者發(fā)現(xiàn)也歡迎聯(lián)系我們,一起探討。(QQ群: 793972859 )。

近期精彩回顧

【學(xué)堂上新】

【學(xué)堂上新】

【學(xué)堂上新】

【萬象更新】

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點推薦
我今年55了,想用血淚教訓(xùn)告訴你:不要跟任何人,包括你的父母、子女、枕邊人,分享這三件事

我今年55了,想用血淚教訓(xùn)告訴你:不要跟任何人,包括你的父母、子女、枕邊人,分享這三件事

東林夕亭
2026-03-19 09:04:30
中美談妥,中方深夜公布結(jié)果,禁止美國做2件事,川普不接受不行

中美談妥,中方深夜公布結(jié)果,禁止美國做2件事,川普不接受不行

烈史
2026-03-22 22:11:50
伊朗:允許非敵方船只通過霍爾木茲海峽!美官員此前稱埃及和卡塔爾傳話美以:伊朗有意進行談判,但開出的條件非常苛刻

伊朗:允許非敵方船只通過霍爾木茲海峽!美官員此前稱埃及和卡塔爾傳話美以:伊朗有意進行談判,但開出的條件非常苛刻

每日經(jīng)濟新聞
2026-03-22 14:39:05
殲20總師被除名:任央企高管,最近露面照曝出,事發(fā)全過程被還原

殲20總師被除名:任央企高管,最近露面照曝出,事發(fā)全過程被還原

博士觀察
2026-03-20 12:20:55
理想高管:理想L9 Livis的800V全主動懸架難度非常大 國內(nèi)沒有一家供應(yīng)商能做出來

理想高管:理想L9 Livis的800V全主動懸架難度非常大 國內(nèi)沒有一家供應(yīng)商能做出來

快科技
2026-03-22 10:41:03
本田的“萬億跌落”,只用了一個季度

本田的“萬億跌落”,只用了一個季度

觀察者網(wǎng)
2026-03-21 08:58:17
離婚6年后,高圣遠轉(zhuǎn)身回美國,找了個年輕貌美富婆,周迅仍單身

離婚6年后,高圣遠轉(zhuǎn)身回美國,找了個年輕貌美富婆,周迅仍單身

草莓解說體育
2026-03-22 06:41:30
終于要補強大外援了?曝廣東簽下2米13防守大閘,朱芳雨放手一搏

終于要補強大外援了?曝廣東簽下2米13防守大閘,朱芳雨放手一搏

老葉評球
2026-03-22 18:05:04
韭菜是血栓的克星?醫(yī)生告誡:不想血管堵塞,少吃這4種菜

韭菜是血栓的克星?醫(yī)生告誡:不想血管堵塞,少吃這4種菜

岐黃傳人孫大夫
2026-03-22 14:17:08
倒計時!曝利物浦將火速解雇斯洛特!1.5億“頂星”來投

倒計時!曝利物浦將火速解雇斯洛特!1.5億“頂星”來投

頭狼追球
2026-03-22 11:04:14
果然蛻變了!熱巴回國后第一次正式公開活動,眼神變了,面相變了

果然蛻變了!熱巴回國后第一次正式公開活動,眼神變了,面相變了

怎挽怎挽
2026-03-21 11:38:16
從法甲金靴到中超助攻王,高球商天才還很無私,卻不受法國隊重用

從法甲金靴到中超助攻王,高球商天才還很無私,卻不受法國隊重用

足籃大世界
2026-03-22 07:59:42
淪為共享單車的女色虎

淪為共享單車的女色虎

深度報
2026-03-05 22:39:27
事關(guān)A股,重要調(diào)整,周一生效!

事關(guān)A股,重要調(diào)整,周一生效!

21世紀(jì)經(jīng)濟報道
2026-03-22 20:50:02
4S店蹭飯260次后續(xù):男子已社死,被同學(xué)認(rèn)出,博主調(diào)解反被追責(zé)

4S店蹭飯260次后續(xù):男子已社死,被同學(xué)認(rèn)出,博主調(diào)解反被追責(zé)

離離言幾許
2026-03-20 17:20:41
女子雪地中凍僵,好心人報警求救,卻苦等80分鐘,在絕望中凍死

女子雪地中凍僵,好心人報警求救,卻苦等80分鐘,在絕望中凍死

英國那些事兒
2026-03-21 23:16:46
醫(yī)生告誡:腦梗早期不是手腳麻,而是頻繁出現(xiàn)5癥狀,千萬別忽視

醫(yī)生告誡:腦梗早期不是手腳麻,而是頻繁出現(xiàn)5癥狀,千萬別忽視

醫(yī)學(xué)科普匯
2026-03-19 21:15:03
外媒:中國國產(chǎn)郵輪“愛達·花城號”出塢意義重大

外媒:中國國產(chǎn)郵輪“愛達·花城號”出塢意義重大

參考消息
2026-03-22 15:49:02
足壇著名酒鬼,喝酒喝到尿床,戒酒后卻成為維埃里口中的雄獅

足壇著名酒鬼,喝酒喝到尿床,戒酒后卻成為維埃里口中的雄獅

足籃大世界
2026-03-21 16:45:26
美日達成一致,不準(zhǔn)中國武力收臺,轉(zhuǎn)頭就發(fā)現(xiàn),又被中方反將一軍

美日達成一致,不準(zhǔn)中國武力收臺,轉(zhuǎn)頭就發(fā)現(xiàn),又被中方反將一軍

浪子阿邴聊體育
2026-03-22 22:15:41
2026-03-23 00:23:00
侑虎科技UWA incentive-icons
侑虎科技UWA
游戲/VR性能優(yōu)化平臺
1558文章數(shù) 986關(guān)注度
往期回顧 全部

科技要聞

嫌臺積電太慢 馬斯克要把芯片產(chǎn)能飆升50倍

頭條要聞

媒體:特朗普48小時通牒砸向伊朗 不排除美國鋌而走險

頭條要聞

媒體:特朗普48小時通牒砸向伊朗 不排除美國鋌而走險

體育要聞

46歲生日快樂!巴薩全隊穿10號致敬小羅

娛樂要聞

47歲“國際章”身材走樣?讓嘲笑她的人閉嘴

財經(jīng)要聞

睡夢中欠債1.2萬?這只“蝦”殺瘋了

汽車要聞

14.28萬元起 吉利銀河星耀8遠航家開啟預(yù)售

態(tài)度原創(chuàng)

房產(chǎn)
本地
旅游
親子
公開課

房產(chǎn)要聞

全城狂送1000杯咖啡!網(wǎng)易房產(chǎn)【早C計劃】,即刻啟動!

本地新聞

春色滿城關(guān)不住|紹興春日頂流,這片櫻花海藏不住了

旅游要聞

“春約五蓮·共享繁花”賞花主題活動在五蓮縣叩官鎮(zhèn)大旺村盛大啟幕

親子要聞

學(xué)術(shù)期刊發(fā)表兒童如廁研究引爭議,專家:倫理層面存在明顯缺失

公開課

李玫瑾:為什么性格比能力更重要?

無障礙瀏覽 進入關(guān)懷版