●●●●●罗云彬那本书中部分代码不懂,请高手指点,谢谢先●●●

etracer 2009-09-09 07:16:29
书上说:“
文件中的_GetKernelBase子程序的参数是主程序从堆栈中得到的返回地址,程序首先设置一个SEH异常处理子程序,以免在搜寻内存的过程中访问到无效的页面后出错;接下来将参数中传递过来的目标地址按页对齐(与0ffff0000h进行and操作);然后以每次一个页的间隔在内存中寻找DOS MZ文件头标识和PE文件头标识,如果找到的话,表示这个页的起始地址就是Kernel32.dll模块的基址。”

问题1 :那么我可不可以这么理解,PE文件头标识对应的位置就是Kernel32.dll模块的基址呢?

问题2,下面代码中的红色①②③④⑤数值都是什么意思,该行代码是什么意思?
----------------------------
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 在内存中扫描 Kernel32.dll 的基址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetKernelBase proc _dwKernelRet
local @dwReturn

pushad
mov @dwReturn,0
;********************************************************************
; 重定位
;********************************************************************
call @F
@@:
pop ebx
sub ebx,offset @B
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
assume fs:nothing
push ebp
lea eax,[ebx + offset _PageError]
push eax
lea eax,[ebx + offset _SEHHandler]
push eax
push fs:[0]
mov fs:[0],esp
;********************************************************************
; 查找 Kernel32.dll 的基地址
;********************************************************************
mov edi,_dwKernelRet
and edi,①0ffff0000h
.while TRUE
.if word ptr [edi] == IMAGE_DOS_SIGNATURE
mov esi,edi
add esi,②[esi+003ch]
.if word ptr [esi] == IMAGE_NT_SIGNATURE
mov @dwReturn,edi
.break
.endif
.endif
_PageError:
sub edi,③010000h
.break .if edi <④ 070000000h
.endw
pop fs:[0]
add esp,⑤0ch
popad
mov eax,@dwReturn
ret

_GetKernelBase endp
...全文
94 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
etracer 2009-09-09
  • 打赏
  • 举报
回复
明白了感谢2位,万分感谢
gzgzlxg 2009-09-09
  • 打赏
  • 举报
回复

and edi,①0ffff0000h ; 按 10000 对齐,因为内核模块加载地址都是按 10000对齐的

add esi,②[esi+003ch] ; IMAGE_DOS_HEADER.e_ifanew 老罗在书中这样的写法实在不敢恭维
比较正规的写法如下:
assume esi: IMAGE_DOS_HEADER
add esi, [esi].e_ifanew
assume esi:nothing

sub edi,③010000h ; 从高往低 10000 的长度搜索,原因如上所述,
; 内核模块加载都是按 10000对齐的
.break .if edi <④ 070000000h ; 70000000h 以下就不是内核模块装载地址了,所以结束

add esp,⑤0ch ; 堆栈平衡,因为前面压了 push ebp, push eax, push eax

各人有各人的书写习惯,不过我不太喜欢这类写法,不过这年头还是少说为妙。
etracer 2009-09-09
  • 打赏
  • 举报
回复
感谢您的解答,明白了,第5个平衡堆栈能说名一下为什么是0ch而不是其他呢?我刚学汇编很多不懂请见量
lmxd70 2009-09-09
  • 打赏
  • 举报
回复
1、准确地说是这样,返回的地址就位于kernel32.dll模块中,而kernel32.dll也是pe文件,所以向上找的时候,只要有mz和pe文件标识符,就一定是kernel32.dll的基址。

2
(1)按基址对齐,也就是按页对齐
(2)找到mz标识头以后,将其+3ch,那么对应的就是pe文件头
(3)这是也可以减1000h,减10000h是为了增加搜索速度。因为加载的pe文件的基址是按xxxx0000的方式对齐的,所以pe文件头一般会出现在这个地址上。
(4)因为dll文件的装载地址都在于70000000h,如果小于70000000h,那么就是没找到。
(5)平衡堆栈

21,499

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧