首页
社区
课程
招聘
[求助]关于dbghelp中StackWalk64用法!
发表于: 2014-5-7 18:58 7147

[求助]关于dbghelp中StackWalk64用法!

2014-5-7 18:58
7147
function RealReadFromProcessMemory64(const AhProcess: THANDLE; const AqwBaseAddress:Int64; const AlpBuffer: Pointer; const ASize: DWORD; var ANumberOfBytesRead: DWORD):BOOL;stdcall;
var
  st  : DWORD;
begin
   Result := ReadProcessMemory(AhProcess, Pointer(AqwBaseAddress), AlpBuffer, ASize, st);
   ANumberOfBytesRead := st;
end;

function RealReadFromProcessMemory32(const AhProcess: THANDLE; const AqwBaseAddress:DWORD; const AlpBuffer: Pointer; const ASize: DWORD; var ANumberOfBytesRead: DWORD):BOOL;stdcall;
var
  st  : DWORD;
begin
   Result := ReadProcessMemory(AhProcess, Pointer(AqwBaseAddress), AlpBuffer, ASize, st);
   ANumberOfBytesRead := st;
end;


function GetStackFrame(var dwRetArray :StackframeArr):Integer;
var
 ContextRecord:TContext;
 StackFrame:TSTACKFRAME64;
begin
 ContextRecord.ContextFlags:=CONTEXT_FULL;
 if GetThreadContext(GetCurrentThread,ContextRecord) then
 begin
  SetLength(dwRetArray,0);    Result:=0;
  FillChar(StackFrame, sizeof(StackFrame), 0);
  StackFrame.AddrPC.Offset := ContextRecord.Eip;
  StackFrame.AddrStack.Offset := ContextRecord.Esp;
  StackFrame.AddrFrame.Offset := ContextRecord.Ebp;
  StackFrame.AddrPC.Mode :=AddrModeFlat;
  StackFrame.AddrStack.Mode :=AddrModeFlat;
  StackFrame.AddrFrame.Mode := AddrModeFlat;


   while StackWalk64(IMAGE_FILE_MACHINE_I386,GetCurrentProcess, GetCurrentThread,StackFrame,@ContextRecord,@RealReadFromProcessMemory64,nil,nil,nil) do
   //while StackWalk(IMAGE_FILE_MACHINE_I386,GetCurrentProcess, GetCurrentThread,StackFrame,@ContextRecord,@RealReadFromProcessMemory32,nil,nil,nil) do
   begin
     if (StackFrame.AddrReturn.Offset <> 0) then
     begin
       //FLogManager.Log('Stack frame:' + IntToHex(Cardinal(Pointer(StackFrame.AddrPC.Offset)), 8));
       SetLength(dwRetArray,High(dwRetArray)+2);
       dwRetArray[High(dwRetArray)]:=StackFrame.AddrReturn.Offset;
       Inc(Result);
     end;
   end;
 end;
end;


调用如下

procedure fun3;
var
 StackframeArr1:StackframeArr;
 count,I:Integer;
begin

 count:=GetStackFrame(StackframeArr1);
 if count>0 then
 begin
  for I := 0 to count - 1 do
  begin
    Form1.Memo1.Lines.Add(IntToHex(StackframeArr1[I],8)); //显示
  end;
 end;
end;

procedure fun2;
begin
  fun3;
end;

procedure fun1;
begin
  fun2;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  fun1;
end;


可惜显示失败 在第一次调用StackWalk64成功后  StackFrame.AddrReturn.Offset显示为0
然后 后面的StackWalk64 均失败了! 求指教

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
2
SymInitialize也调用了
2014-5-7 21:00
0
雪    币: 73
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
MSDN:
You cannot get a valid context for a running thread. Use the SuspendThread function to suspend the thread before calling GetThreadContext.

ContextRecord.ContextFlags:=CONTEXT_FULL;
if GetThreadContext(GetCurrentThread,ContextRecord) then

这句改成

RtlCaptureContext(&ContextRecord);                        // Get context.

我这个是vc的调用方式,应该是这个问题, 你试试看(zh)
2014-5-7 22:06
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
4
还是不行
2014-5-8 00:41
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
5
同样的代码 用VC写就可以 why why why
2014-5-8 00:42
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
6
解决了  delphi编译 开启 {$Z4}开关
2014-5-8 02:19
0
游客
登录 | 注册 方可回帖
返回
//