首页
社区
课程
招聘
请帮忙看看这段代码为什么需要这样做
发表于: 2007-1-15 21:34 4057

请帮忙看看这段代码为什么需要这样做

2007-1-15 21:34
4057
我在分析某程序时经常会看到这段代码被调用,而据我分析这段代码只是在堆上分配了一些内存,并将该内存提供给上一调用者使用
120077F0   /$  51                     push ecx
120077F1   |.  8D4C24 04              lea ecx,dword ptr ss:[esp+4]
120077F5   |.  2BC8                   sub ecx,eax
120077F7   |.  1BC0                   sbb eax,eax
120077F9   |.  F7D0                   not eax
120077FB   |.  23C8                   and ecx,eax
120077FD   |.  8BC4                   mov eax,esp
##[1]## 这里不解,与0xfffff000与之后,我原以为是对齐到4KB字节的边界但
120077FF   |.  25 00F0FFFF            and eax,FFFFF000
12007804   |>  3BC8                   /cmp ecx,eax
12007806   |.  72 0A                  |jb short yb_mem.12007812
这里将ecx值放入eax后直接与esp交换,好像和4KB边界没什么关系
所以这个循环很奇怪,搞不懂为啥这样写
12007808   |.  8BC1                   |mov eax,ecx
1200780A   |.  59                     |pop ecx
1200780B   |.  94                     |xchg eax,esp
1200780C   |.  8B00                   |mov eax,dword ptr ds:[eax]
1200780E   |.  890424                 |mov dword ptr ss:[esp],eax
12007811   |.  C3                     |retn
12007812   |>  2D 00100000            |sub eax,1000
12007817   |.  8500                   |test dword ptr ds:[eax],eax
12007819   \.^ EB E9                  \jmp short yb_mem.12007804

另一个函数,调用上面的函数
12002040 <>/$  6A FF                  push -1
12002042   |.  68 67650112            push yb_mem.12016567
12002047   |.  64:A1 00000000         mov eax,dword ptr fs:[0]
1200204D   |.  50                     push eax
1200204E   |.  B8 44280000            mov eax,2844
以上的函数在这里被调用,通过寄存器EAX 传值
12002053   |.  E8 98570000            call yb_mem.120077F0

g_StackKey1是在初始化时生成的某随机值,之后不变
##2##  还有这里也很奇怪
12002058   |.  A1 78C10112            mov eax,dword ptr ds:[<g_StackKey1>]
1200205D   |.  33C4                   xor eax,esp
1200205F   |.  898424 40280000        mov dword ptr ss:[esp+2840],eax
...
...
...
上面2号位置的值最终在这里取出,再次异或esp,再与g_StackKey1比较
1200230B   |.  8B8C24 40280000        mov ecx,dword ptr ss:[esp+2840]
12002312   |.  33CC                   xor ecx,esp
xxxxxxxx       3B0D 78C10112          cmp ecx,dword ptr ds:[<g_StackKey1>]
xxxxxxxx    .  75 02                  jnz short yb_mem.12006A60
...
函数结束

问题: ##1##位置为什么要与0xfffff000异或?是为了4KB字节边界对齐吗?
       但eax小于ecx后,又将esp指向ecx,循环似乎没什么用啊?

       ##2##位置与esp异或,结束后再异或得到原来值,再比较是否确实为原值。我觉得肯定会是原值啊,不然堆栈没有正确释放会影响下一个函数执行。但如果和原值不同,将跳到另一个地方去执行,那里的代码调用了IsDebuggerPresent,不过返回值不重要,只要跳过去,最终调用了TerminateProcess. 能帮忙解释下这样做的用途吗?

小弟刚接触这方面半年,盼有朋友指点一二,谢谢!!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
帮帮忙啊朋友们,鼓励下新人啊
2007-1-16 19:59
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
3
Delphi的  编译结构不熟悉。
2007-1-16 21:26
0
雪    币: 222
活跃值: (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
栈上分配大内存用。因为栈可增长,在初始的时候,OS为应用程序分配一个或多个4K大的页,并将邻接栈尾的内存页设置为警告属性。当应用程序访问到这块内存的时候,缺页中断发生,OS根据页表中的描述符判断此页为警告页,然后提交物理内存使其成为可用页,并继续将邻接栈尾的下一页设置为警告属性,以此达到栈自动增长的目的。如果应用程序访问的地址超出了这个警告页的范围,就会发生真正的无效页访问异常,所以在分配大内存的时候,会以test [mem],reg的方式激活每一页的内存。
2007-1-16 22:32
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
多谢楼上大侠,明白!!!

不过还请大侠帮忙看看第2个问题吧,为啥要将esp与g_StackKey1异或,结果在函数末尾再次与esp异或并与g_StackKey1比较呢?
2007-1-16 23:25
0
游客
登录 | 注册 方可回帖
返回