| 27 | } |
| 28 | |
| 29 | void GetCallStack(std::string& callStack) { |
| 30 | CONTEXT context; |
| 31 | RtlCaptureContext(&context); |
| 32 | |
| 33 | DWORD64 imageBase; |
| 34 | DWORD64 controlPc = context.Pc; |
| 35 | DWORD64 frameBase = context.Fp; |
| 36 | |
| 37 | HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); |
| 38 | HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); |
| 39 | MODULEINFO kernel32Info = { 0 }; |
| 40 | MODULEINFO ntdllInfo = { 0 }; |
| 41 | GetModuleInformation(GetCurrentProcess(), hKernel32, &kernel32Info, sizeof(kernel32Info)); |
| 42 | GetModuleInformation(GetCurrentProcess(), hNtdll, &ntdllInfo, sizeof(ntdllInfo)); |
| 43 | |
| 44 | |
| 45 | std::ostringstream oss; |
| 46 | |
| 47 | oss << "已触发QQ文件校验退出函数, 一般情况下有可能是LLQQNT框架/插件导致的问题\n有任何问题请到Repo开issue, 带上你的截图\nCallStack:\n"; |
| 48 | |
| 49 | /*Skip self*/ |
| 50 | UNWIND_HISTORY_TABLE historyTable; |
| 51 | ZeroMemory(&historyTable, sizeof(UNWIND_HISTORY_TABLE)); |
| 52 | PRUNTIME_FUNCTION pFunction = RtlLookupFunctionEntry(controlPc, &imageBase, &historyTable); |
| 53 | if (pFunction != NULL) { |
| 54 | PVOID handlerData; |
| 55 | ULONG64 establisherFrame; |
| 56 | RtlVirtualUnwind(UNW_FLAG_NHANDLER, imageBase, controlPc, pFunction, &context, &handlerData, &establisherFrame, NULL); |
| 57 | controlPc = context.Pc; |
| 58 | frameBase = context.Fp; |
| 59 | } |
| 60 | /*---------*/ |
| 61 | |
| 62 | for (int i = 0; i < 16; ++i) { |
| 63 | if (controlPc == 0) { |
| 64 | break; |
| 65 | } |
| 66 | |
| 67 | if ((controlPc >= (DWORD64)hKernel32 && controlPc < (DWORD64)hKernel32 + kernel32Info.SizeOfImage)) |
| 68 | { |
| 69 | oss << "in module kernel32.dll | Maybe BaseThreadInitThunk\n"; |
| 70 | } |
| 71 | else if ((controlPc >= (DWORD64)hNtdll && controlPc < (DWORD64)hNtdll + ntdllInfo.SizeOfImage)) |
| 72 | { |
| 73 | oss << "in module ntdll.dll | Maybe RtlUserThreadStart\n"; |
| 74 | } |
| 75 | |
| 76 | oss << "Address: 0x" << std::hex << controlPc << std::endl; |
| 77 | |
| 78 | BYTE buffer[32]; |
| 79 | SIZE_T bytesRead; |
| 80 | if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID)controlPc, buffer, sizeof(buffer), &bytesRead)) |
| 81 | { |
| 82 | oss << "Data: "; |
| 83 | for (SIZE_T j = 0; j < bytesRead; ++j) { |
| 84 | oss << std::setw(2) << std::setfill('0') << std::hex << (int)buffer[j] << " "; |
| 85 | } |
| 86 | oss << std::endl; |
nothing calls this directly
no outgoing calls
no test coverage detected