开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 9280|回复: 9
收起左侧

[其它] CE中的“THREADSTACK0”的地址获取

[复制链接]
结帖率:60% (3/5)
发表于 2022-5-7 15:17:48 | 显示全部楼层 |阅读模式   广西壮族自治区柳州市
CE扫描地址经常会出现"THREADSTACK0"-XXXX  "THREADSTACK1"-XXXX这种格式的基址,以前没怎么在意,因为大部分进程都可以找到模块+偏移
最新遇上一个扫不到模块的进程,扫到的全是这种格式,就有一个自己把这个“THREADSTACK”转换成地址的想法。
QQ截图20220507142207.jpg
怎么把THREADSTACK0转换成0X127FD88呢,

百度了一圈这玩意没找到什么有用的信息,只有一二个几年前别人问题过的此类问题,没有看到满意答案,只能靠自己了。

看字面意思“THREADSTACK"就是线程栈,我的理解0表示进程的第一个线程,也就是主线程,1表示第二个线程,大体上知道它是个啥玩意就好办。
继续百度线程环境块
QQ截图20220507141754.jpg
看到NT_TIB.StackBase我以为它就是这玩意,结果觉在意料之外,它跟这个数值总是差了那么一点,突然想到我手上有某版CE的源码,就试着去找找
QQ截图20220507132220.jpg
可以看到这个栈地址是通个GetStackStar这个函数去获取,然后去找它这个函数

function GetStackStart(threadnr: integer=0): ptruint;
var
  c: tcontext;    //do not move, or be sure it's on a proper alignment
  tbi: THREAD_BASIC_INFORMATION;
  stacktop: ptruint;
  x: PtrUInt;
  h: thandle;
  ths: thandle;
  te32: TThreadEntry32;
  i: integer;
  ldtentry: TLDTENTRY;
  mi: TModuleInfo;
  buf: pointer;
  buf32: PDwordArray absolute buf;
  buf64: PQWordArray absolute buf;
//gets the stack base of the main thread, then checks where the "exitThread" entry is located and uses that -pointersize as the stackbase
begin
  result:=0;
  //get the first thread of this process
  if symhandler.getmodulebyname('kernel32.dll', mi)=false then
  begin
    symhandler.loadmodulelist;
    if symhandler.getmodulebyname('kernel32.dll', mi)=false then
      exit;
  end;
  ths:=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
  if ths<>INVALID_HANDLE_VALUE then
  begin
    zeromemory(@te32,sizeof(te32));
    te32.dwSize:=sizeof(te32);
    if Thread32First(ths, te32) then
    repeat
      if te32.th32OwnerProcessID=processid then
      begin
        //found a thread
        if threadnr=0 then //is it the one I want ?
        begin
          h:=OpenThread(THREAD_QUERY_INFORMATION or THREAD_GET_CONTEXT, false, te32.th32ThreadID);
          if (h<>0) then
          begin
            stacktop:=0;
            if processhandler.is64Bit then
            begin
              x:=0;
              i:=NtQueryInformationThread(h, ThreadBasicInformation, @tbi, sizeof(tbi), @x);
              if i=0 then
                ReadProcessMemory(processhandle, pointer(ptruint(tbi.TebBaseAddress)+8), @stacktop, 8, x);
            end
            else
            begin
              zeromemory(@c,sizeof(c));
              c.ContextFlags:=CONTEXT_SEGMENTS;
              if GetThreadContext(h, c) then
              begin
                if GetThreadSelectorEntry(h, c.segFs, ldtentry) then
                  ReadProcessMemory(processhandle, pointer(ptruint(ldtentry.BaseLow+ldtentry.HighWord.Bytes.BaseMid shl 16+ldtentry.HighWord.Bytes.BaseHi shl 24)+4), @stacktop, 4, x);
              end;
            end;
            closehandle(h);
            if stacktop<>0 then
            begin
              //find the stack entry pointing to the function that calls "ExitXXXXXThread"
              //Fun thing to note: It's the first entry that points to a address in kernel32
              getmem(buf,4096);
              if ReadProcessMemory(processhandle, pointer(stacktop-4096), buf, 4096, x) then
              begin
                if processhandler.is64Bit then
                begin
                  for i:=(4096 div 8)-1 downto 0 do
                    if inrangeq(buf64, mi.baseaddress, mi.baseaddress+mi.basesize) then
                    begin
                      result:=stacktop-4096+i*8;
                      break;
                    end;
                end
                else
                begin
                  for i:=(4096 div 4)-1 downto 0 do
                    if inrangeq(buf32, mi.baseaddress, mi.baseaddress+mi.basesize) then
                    begin
                      result:=stacktop-4096+i*4;
                      break;
                    end;
                end;
              end;
              freemem(buf);
            end;
          end;
          break;
        end;
        dec(threadnr);
      end;
    luntil Thread32Next(ths, te32)=false;
    closehandle(ths);
  end;
end;

开始有点不明白if symhandler.getmodulebyname('kernel32.dll', mi)=false then,这东西跟kernel32.dll有什么关系,再看下看它确实是取了NT_TIB.StackBase  ReadProcessMemory(processhandle, pointer(ptruint(tbi.TebBaseAddress)+8), @stacktop, 8, x);
再往下看,它还取了NT_TIB.StackBase之前4KB的数据去跟kernel32的模块地址对比。。。。。。正郁闷的时候突然看到CE上的数据,回到第一张图,它每个线程栈指针都指向了同一个地方0X7FFC2AB87BD4,去看看这是何方妖物,

QQ截图20220507145134.jpg
再看看32位进程指向的0X75E76340
QQ截图20220507145556.jpg
至此终于把它这个代码看明白了
CreateToolhelp32Snapshot遍历线程
NtQueryInformationThread 的0号功能取TEB信息
通过TebBaseAddress得到StackBase
再遍历StackBase-4096 到StackBase地方,如果有地址指向kernel32模块,那这个地址就是它的THREADSTACK
跟居这个方法可以读跟CE一模一样的数据
QQ截图20220507151424.jpg
这是explorer的线程,图1上也是explorer的前三个线程,栈地址是不是一模一样


评分

参与人数 2好评 +2 精币 +5 收起 理由
baitso + 1 + 2 开源精神必须支持~
Suky + 1 + 3 有用的知识增加了

查看全部评分


签到天数: 22 天

发表于 2024-9-6 22:18:59 | 显示全部楼层   广东省广州市
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
发表于 2022-9-5 12:46:33 | 显示全部楼层   四川省绵阳市
还是完全不明白易语言该怎么写
回复 支持 反对

使用道具 举报

结帖率:100% (16/16)

签到天数: 1 天

发表于 2022-8-14 13:52:51 | 显示全部楼层   重庆市重庆市
直接在CE中手动添加地址 THREADSTACK0-xxx  注意是整体没偏移  点击确定 他的模块jz就出来了 地址栏的是模块jz
回复 支持 反对

使用道具 举报

发表于 2022-8-10 00:27:35 | 显示全部楼层   香港特别行政区*
请问易语言有现成的源码或者模块吗? 小白来说太难了
回复 支持 反对

使用道具 举报

发表于 2022-8-9 22:04:39 | 显示全部楼层   香港特别行政区*
易语言中如何编码获得这个地址呢 求代码
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
发表于 2022-5-11 22:07:01 | 显示全部楼层   广东省东莞市
大佬中的 大佬
回复 支持 反对

使用道具 举报

发表于 2022-5-9 12:48:11 | 显示全部楼层   湖南省永州市
多谢分享 点赞
回复 支持 反对

使用道具 举报

结帖率:89% (110/123)

签到天数: 4 天

发表于 2022-5-7 17:00:54 | 显示全部楼层   山东省青岛市
非常好的文章,感谢分享.
回复 支持 反对

使用道具 举报

结帖率:86% (6/7)

签到天数: 1 天

发表于 2022-5-7 16:58:32 | 显示全部楼层   江苏省常州市
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表