飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3838|回复: 3

[转贴] 3个脱壳相关的重要函数介绍

[复制链接]
  • TA的每日心情
    开心
    2024-4-30 21:58
  • 签到天数: 75 天

    [LV.6]常住居民II

    发表于 2006-10-10 21:46:47 | 显示全部楼层 |阅读模式
    3个脱壳相关的重要函数介绍   

    -------------------------------------------------------------------------
    脱壳相关的重要函数介绍
    【QduWg】翻译

    声明:本人翻译此类文章,原来是为了自己阅读方便,想到其他人可能也需要,不过

    E文可能比较难理解,故本人贴出来供各位菜鸟学习吧。错误之处请指出。祝学习进

    步!^_*

    1.GetModuleHandle函数
    如果文件已经被映射进了调用进程的地址空间,则此函数返回指定模块的句柄,

    HMODULE GetModuleHandle(
      LPCTSTR lpModuleName   // 需要返回句柄的模块名的地址
    );

    参数:
    lpModuleName 指向一个包含模块名字的以0结尾的串(或者是a .DLL或者.EXE文件).

    如果函数扩展名省略掉,默认为库文件扩展名.DLL。文件名串可以尾部可以是一个点

    (.),指明模块没有扩展名。该串不必指定路径。当指定路径时务必用反斜杠(\), 而

    不是正斜杠(/). 名字与映射进进程地址空间的模块比较。如果此参数为空NULL,

    GetModuleHandle 返回创建调用进程的文件句柄。

    返回值:
    如果函数成功调用,返回值是指定模块的句柄。如果函数失败,返回NULL.要得到更

    进一步的错误信息,调用GetLastError函数。

    备注:
    返回的句柄不是全局的,可继承的或者可复制的,它不可以被另外的进程使用。

    由GetModuleHandle和LoadLibrary返回的句柄可以在同一个函数内使用(例如

    GetProcAddress, FreeLibrary, 或者LoadResource)吗?两个函数之间的区别在于

    引用次数(reference count)。LoadLibrary把模块映射进调用进程的地址空间内,

    映射进地址空间后,如果必要,则增加模块的引用次数。 然而GetModuleHandle却是

    在不增加引用次数的情况下返回已映射模块的句柄。

    注意:引用次数被FreeLibrary 用来决定是否把一个函数从进程地址空间释放掉。由

    于这个原因,当把由GetModuleHandle返回的句柄用于FreeLibrary时,必须小心,因

    为如此以来可能导致一个DLL模块被提前释放掉。

    在多线程应用里,要小心使用这个函数。因为在一个函数返回句柄和另一个函数使用

    句柄期间,无法保证模块句柄保持有效。比如一个线程可能通过GetModuleHandle提

    取模块句柄。在线程于某个函数内使用句柄之前,第二个线程可能释放了句柄,系统

    可能加载了另一个模块,而且给它赋予和刚释放的模块相同的句柄值。 第一个线程

    则被留下一个引用了不同模块的句柄,此模块并非它想要的那个模块。


    2. GetProcAddress函数

    GetProcAddress函数返回指定的输出动态链接库内的函数地址。

    FARPROC GetProcAddress(
      HMODULE hModule,    // DLL模块句柄
      LPCSTR lpProcName   // 函数名
    );

    参数:
    (1)hModule
    Handle是包含函数的DLL模块的句柄。该句柄由LoadLibrary或GetModuleHandle返回


    (2)lpProcName
    指向以0结尾的函数名字符串,或者指定函数的序号值。如果参数是序号值,必须出

    现在低字部分,高字部分置0。
    返回值:
    如果函数成功,返回DLL输出函数的地址。如果失败,返回NULL.得到更多错误信息,

    使用GetLastError函数.

    备注:
    GetProcAddress函数用来提取在DLL内的输出函数的地址。由lpProcName指向的函数

    名的拼写和大小写必须与DLL模块定义文件(.DEF) 的EXPORTS声明的函数一致。Win32

    API函数的输出名也许与你代码内调用的函数名不一样。这些差异被SDK 头文件内使

    用的宏隐藏起来了。

    lpProcName参数可以通过指定一个函数序号(在输出声明中关联到一个函数上)来表

    明一个DLL函数。GetProcAddress校验指定的序号是否在.DEF 文件声明的从1和最高

    序号值之间。 然后函数使用序号作为索引从一个函数表内读取函数地址。如果.DEF

    文件没有对函数连续从1到N编号的话,错误产生了,该函数返回一个无效的非0地址

    ,即使没有函数使用指定的序号。在函数不操作的情况下,函数必须以名字指出而非

    序号。

    3.LoadLibrary函数

    LoadLibrary函数把指定的可执行模块映射进调用进程的地址空间。

    HINSTANCE LoadLibrary(
      LPCTSTR lpLibFileName   //可执行模块的文件名
    );

    参数:
    lpLibFileName 是指向以0结尾的字符串命名的可执行模块。如a .DLL或.EXE。指定

    的名字是模块的文件名,与保存在库模块文件的由.DEF文件内的LIBRARY关键字指定

    的名字无关。
    如果文件不在指定的目录上,函数失败。当指定路径时,必须使用反斜杠(\),而非正

    斜杠(/).
    如果没有指定路径,函数就使用标准搜索策略寻找函数。
    返回值:
    如果函数成功,返回值为模块句柄。如果函数失败,则返回NULL.得到更多错误信息

    ,使用GetLastError函数.

    备注:
    LoadLibrary可以用来把DLL模块映射进内存并返回一个可以被GetProcAddress函数使

    用的句柄,以得到DLL函数的地址。LoadLibrary 也可用来映射其他可执行模块,例

    如可以得到一个.EXE文件句柄,该句柄用于FindResource或者LoadResource函数.不

    要使用 LoadLibrary 来“运行”一个.EXE文件。

    如果模块是一个没有映射进调用进程内存空间的DLL,系统用DLL_PROCESS_ATTACH来

    调用DLL的DllMain函数。如果DLL的入口点函数没有返回TRUE, LoadLibrary失败并返

    回NULL. 从 DllMain调用LoadLibrary是不安全的。
    模块句柄不是全局的和可继承的。一个进程对LoadLibrary的调用可以产生被另一个

    进程使用的句柄吗?不可以。另外一个进程在调用GetProcAddress之前,必须调用自

    己的LoadLibrary得到句柄。

    如果在lpLibFileName指定的字符串内没有扩展名,则把默认的库扩展名DLL追加上。

    文件名串可以用点(.)结尾,指明该模块没有扩展名。当没有路径指定时,该函数搜

    索已调入模块,而且其主名与即将调入的模块主名匹配。如果名字匹配,加载成功,

    否则,函数按照如下顺序搜索。
    ⑴应用程序加载的目录;
    ⑵当前目录;
    ⑶Windows 95 and Windows 98系统目录,用GetSystemDirectory函数得到目录路径


    ⑷Windows NT系统目录,用GetSystemDirectory函数得到目录路径,目录名为

    SYSTEM32;
    Windows NT: 16位系统目录,没有函数得到该目录。但它被搜索,目录名是SYSTEM.
    Windows目录:该目录是在环境变量内用PATH列出的目录。被搜索的第一个目录是含

    有用于创建调用进程的映象文件的目录。这样做允许私有DLL文件与已经发现的进程

    关联,而不必添加进程的已安装目录到环境变量的PAHT里。

    Visual C++ 编译器提供允许声明线程局部变量的语法:_declspec(thread).如果在

    DLL内使用这个语法,你将不能够显式地用LoadLibrary或者LoadLibraryEx函数了.如

    果你的DLL显式地加载,你必须使用线程局部存储函数,而非_declspec(thread).

    Windows 95: 如果用LoadLibrary加载一个包含ID大于0x7FFF资源的模块将失败。
    Windows CE: 两个不同的模块不能够使用相同文件名。例如,试图用LoadLibrary加

    载"Sample.cpl", 操作系统不会加载Sample.cpl, 而是加载的Sample.dll.一个类似

    的限制存在于使用相同名字但位于不同目录的情况,如:LoadLibrary加载

    "\\Windows\Sample.dll",LoadLibrary 加载"\\MyDir\Sample.dll",

    "\\Windows\Sample.dll" 将被重新加载

    可执行模块的搜索路径不可以指定,除非给出模块的完全路径。


    另外参考:

    Dynamic-Link Libraries Overview, Dynamic-Link Library Functions,

    DllMain,FindResource, FreeLibrary,

    GetProcAddress,GetSystemDirectory,GetWindowsDirectory,

    LoadLibraryEx,LoadResource
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    7 小时前
  • 签到天数: 2106 天

    [LV.Master]伴坛终老

    发表于 2006-10-11 08:51:06 | 显示全部楼层
    谢谢分享,支持一下楼主,学习了
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2023-10-22 12:29
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2006-10-11 09:13:19 | 显示全部楼层
    多谢LZ
    俺下来打印了看
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2006-10-22 15:59:55 | 显示全部楼层
    先收藏了 看不懂..支持一下
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表