-
-
对导入表结构的学习心得
-
发表于:
2005-2-13 18:43
7364
-
对导入表结构的学习心得
by mirrormask
2005.2.13
学习逆向一个月,这两天才刚刚接触pe结构,对导入表的各个字段和结构之间的关系一头雾水。于是做了一些试验,有了几点想法,也不知道对不对,污高手耳目了,请指点:)
文中涉及的字段和结构:
INT:IMPORT NAME TABLE
IAT: IMPORT ADDRESS TABLE 两个指针数组
OriginalFirstThunk 、 FirstThunk是IMAGE_IMPORT_DESCRIPTION结构的两个指针
DATADIRETORY中的第13项IMAGE_DIRETORY_ENTRY_IAT结构
我对masm编译生成的一个exe文件进行了静态修改,改变上面提到的字段或结构的内容,看看在pe文件装载时它们之间的关系是怎样的.
如果pe文件调用了dll文件中的函数,在程序编译时,编译器(只用过masm32 8.0)确定好OriginalFirstThunk指向的INT和FirstThunk指向的IAT的内容。同时在执行代码尾部形成形式如jump dword ptr ds:[********]的一系列指令,********显示的是在编译时确定的相应的IAT数组成员的地址,[********]是IAT数组成员的内容--映射到内存中的dll文件的函数地址(函数入口地址).
1、只修改FirstThunk:
在pe装载到内存时的初始阶段,系统搜索遍历INT指向的IMAGE_THUNK_DATA结构,确定每一个函数在内存映射空间中的位置(函数入口地址),然后系统根据FirstThunk指向的地址,把该地址向下的每一位置依次填写搜索到的函数入口地址--只要该段的属性是可写的。如果该位置的段属性是不可写,则发生访问违反(ollydbg),windows提示内存初始化失败。这时用od打开修改后的FirstThunk指向的地址,会发现该部分内存已被函数入口地址覆盖。
同时,如果OriginalFirstThunk 和INT正确(没有修改),系统在装入时可以解析函数的名称(该名称是INT指向的IMAGE_THUNK_DATA结构中的编译时填入的函数名称(IMAGE_IMORT_BY_NAME结构内容),而不是函数真实调用的dll文件中的函数名称。ollydbg的注释栏可‘正确’显示函数名,反汇编栏则只显示调用地址)。
此时程序仍然按照编译时确定的IAT数组内容调用函数,可惜搜索到的函数入口地址没有填入该位置,该位置的内容仍然是一个个的IMAGE_IMORT_BY_NAME结构地址,程序无法正常运行.
2、只修改DATADIRETORY中的第13项IMAGE_DIRETORY_ENTRY_IAT
在加载pe文件时,系统首先根据DATADIRETORY中的第13项IMAGE_DIRETORY_ENTRY_IAT中的地址内容(VirtualAddress)改变该地址所在段(SECTION)的属性-----不论该段属性(IMAGE_SECTION_HEADER结构的CHARACTERISTICTICs指定)是否可写,在加载阶段,搜索到的函数入口地址均可写入该段(初始化IAT数组)。
VirtualAddress的值除了影响该地址所在段在初始化IAT数组时的属性外,不会给程序加载和运行造成任何影响。但是该值必须落在pe文件本身的某一段内(从0000 0000――文件结尾的RVA),对于超出此范围的地址所在的内存空间,程序没有权限改变属性。
isize的值可以变化(改变后程序仍然运行正常),但可以变化的范围不明:(
3、只修改IAT的内容
IAT数组在程序装载到内存后动态更新,只要不破坏数组结构,静态修改数组内容不会影响程序运行
当空IAT出现在FirstThunk指向的地址时(该dword==null),该位置及其以下的IAT数组不会被函数入口地址填充。
4、其他
对 DATADIRETORY中IMAGE_DIRETORY_ENTRY_IMPORT的VirtualAddress的任何修改都会导致程序错误--因为找不到导入表。
对OriginalFirstThunk、INT数组成员、IMAGE_IMORT_BY_NAME的任何修改都会导致程序错误。
我只是凭兴趣学习,没有这方面的理论修养,有说错话用错字的地方还请各位指点:)写了一下午,晕了
感谢看雪学院和罗云彬两部大作的引我入门。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课