29 typedef struct _PH_SYMBOL_MODULE
 
   62 static HANDLE PhNextFakeHandle = (HANDLE)0;
 
   65 #define PH_LOCK_SYMBOLS() PhAcquireFastLockExclusive(&PhSymMutex) 
   66 #define PH_UNLOCK_SYMBOLS() PhReleaseFastLockExclusive(&PhSymMutex) 
  105     _In_opt_ PVOID DbgHelpBase
 
  108     HMODULE dbghelpHandle;
 
  109     HMODULE symsrvHandle;
 
  116         dbghelpHandle = DbgHelpBase;
 
  118         dbghelpHandle = GetModuleHandle(L
"dbghelp.dll");
 
  120     symsrvHandle = GetModuleHandle(L
"symsrv.dll");
 
  122     SymInitialize_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymInitialize");
 
  123     SymCleanup_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymCleanup");
 
  124     if (!(
SymEnumSymbolsW_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymEnumSymbolsW")))
 
  126     if (!(
SymFromAddrW_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymFromAddrW")))
 
  127         SymFromAddr_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymFromAddr");
 
  128     if (!(
SymFromNameW_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymFromNameW")))
 
  129         SymFromName_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymFromName");
 
  134     SymGetOptions_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymGetOptions");
 
  135     SymSetOptions_I = (PVOID)GetProcAddress(dbghelpHandle, 
"SymSetOptions");
 
  144     StackWalk64_I = (PVOID)GetProcAddress(dbghelpHandle, 
"StackWalk64");
 
  169         static ACCESS_MASK accesses[] =
 
  171             STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff, 
 
  181         for (i = 0; i < 
sizeof(accesses) / 
sizeof(ACCESS_MASK); i++)
 
  198         symbolProvider->
ProcessHandle = (HANDLE)((ULONG_PTR)fakeHandle + 1);
 
  201     return symbolProvider;
 
  210     PLIST_ENTRY listEntry;
 
  231         listEntry = listEntry->Flink;
 
  250     return STATUS_SUCCESS;
 
  254     _In_ HANDLE hProcess,
 
  255     _In_ ULONG ActionCode,
 
  256     _In_opt_ ULONG64 CallbackData,
 
  257     _In_opt_ ULONG64 UserContext
 
  262     PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 callbackData;
 
  276             data->
Type = ActionCode;
 
  280                 callbackData = (PIMAGEHLP_DEFERRED_SYMBOL_LOADW64)CallbackData;
 
  282                 data->
CheckSum = callbackData->CheckSum;
 
  283                 data->
TimeStamp = callbackData->TimeDateStamp;
 
  322             SymbolProvider->IsRegistered = 
TRUE;
 
  346     return uint64cmp(symbolModule1->BaseAddress, symbolModule2->BaseAddress);
 
  351     _In_ ULONG64 Address,
 
  353     _Out_opt_ PULONG Displacement,
 
  357     IMAGEHLP_LINEW64 line;
 
  367     line.SizeOfStruct = 
sizeof(IMAGEHLP_LINEW64);
 
  374             SymbolProvider->ProcessHandle,
 
  385         IMAGEHLP_LINE64 lineA;
 
  387         lineA.SizeOfStruct = 
sizeof(IMAGEHLP_LINE64);
 
  390             SymbolProvider->ProcessHandle,
 
  399             line.LineNumber = lineA.LineNumber;
 
  400             line.Address = lineA.Address;
 
  409     *FileName = fileName;
 
  412         *Displacement = displacement;
 
  416         Information->LineNumber = line.LineNumber;
 
  417         Information->Address = line.Address;
 
  425     _In_ ULONG64 Address,
 
  434     ULONG64 foundBaseAddress;
 
  437     foundFileName = NULL;
 
  438     foundBaseAddress = 0;
 
  442     lookupModule.BaseAddress = Address;
 
  478     if (module && Address < module->BaseAddress + module->Size)
 
  481         foundBaseAddress = module->BaseAddress;
 
  490             *FileName = foundFileName;
 
  498     return foundBaseAddress;
 
  502     _Out_ PSYMBOL_INFOW SymbolInfoW,
 
  503     _In_ PSYMBOL_INFO SymbolInfoA
 
  506     SymbolInfoW->TypeIndex = SymbolInfoA->TypeIndex;
 
  507     SymbolInfoW->Index = SymbolInfoA->Index;
 
  508     SymbolInfoW->Size = SymbolInfoA->Size;
 
  509     SymbolInfoW->ModBase = SymbolInfoA->ModBase;
 
  510     SymbolInfoW->Flags = SymbolInfoA->Flags;
 
  511     SymbolInfoW->Value = SymbolInfoA->Value;
 
  512     SymbolInfoW->Address = SymbolInfoA->Address;
 
  513     SymbolInfoW->Register = SymbolInfoA->Register;
 
  514     SymbolInfoW->Scope = SymbolInfoA->Scope;
 
  515     SymbolInfoW->Tag = SymbolInfoA->Tag;
 
  516     SymbolInfoW->NameLen = 0;
 
  518     if (SymbolInfoA->NameLen != 0 && SymbolInfoW->MaxNameLen != 0)
 
  522         copyCount = min(SymbolInfoA->NameLen, SymbolInfoW->MaxNameLen - 1);
 
  528             SymbolInfoW->MaxNameLen,
 
  532             SymbolInfoW->NameLen = copyCount;
 
  539     _In_ ULONG64 Address,
 
  543     _Out_opt_ PULONG64 Displacement
 
  546     PSYMBOL_INFOW symbolInfo;
 
  550     ULONG64 displacement;
 
  559         if (FileName) *FileName = NULL;
 
  560         if (SymbolName) *SymbolName = NULL;
 
  561         if (Displacement) *Displacement = 0;
 
  572     memset(symbolInfo, 0, 
sizeof(SYMBOL_INFOW));
 
  573     symbolInfo->SizeOfStruct = 
sizeof(SYMBOL_INFOW);
 
  589             SymbolProvider->ProcessHandle,
 
  594         nameLength = symbolInfo->NameLen;
 
  599             symbolInfo = PhAllocate(FIELD_OFFSET(SYMBOL_INFOW, Name) + nameLength * 2 + 2);
 
  600             memset(symbolInfo, 0, 
sizeof(SYMBOL_INFOW));
 
  601             symbolInfo->SizeOfStruct = 
sizeof(SYMBOL_INFOW);
 
  602             symbolInfo->MaxNameLen = nameLength + 1;
 
  605                 SymbolProvider->ProcessHandle,
 
  614         PSYMBOL_INFO symbolInfoA;
 
  617         memset(symbolInfoA, 0, 
sizeof(SYMBOL_INFO));
 
  618         symbolInfoA->SizeOfStruct = 
sizeof(SYMBOL_INFO);
 
  622             SymbolProvider->ProcessHandle,
 
  627         nameLength = symbolInfoA->NameLen;
 
  632             symbolInfoA = PhAllocate(FIELD_OFFSET(SYMBOL_INFO, Name) + nameLength + 1);
 
  633             memset(symbolInfoA, 0, 
sizeof(SYMBOL_INFO));
 
  634             symbolInfoA->SizeOfStruct = 
sizeof(SYMBOL_INFO);
 
  635             symbolInfoA->MaxNameLen = nameLength + 1;
 
  638                 SymbolProvider->ProcessHandle,
 
  646             symbolInfo = PhAllocate(FIELD_OFFSET(SYMBOL_INFOW, Name) + nameLength * 2 + 2);
 
  647             memset(symbolInfo, 0, 
sizeof(SYMBOL_INFOW));
 
  648             symbolInfo->SizeOfStruct = 
sizeof(SYMBOL_INFOW);
 
  649             symbolInfo->MaxNameLen = nameLength + 1;
 
  660     if (symbolInfo->ModBase == 0)
 
  674         lookupSymbolModule.BaseAddress = symbolInfo->ModBase;
 
  705     if (symbolInfo->NameLen == 0)
 
  725     if (displacement == 0)
 
  751         *ResolveLevel = resolveLevel;
 
  757         *Displacement = displacement;
 
  773     PSYMBOL_INFOW symbolInfo;
 
  782     symbolInfo = (PSYMBOL_INFOW)symbolInfoBuffer;
 
  783     memset(symbolInfo, 0, 
sizeof(SYMBOL_INFOW));
 
  784     symbolInfo->SizeOfStruct = 
sizeof(SYMBOL_INFOW);
 
  794             SymbolProvider->ProcessHandle,
 
  802         PSYMBOL_INFO symbolInfoA;
 
  805         symbolInfoA = (PSYMBOL_INFO)buffer;
 
  806         memset(symbolInfoA, 0, 
sizeof(SYMBOL_INFO));
 
  807         symbolInfoA->SizeOfStruct = 
sizeof(SYMBOL_INFO);
 
  813             SymbolProvider->ProcessHandle,
 
  833     Information->Address = symbolInfo->Address;
 
  834     Information->ModuleBase = symbolInfo->ModBase;
 
  835     Information->Index = symbolInfo->Index;
 
  836     Information->Size = symbolInfo->Size;
 
  844     _In_ ULONG64 BaseAddress,
 
  862     lookupSymbolModule.BaseAddress = BaseAddress;
 
  874             SymbolProvider->ProcessHandle,
 
  890             SymbolProvider->ProcessHandle,
 
  907     lookupSymbolModule.BaseAddress = BaseAddress;
 
  913         symbolModule->BaseAddress = BaseAddress;
 
  914         symbolModule->Size = 
Size;
 
  915         symbolModule->FileName = 
PhGetFullPath(FileName, &symbolModule->BaseNameIndex);
 
  918         assert(!existingLinks);
 
  919         InsertTailList(&SymbolProvider->ModulesListHead, &symbolModule->ListEntry);
 
  926         if (GetLastError() != ERROR_SUCCESS)
 
  987 NTSTATUS PhpLookupDynamicFunctionTable(
 
  988     _In_ HANDLE ProcessHandle,
 
  989     _In_ ULONG64 Address,
 
  990     _Out_opt_ PDYNAMIC_FUNCTION_TABLE *FunctionTableAddress,
 
  991     _Out_opt_ PDYNAMIC_FUNCTION_TABLE FunctionTable,
 
  992     _Out_writes_bytes_opt_(OutOfProcessCallbackDllBufferSize) PWCHAR OutOfProcessCallbackDllBuffer,
 
  993     _In_ ULONG OutOfProcessCallbackDllBufferSize,
 
  998     PLIST_ENTRY (NTAPI *rtlGetFunctionTableListHead)(
VOID);
 
  999     PLIST_ENTRY tableListHead;
 
 1000     LIST_ENTRY tableListHeadEntry;
 
 1001     PLIST_ENTRY tableListEntry;
 
 1002     PDYNAMIC_FUNCTION_TABLE functionTableAddress;
 
 1003     DYNAMIC_FUNCTION_TABLE functionTable;
 
 1005     SIZE_T numberOfBytesRead;
 
 1011     if (!rtlGetFunctionTableListHead)
 
 1012         return STATUS_PROCEDURE_NOT_FOUND;
 
 1014     tableListHead = rtlGetFunctionTableListHead();
 
 1021         &tableListHeadEntry,
 
 1027     tableListEntry = tableListHeadEntry.Flink;
 
 1032         functionTableAddress = CONTAINING_RECORD(tableListEntry, DYNAMIC_FUNCTION_TABLE, ListEntry);
 
 1036             functionTableAddress,
 
 1038             sizeof(DYNAMIC_FUNCTION_TABLE),
 
 1043         if (Address >= functionTable.MinimumAddress && Address < functionTable.MaximumAddress)
 
 1045             if (OutOfProcessCallbackDllBuffer)
 
 1047                 if (functionTable.OutOfProcessCallbackDll)
 
 1052                     memset(OutOfProcessCallbackDllBuffer, 0xff, OutOfProcessCallbackDllBufferSize);
 
 1055                         functionTable.OutOfProcessCallbackDll,
 
 1056                         OutOfProcessCallbackDllBuffer,
 
 1057                         OutOfProcessCallbackDllBufferSize,
 
 1061                     if (status != STATUS_PARTIAL_COPY && !
NT_SUCCESS(status))
 
 1066                     for (i = 0; i < OutOfProcessCallbackDllBufferSize / 
sizeof(WCHAR); i++)
 
 1068                         if (OutOfProcessCallbackDllBuffer[i] == 0)
 
 1072                             if (OutOfProcessCallbackDllString)
 
 1074                                 OutOfProcessCallbackDllString->Buffer = OutOfProcessCallbackDllBuffer;
 
 1075                                 OutOfProcessCallbackDllString->Length = (USHORT)(i * 
sizeof(WCHAR));
 
 1076                                 OutOfProcessCallbackDllString->MaximumLength = OutOfProcessCallbackDllString->Length;
 
 1086                         return STATUS_BUFFER_OVERFLOW;
 
 1090                     OutOfProcessCallbackDllBuffer[0] = 0;
 
 1092                     if (OutOfProcessCallbackDllString)
 
 1094                         OutOfProcessCallbackDllString->Buffer = NULL;
 
 1095                         OutOfProcessCallbackDllString->Length = 0;
 
 1096                         OutOfProcessCallbackDllString->MaximumLength = 0;
 
 1101             if (FunctionTableAddress)
 
 1102                 *FunctionTableAddress = functionTableAddress;
 
 1105                 *FunctionTable = functionTable;
 
 1107             return STATUS_SUCCESS;
 
 1110         tableListEntry = functionTable.ListEntry.Flink;
 
 1114     return STATUS_NOT_FOUND;
 
 1117 PRUNTIME_FUNCTION PhpLookupFunctionEntry(
 
 1118     _In_ PRUNTIME_FUNCTION Functions,
 
 1119     _In_ ULONG NumberOfFunctions,
 
 1120     _In_ BOOLEAN Sorted,
 
 1121     _In_ ULONG64 RelativeControlPc
 
 1130         if (NumberOfFunctions == 0)
 
 1134         high = NumberOfFunctions - 1;
 
 1138             i = (low + high) / 2;
 
 1140             if (RelativeControlPc < Functions[i].BeginAddress)
 
 1142             else if (RelativeControlPc >= Functions[i].EndAddress)
 
 1145                 return &Functions[i];
 
 1146         } 
while (low <= high);
 
 1150         for (i = 0; i < NumberOfFunctions; i++)
 
 1152             if (RelativeControlPc >= Functions[i].BeginAddress && RelativeControlPc < Functions[i].EndAddress)
 
 1153                 return &Functions[i];
 
 1160 NTSTATUS PhpAccessCallbackFunctionTable(
 
 1161     _In_ HANDLE ProcessHandle,
 
 1162     _In_ PVOID FunctionTableAddress,
 
 1164     _Out_ PRUNTIME_FUNCTION *Functions,
 
 1165     _Out_ PULONG NumberOfFunctions
 
 1168     static PH_STRINGREF knownFunctionTableDllsKeyName = 
PH_STRINGREF_INIT(L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\KnownFunctionTableDlls");
 
 1174     ANSI_STRING outOfProcessFunctionTableCallbackName;
 
 1175     POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK outOfProcessFunctionTableCallback;
 
 1177     if (!OutOfProcessCallbackDllString->Buffer)
 
 1178         return STATUS_INVALID_PARAMETER;
 
 1186         &knownFunctionTableDllsKeyName,
 
 1194     if (status == STATUS_OBJECT_NAME_NOT_FOUND)
 
 1195         return STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT;
 
 1197     status = LdrLoadDll(NULL, NULL, OutOfProcessCallbackDllString, &dllHandle);
 
 1202     RtlInitAnsiString(&outOfProcessFunctionTableCallbackName, OUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK_EXPORT_NAME);
 
 1203     status = LdrGetProcedureAddress(dllHandle, &outOfProcessFunctionTableCallbackName, 0, (PVOID *)&outOfProcessFunctionTableCallback);
 
 1207         status = outOfProcessFunctionTableCallback(
 
 1209             FunctionTableAddress,
 
 1215     LdrUnloadDll(dllHandle);
 
 1220 NTSTATUS PhpAccessNormalFunctionTable(
 
 1221     _In_ HANDLE ProcessHandle,
 
 1222     _In_ PDYNAMIC_FUNCTION_TABLE FunctionTable,
 
 1223     _Out_ PRUNTIME_FUNCTION *Functions,
 
 1224     _Out_ PULONG NumberOfFunctions
 
 1229     PRUNTIME_FUNCTION functions;
 
 1232     if (FunctionTable->EntryCount > 0x100000)
 
 1233         return STATUS_BUFFER_OVERFLOW;
 
 1235     bufferSize = FunctionTable->EntryCount * 
sizeof(RUNTIME_FUNCTION);
 
 1239         return STATUS_NO_MEMORY;
 
 1241     status = 
PhReadVirtualMemory(ProcessHandle, FunctionTable->FunctionTable, functions, bufferSize, NULL);
 
 1245         *Functions = functions;
 
 1246         *NumberOfFunctions = FunctionTable->EntryCount;
 
 1256 NTSTATUS PhAccessOutOfProcessFunctionEntry(
 
 1257     _In_ HANDLE ProcessHandle,
 
 1258     _In_ ULONG64 ControlPc,
 
 1259     _Out_ PRUNTIME_FUNCTION Function
 
 1263     PDYNAMIC_FUNCTION_TABLE functionTableAddress;
 
 1264     DYNAMIC_FUNCTION_TABLE functionTable;
 
 1265     WCHAR outOfProcessCallbackDll[512];
 
 1267     PRUNTIME_FUNCTION functions;
 
 1268     ULONG numberOfFunctions;
 
 1269     PRUNTIME_FUNCTION 
function;
 
 1271     if (!
NT_SUCCESS(status = PhpLookupDynamicFunctionTable(
 
 1274         &functionTableAddress,
 
 1276         outOfProcessCallbackDll,
 
 1277         sizeof(outOfProcessCallbackDll),
 
 1278         &outOfProcessCallbackDllString
 
 1284     if (functionTable.Type == RF_CALLBACK)
 
 1286         if (!
NT_SUCCESS(status = PhpAccessCallbackFunctionTable(
 
 1288             functionTableAddress,
 
 1289             &outOfProcessCallbackDllString,
 
 1297         function = PhpLookupFunctionEntry(functions, numberOfFunctions, 
FALSE, ControlPc - functionTable.BaseAddress);
 
 1300             *Function = *
function;
 
 1302             status = STATUS_NOT_FOUND;
 
 1308         if (!
NT_SUCCESS(status = PhpAccessNormalFunctionTable(
 
 1318         function = PhpLookupFunctionEntry(functions, numberOfFunctions, functionTable.Type == RF_SORTED, ControlPc - functionTable.BaseAddress);
 
 1321             *Function = *
function;
 
 1323             status = STATUS_NOT_FOUND;
 
 1334     _In_ HANDLE hProcess,
 
 1340     DYNAMIC_FUNCTION_TABLE functionTable;
 
 1344     if (
NT_SUCCESS(PhpLookupDynamicFunctionTable(
 
 1354         base = functionTable.BaseAddress;
 
 1371     _In_ HANDLE hProcess,
 
 1372     _In_ DWORD64 AddrBase
 
 1376     static RUNTIME_FUNCTION lastRuntimeFunction;
 
 1382     if (
NT_SUCCESS(PhAccessOutOfProcessFunctionEntry(hProcess, AddrBase, &lastRuntimeFunction)))
 
 1383         entry = &lastRuntimeFunction;
 
 1397     _In_ ULONG MachineType,
 
 1398     _In_ HANDLE ProcessHandle,
 
 1399     _In_ HANDLE ThreadHandle,
 
 1401     _Inout_ PVOID ContextRecord,
 
 1416     if (!FunctionTableAccessRoutine)
 
 1418         if (MachineType == IMAGE_FILE_MACHINE_AMD64)
 
 1424     if (!GetModuleBaseRoutine)
 
 1426         if (MachineType == IMAGE_FILE_MACHINE_AMD64)
 
 1440         FunctionTableAccessRoutine,
 
 1441         GetModuleBaseRoutine,
 
 1450     _In_ HANDLE ProcessHandle,
 
 1452     _In_ HANDLE FileHandle,
 
 1463         SetLastError(ERROR_PROC_NOT_FOUND);
 
 1489     _In_ STACKFRAME64 *StackFrame64,
 
 1496     ThreadStackFrame->PcAddress = (PVOID)StackFrame64->AddrPC.Offset;
 
 1497     ThreadStackFrame->ReturnAddress = (PVOID)StackFrame64->AddrReturn.Offset;
 
 1498     ThreadStackFrame->FrameAddress = (PVOID)StackFrame64->AddrFrame.Offset;
 
 1499     ThreadStackFrame->StackAddress = (PVOID)StackFrame64->AddrStack.Offset;
 
 1500     ThreadStackFrame->BStoreAddress = (PVOID)StackFrame64->AddrBStore.Offset;
 
 1502     for (i = 0; i < 4; i++)
 
 1503         ThreadStackFrame->Params[i] = (PVOID)StackFrame64->Params[i];
 
 1505     ThreadStackFrame->Flags = Flags;
 
 1507     if (StackFrame64->FuncTableEntry)
 
 1539     _In_ HANDLE ThreadHandle,
 
 1540     _In_opt_ HANDLE ProcessHandle,
 
 1545     _In_opt_ PVOID Context
 
 1548     NTSTATUS status = STATUS_SUCCESS;
 
 1549     BOOLEAN suspended = 
FALSE;
 
 1550     BOOLEAN processOpened = 
FALSE;
 
 1551     BOOLEAN isCurrentThread = 
FALSE;
 
 1552     BOOLEAN isSystemProcess = 
FALSE;
 
 1572                 ClientId->UniqueProcess
 
 1577         processOpened = 
TRUE;
 
 1583         if (ClientId->UniqueThread == NtCurrentTeb()->ClientId.UniqueThread)
 
 1584             isCurrentThread = 
TRUE;
 
 1586             isSystemProcess = 
TRUE;
 
 1590         if (ThreadHandle == NtCurrentThread())
 
 1592             isCurrentThread = 
TRUE;
 
 1597                 isCurrentThread = 
TRUE;
 
 1599                 isSystemProcess = 
TRUE;
 
 1605     if (!isCurrentThread && !isSystemProcess)
 
 1607         if (
NT_SUCCESS(NtSuspendThread(ThreadHandle, NULL)))
 
 1614         PVOID stack[62 - 1]; 
 
 1615         ULONG capturedFrames;
 
 1621             sizeof(stack) / 
sizeof(PVOID),
 
 1631             for (i = 0; i < capturedFrames; i++)
 
 1636                 if (!Callback(&threadStackFrame, Context))
 
 1647         STACKFRAME64 stackFrame;
 
 1651         context.ContextFlags = CONTEXT_ALL;
 
 1657             goto SkipAmd64Stack;
 
 1659         memset(&stackFrame, 0, 
sizeof(STACKFRAME64));
 
 1660         stackFrame.AddrPC.Mode = AddrModeFlat;
 
 1661         stackFrame.AddrPC.Offset = context.Rip;
 
 1662         stackFrame.AddrStack.Mode = AddrModeFlat;
 
 1663         stackFrame.AddrStack.Offset = context.Rsp;
 
 1664         stackFrame.AddrFrame.Mode = AddrModeFlat;
 
 1665         stackFrame.AddrFrame.Offset = context.Rbp;
 
 1670                 IMAGE_FILE_MACHINE_AMD64,
 
 1684             if (!stackFrame.AddrPC.Offset || stackFrame.AddrPC.Offset == -1)
 
 1691             if (!Callback(&threadStackFrame, Context))
 
 1702         STACKFRAME64 stackFrame;
 
 1707         context.ContextFlags = CONTEXT_ALL;
 
 1715         WOW64_CONTEXT context;
 
 1717         context.ContextFlags = WOW64_CONTEXT_ALL;
 
 1719         if (!
NT_SUCCESS(status = NtQueryInformationThread(
 
 1723             sizeof(WOW64_CONTEXT),
 
 1729         memset(&stackFrame, 0, 
sizeof(STACKFRAME64));
 
 1730         stackFrame.AddrPC.Mode = AddrModeFlat;
 
 1731         stackFrame.AddrPC.Offset = context.Eip;
 
 1732         stackFrame.AddrStack.Mode = AddrModeFlat;
 
 1733         stackFrame.AddrStack.Offset = context.Esp;
 
 1734         stackFrame.AddrFrame.Mode = AddrModeFlat;
 
 1735         stackFrame.AddrFrame.Offset = context.Ebp;
 
 1740                 IMAGE_FILE_MACHINE_I386,
 
 1754             if (!stackFrame.AddrPC.Offset || stackFrame.AddrPC.Offset == -1)
 
 1761             if (!Callback(&threadStackFrame, Context))
 
 1765             context.Eip = PtrToUlong(threadStackFrame.
PcAddress);
 
 1766             stackFrame.AddrPC.Offset = PtrToUlong(threadStackFrame.
PcAddress);
 
 1767             context.Ebp = PtrToUlong(threadStackFrame.
FrameAddress);
 
 1768             stackFrame.AddrFrame.Offset = PtrToUlong(threadStackFrame.
FrameAddress);
 
 1769             context.Esp = PtrToUlong(threadStackFrame.
StackAddress);
 
 1770             stackFrame.AddrStack.Offset = PtrToUlong(threadStackFrame.
StackAddress);
 
 1778         NtResumeThread(ThreadHandle, NULL);
 
 1781         NtClose(ProcessHandle);