1.介绍

本文主要简单介绍在没有代码的情况下,如何从一个动态链接库中获取某个函数的址.主要实现方式为Signature Scanning(特征码扫描)

2.什么是Signature Scanning(特征码扫描)

我就简单解释一下,其实就是从一个二进制文件的开始位置扫描,一直到文件的末尾的这样一项工作,当扫到某一段与我们所需要的符合时,

那么就说明查找到目标的地址.(感觉说得不够好,这里大家自己补补吧^^.https://wiki.alliedmods.net/Signature_Scanning#What_is_Sigscanning.3F,

当然有C++底的,应该可以通过我下面的代码就能理解了哈^^)

3.准备工作

1).通过逆向工具,这里我推荐IDA哈,如果你有其它工具能得到特征码,那也行.至于IDA自己想办法哈,这里我就不提供了

2).查看此文章以了解如何获取特征码.

3).所需要的二进制文件,与特征码

4.正式开始

1.获取某二进制文件的基地址与大小,可能通过以下函数获得

 1 DWORD MH_GetModuleBase(HMODULE hModule) //获取二进制文件的基地址
2 {
3 MEMORY_BASIC_INFORMATION mem;
4
5 if (!VirtualQuery(hModule, &mem, sizeof(MEMORY_BASIC_INFORMATION)))
6 return 0;
7
8 return (DWORD)mem.AllocationBase;
9 }
10
11 DWORD MH_GetModuleSize(HMODULE hModule) //获取二进制文件的大小
12 {
13 return ((IMAGE_NT_HEADERS *)((DWORD)hModule + ((IMAGE_DOS_HEADER *)hModule)->e_lfanew))->OptionalHeader.SizeOfImage;
14 }

2.然后就能过以下函数在加载该进制文件后进行扫描

 1 void *MH_SearchPattern(void *pStartSearch, DWORD dwSearchLen, char *pPattern, DWORD dwPatternLen)
2 {
3 DWORD dwStartAddr = (DWORD)pStartSearch;
4 DWORD dwEndAddr = dwStartAddr + dwSearchLen - dwPatternLen;
5
6 while (dwStartAddr < dwEndAddr) //这里从文件的开始位置扫描,如果没有找到指定特征码的位置的话,就会跳出循环并结束扫描工作;否则会返回所查到的址
7 {
8 bool found = true;
9
10 for (DWORD i = 0; i < dwPatternLen; i++)
11 {
12 char code = *(char *)(dwStartAddr + i);
13 //0x2A为跳转码的转换,比如当某一部分为 E8 AB CD 2E 76 call sub_xxxxxxxx时,
14 //那么此时除了E8之外,其它的应该更换为2A
15 if (pPattern[i] != 0x2A && pPattern[i] != code)
16 {
17 found = false;
18 break;
19 }
20 }
21
22 if (found)
23 return (void *)dwStartAddr;
24
25 dwStartAddr++;
26 }
27
28 return 0;
29 }

如果扫描成功,会返回该特征码存在的地址否则返回空

5.这样做有什么用?

对于函数挂勾有非常大的作用,可能通过Inline Hook直接勾函数,接下来要干什么就自己做吧^^,欢迎吐

补充大概用法:
 1 #define SIG_FUNC "\x55\x8B\xEC\x53\x56\x8B\xF1\x57\x8B\x4E\x2A\xE8\x2A\x2A\x2A\x2A\x56\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x6A"
2
3
4 void *g_pOrigin = NULL;
5 HMODULE g_hModule = NULL;
6 DWORD g_dwBase, g_dwSize;
7
8 g_hModule = LoadLibrary("my.dll");
9 g_dwBase = MH_GetModuleBase(g_hModule);
10 g_dwSize = MH_GetModuleSize(g_hModule);
11 g_pOrigin = MH_SearchPattern(g_dwBase, g_dwSize, SIG_FUNC, sizeof(SIG_FUNC) - 1);
12
13 正常情况下,g_pOrigin返回就是特征所指向的函数地址了^^

随机推荐

  1. webpack做项目优化

    webpack优化 -- compression-webpack-plugin 开启gzip 打包的时候开启gzip可以大大减少体积,非常适合于上线部署.下面以vue-cli2.x项目为例,介绍如何在 ...

  2. 为什么要做一款ERP软件——开源软件诞生7

    技术之外的探讨--第7篇 用日志记录“开源软件”的诞生 赤龙ERP开源地址: 点亮星标,感谢支持,与开发者交流 kzca2000 码云:https://gitee.com/redragon/redra ...

  3. PHP + Redis 生成自定义订单编号

    /** * 订单编号生成规则 * 14位 = 6位时间 + 5位自增 + 3位ID * @param string $prefix 前缀: 默认为order * @param int $userId ...

  4. nodejs解压版安装和配置(带有搭建前端项目脚手架)

    nodejs 安装  我先前用了nvm,觉得nvm挺厉害可以随时更换nodejs版本,但是研究了下,可能自己功力不够还是什么,并不好用,中间还出现了错误:所以最后还是卸载了: 本文图文并茂的一步一步的 ...

  5. Java-Collection和Map

    创建博客的目的主要帮助自己记忆和复习日常学到和用到的知识:或有纰漏请大家斧正,非常感谢! 之前面试,被问过一个问题:List和Set的区别. 主要区别很明显了,两者都是数组形式存在的,继承了Colle ...

  6. [程序员代码面试指南]链表问题-将单链表的每k个节点之间逆序

    题目描述 给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点. 题解 内部函数reverse实现链表beg到end的翻转 ...

  7. C#开发PACS医学影像处理系统(十六):2D处理之影像平移和缩放

    1.平移,利用WPF中控件边距来控制位移: /// <summary> /// 平移图像 /// </summary> /// <param name="X&q ...

  8. Spring 标签纸property

    转载自https://www.cnblogs.com/zzb-yp/p/9968849.html Spring中XML文件配置Bean的简单示例,如下: <bean id="car&q ...

  9. Java 里的 for (;;) 与 while (true),哪个更快?

    在 JDK8u 的 jdk 项目下做个很粗略的搜索: mymbp:/Users/me/workspace/jdk8u/jdk/src$ egrep -nr "for \\(\\s?;\\s? ...

  10. 工作10年后,再看String s = new String("xyz") 创建了几个对象?

    这个问题相信每个学习java的同学都不陌生,作为一个经典的面试题,到现在工作这么多年了我真是认为挺操蛋的一个问题,在网上到现在你仍然可以看见很多讨论这个问题的人,其中不乏工作很多年的人都有争论,我认为 ...