Signature Scanning(中文暂时译为"特征码扫描")是在C++(起码我是用C++^^)开发中很好的一种方式
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返回就是特征所指向的函数地址了^^
随机推荐
- Python 利用三个简易模块熟悉前后端交互流程
准备工作 在学习Django之前,先动手撸一个简单的WEB框架来熟悉一下前后端交互的整体流程 本次用到的模块: 1.wsgiref,这是一个Python自带的模块,用于构建路由与视图 2.pymysq ...
- 部署一套完整的Kubernetes高可用集群(二进制,最新版v1.18)下
七.高可用架构(扩容多Master架构) Kubernetes作为容器集群系统,通过健康检查+重启策略实现了Pod故障自我修复能力,通过调度算法实现将Pod分布式部署,并保持预期副本数,根据Node失 ...
- ckeditor4.0以上使用行间距插件lineheight报错修改
①从百度上下载一个 ckeditor 行距包,解压放到ckeditor/plugins目录下. ②在config.js 中添加 config.extraPlugins += (config.extra ...
- 一起来读官方文档-----SpringIOC(03)
1.4.依存关系 典型的企业应用程序不坑你只包含单个对象或单个bean.即使是最简单的应用程序,也有一些对象可以协同工作,以呈现最终用户视为一致的应用程序.下一部分将说明如何从定义多个独立的Bean定 ...
- ParticleSystem的小优化
最近游戏场景希望加入一些ParticleSystem来丰富场景,这样肯定会带来一定的性能开销.一般来说ParticleSystem的优化就是尽量减少粒子数,尽量不使用粒子碰撞等.而今天要说的是,多个P ...
- pytest测试框架 -- assert断言和fixture固件
一.断言 (1)使用assert语句进行断言 # test_run.py @pytest.mark.assert def test_assert(self): r = requests.get(&qu ...
- 你想了解的分布式文件系统HDFS,看这一篇就够了
1.分布式文件系统 计算机集群结构 分布式文件系统把文件分布存储到多个节点(计算机)上,成千上万的计算机节点构成计算机集群. 分布式文件系统使用的计算机集群,其配置都是由普通硬件构成的,与用多个处理器 ...
- 算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法
强连通分量分解的Kosaraju算法 今天是算法数据结构专题的第35篇文章,我们来聊聊图论当中的强连通分量分解的Tarjan算法. Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起 ...
- windows操作系统的电脑越用越卡?简说几种原因和解决方法。
很多人在使用windows操作系统的发现电脑越用越卡,但是不知道什么原因,只知道电脑越便宜的越卡(电脑配置低), 然而导致电脑卡顿缓慢的原因有很多,总结出来就是软件和硬件的问题,那怎么办呢? 电脑系统 ...
- Docker跨主机通信(九)
容器网络 在前面的博客中已经详细讲解了几种网络方案: none, host, bridge,user-defined.但是他们只是解决了单个主机间的容器的通信问题,并不能实现多个主机容器之间的通信.本 ...