Menooker / PFishHook

An x64 inline hook library
Apache License 2.0
30 stars 10 forks source link

Update AllocFunc,use fixed mmap ranges. #4

Closed ghost closed 5 years ago

ghost commented 5 years ago

1

Menooker commented 5 years ago

很好的改进!我有几个建议:

ghost commented 5 years ago

可以把512MB改小,直接MAP_32BIT可能会导致比预期更小的堆。例如这个内存布局 |ELF||HEAP||for HEAP||mmap(MAP_32BIT)| 指定MAP_32BIT且地址重叠 似乎会默认映射到0x40000000 但是这样,会导致,原本留给heap扩展的空间被占用了。现在是找到一块最朝后的内存,并且满足内存里面所有地址和ELF最前地址的diff小于2G

ghost commented 5 years ago

根据原来代码的逻辑,似乎mmap给的addr有两种情况,一种是NULL,一种是一个已经被映射过的地址。然后通过pull #2 他会在ELF前端分配(64bit)。然后32bit因为制定了MAP_32BIT所以是到一个固定的地址去mmap。实质上,和这个pr所做的是一样的

ghost commented 5 years ago

看起来,只要制定了addr,这个addr都会重叠,然后linux会瞎搞,映射到一个固定的很远的地址(64bit下),然后总会触发fallback机制在ELF映射地址之前分配

Menooker commented 5 years ago

map_32bit的话hint直接给null,这样让操作系统决定位置,也许可以给一个优化一点的位置……主要想用map_32bit是因为逻辑可以比较简化,而且保证mmap出来的地址真的是低32位的,貌似你的低32位逻辑不能确保mmap到这个地址吧?也许系统会瞎搞到高位地址?

Menooker commented 5 years ago

我的想法是先用你的两块区域,不行的话fallback到用给定的addr做mmap,文档里好像是说会分配到hint附近的地址,实际上如果还是不行再失败,这样可以patch到JIT的代码。我觉得hint被忽略是特殊情况,不一定都会瞎搞

用给定addr做hint的话需要原有的memchunk逻辑

Menooker commented 5 years ago

这样对于大部分情况,使用你的新的分配逻辑,直接在两块大区域分配内存(效率比较高)。对于少部分情况,如果这两块区域都不行,那么再去尝试使用mmap + hint分配空间(memchunk逻辑),多余的空间需要扔到memchunk链表里。memchunk逻辑失败就返回失败(不会再去尝试分配ELF附近的空间)。如果你觉得这个方案可以我就merge了?我来改也行。

ghost commented 5 years ago

可以

Menooker commented 5 years ago

已merge,基于你的我再改进了一下,commit