手动修复输入表时的发现---对于IID输入表和IAT和INT对应关系及程序载入DLL
2013-03-11 16:25
399 查看
IMAGE_IMPORT_DESCRIPTOR struct
union {
DWORD OriginalFirstThunk; 4Byte
};
TimeDateStamp DWORD ;04h 4Byte
ForwarderChain DWORD ;08h 4Byte
Name DWORD ;0Ch; 4Byte
FirstThunk DWORD ;10h; 4Byte
IMAGE_IMPORT_DESCRIPTOR ends
以上是输入表结构,5个部分,由这5个部分引出导入地址表(IAT)和导入名称表(INT)。。。。
首先明白函数名和DLL名的在程序中的排列:
WORD String
HINT号 函数名
……
……
模块名1
HINT号 函数名
……
……
模块名2
……
//---------------------------------------------------------------------------
也就是说2个字节代表HINT号,后面紧跟的就是函数名,函数名以0x00结尾。在所有函数都罗列完毕后,紧跟的就是这些函数所在的模块名。然后又是函数名,又是模块名……
第一个IID成员:OriginalFirstThunk,是一个RVA,以例子形式表现,假如OriginalFirstThunk存放的是地址1111,我去地址1111处看一下是什么;
地址1111:地址2222,也就是说在地址1111里面放的是地址2222,那再去地址2222里面看看放的是什么;
地址2222:0001 GetModuleHandleA,也就是说地址2222中放和是Hint和函数名称字符串,这个Hint是指函数在某DLL中和次序;值得说明的是这个函数是某个DLL中导入本程序的第一个函数,其他是**** 函数名2 。。。。一直到DLL名字字符串结束,这时从这个DLL中导入程序的函数就完全了; 其他DLL的函数导入也是这样。
第二个IID成员和第三个IID成员一般用不上,为00000000(DWORD)。
第四个IID成员:Name,是一个RVA,Name中存放的是地址3333,那去看一下地址3333中存放的内容,
地址3333:kernel32.DLL,显然是一个DLL名字符串,,和第一个成员解释中对应
第五个IID成员:FirstThunk ,是一个RVA,FirstThunk 中存放的是地址有两种情况,1111(和OriginalFirstThunk中相同)或者4444,出现第一种情况是标准程序中见到的,这是Windows导入函数的一种方式,出现第二种情况是在脱壳程序中看到,我讨论4444这种情况,看一下地址4444中的内容,
地址4444:BD 2F 81 7C,倒过来看就是一个函数地址。。。这是另一种导入库函数的方式,当第一种方式失效时就用第二种方式。
切入正题。。。。。。。。。。。
手动修复输入表时,我把得到 的API地址单独放置在6E50处,这些API地址有在kernel32.DLL中的,还有Shell32.DLL中的,有user32.DLL等各种不确定DLL中的,反正不是 一个DLL中的,都说在IAT中不同的DLL中的函数地址要放在一起,问题是这种说法对吗?我得到的结论是否定这种说法。。。
只要DLL中有一个函数导入了,DLL中其他函数地址也能被程序找到就OK了,正是如此的!
手动修复过程中遇到初始化失败问题,最后出现了,一个是IAT地址和大小没有写,另一个是OriginalFirstThunk中的值写的不对,假如OriginalFirstThunk中的值是地址5555,那么地址5555处的数据是地址6666,那么地址6666处的数据一定要是0才行,如果不是0会有两种错误出现:
第一种,6666没有超过程序的最大偏移,并且地址6666里的数据为该DLL中的一个函数名比如user32中的MessageBoxA(相应6666处为 00 00(不能少了序号) MessageBoxA),不会提示错误,
第二种,如果地址6666处是另一个DLL中的函数名或者其他数据,会显示如下错误
![](http://img.my.csdn.net/uploads/201211/07/1352219971_4400.png)
第三种,如果地址5555(OriginalFirstThunk)处的数据不是6666,而是一个很大的地址,比如00900000,900000这个地址超过程序的范围了,会出现如下错误
![](http://img.my.csdn.net/uploads/201211/07/1352220382_4891.png)
结论,总共两点:
第一点,OriginalFirstThunk的内容问题
第二点,DLL导入和API调用问题
union {
DWORD OriginalFirstThunk; 4Byte
};
TimeDateStamp DWORD ;04h 4Byte
ForwarderChain DWORD ;08h 4Byte
Name DWORD ;0Ch; 4Byte
FirstThunk DWORD ;10h; 4Byte
IMAGE_IMPORT_DESCRIPTOR ends
以上是输入表结构,5个部分,由这5个部分引出导入地址表(IAT)和导入名称表(INT)。。。。
首先明白函数名和DLL名的在程序中的排列:
WORD String
HINT号 函数名
……
……
模块名1
HINT号 函数名
……
……
模块名2
……
//---------------------------------------------------------------------------
也就是说2个字节代表HINT号,后面紧跟的就是函数名,函数名以0x00结尾。在所有函数都罗列完毕后,紧跟的就是这些函数所在的模块名。然后又是函数名,又是模块名……
第一个IID成员:OriginalFirstThunk,是一个RVA,以例子形式表现,假如OriginalFirstThunk存放的是地址1111,我去地址1111处看一下是什么;
地址1111:地址2222,也就是说在地址1111里面放的是地址2222,那再去地址2222里面看看放的是什么;
地址2222:0001 GetModuleHandleA,也就是说地址2222中放和是Hint和函数名称字符串,这个Hint是指函数在某DLL中和次序;值得说明的是这个函数是某个DLL中导入本程序的第一个函数,其他是**** 函数名2 。。。。一直到DLL名字字符串结束,这时从这个DLL中导入程序的函数就完全了; 其他DLL的函数导入也是这样。
第二个IID成员和第三个IID成员一般用不上,为00000000(DWORD)。
第四个IID成员:Name,是一个RVA,Name中存放的是地址3333,那去看一下地址3333中存放的内容,
地址3333:kernel32.DLL,显然是一个DLL名字符串,,和第一个成员解释中对应
第五个IID成员:FirstThunk ,是一个RVA,FirstThunk 中存放的是地址有两种情况,1111(和OriginalFirstThunk中相同)或者4444,出现第一种情况是标准程序中见到的,这是Windows导入函数的一种方式,出现第二种情况是在脱壳程序中看到,我讨论4444这种情况,看一下地址4444中的内容,
地址4444:BD 2F 81 7C,倒过来看就是一个函数地址。。。这是另一种导入库函数的方式,当第一种方式失效时就用第二种方式。
切入正题。。。。。。。。。。。
手动修复输入表时,我把得到 的API地址单独放置在6E50处,这些API地址有在kernel32.DLL中的,还有Shell32.DLL中的,有user32.DLL等各种不确定DLL中的,反正不是 一个DLL中的,都说在IAT中不同的DLL中的函数地址要放在一起,问题是这种说法对吗?我得到的结论是否定这种说法。。。
只要DLL中有一个函数导入了,DLL中其他函数地址也能被程序找到就OK了,正是如此的!
手动修复过程中遇到初始化失败问题,最后出现了,一个是IAT地址和大小没有写,另一个是OriginalFirstThunk中的值写的不对,假如OriginalFirstThunk中的值是地址5555,那么地址5555处的数据是地址6666,那么地址6666处的数据一定要是0才行,如果不是0会有两种错误出现:
第一种,6666没有超过程序的最大偏移,并且地址6666里的数据为该DLL中的一个函数名比如user32中的MessageBoxA(相应6666处为 00 00(不能少了序号) MessageBoxA),不会提示错误,
第二种,如果地址6666处是另一个DLL中的函数名或者其他数据,会显示如下错误
![](http://img.my.csdn.net/uploads/201211/07/1352219971_4400.png)
第三种,如果地址5555(OriginalFirstThunk)处的数据不是6666,而是一个很大的地址,比如00900000,900000这个地址超过程序的范围了,会出现如下错误
![](http://img.my.csdn.net/uploads/201211/07/1352220382_4891.png)
结论,总共两点:
第一点,OriginalFirstThunk的内容问题
第二点,DLL导入和API调用问题
相关文章推荐
- 手动修复输入表时的发现---对于IID输入表和IAT和INT对应关系及程序载入DLL
- 菜鸟脱壳之脱壳的基础知识(六)——手动查找IAT和修复Dump的程序
- 以人为本的机器学习:谷歌人工智能产品设计概述 By 机器之心2017年7月17日 12:13 取代了手动编程,机器学习(ML)是一种帮助计算机发现数据中的模式和关系的科学。对于创建个人的和动态的经历
- 无法定位程序输入点 _except_handler4_common 于动态链接库 msvcrt.dll 上
- Context3D类的setVertexBufferAt方法(指定与单个着色器程序输入相对应的顶点数据组件)
- 如运行程序提示:“没有找到libmysql.dll,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。
- 手动修复鼠标单击变双击和对于国产鼠标的看法
- 8、编写一个程序,它先将键盘上输入的一个字符串转换成十进制整数, 然后打印出这个十进制整数对应的二进制形式。
- 无法定位程序输入点 _except_handler4_common 于动态链接库 msvcrt.dll 上。
- 从键盘输入10个学生的姓名和成绩,按字典序排列学生的姓名并输出(姓名和成绩对应关系保持不变)
- 无法定位程序输入点到_ftol2于动态链接库msvcrt.dll的错误的解决
- input 使用js赋值而非手动输入input,并执行input事件对应函数
- C#程序中从数据库取数据时需注意数据类型之间的对应,int16\int32\int64
- 第19课时,实践1,编写一个程序,从键盘上输入一个小写字母,显示这个小写字母及它所对应的大写字母以及它们的ASCII码值
- 人民币金额大写 在与财务相关的应用中,经常会用到人民币金额的大写,比如发票的打印程序。 本题的任务是:从键盘输入一个十亿以内的正整数(int类型),把它转换为人民币金额大写(不考虑用户输入错误
- 无法定位程序输入点_except_handler4_common于动态链接库msvcrt.dll上
- 关于“无法定位程序输入点getaddrinfo于动态链接库WS32_32.dll上”的问题
- 解决 WinXP下 libcurl.dll 无法定位程序输入点GetTickCount64问题
- Win7如何手动注册DLL文件以解决程序不能使用的问题
- 手动插int 3实现程序主动断点