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. Mybatis联合查询(一)

    Mybatis的简单联合查询操作: 实体类: Employee: package com.test.mybatis; public class Employee { private Integer i ...

  2. 16_Python的包package

    1.包的概述 1.包是将模块一文件夹的组织形式进行分组管理的方法,一系列模块进行分类管理有利于防止命名冲突 2.包是一个包含多个模块的特色目录,目录下有一个特色的文件__init__.py 3.包的命 ...

  3. [01] C#网络编程的最佳实践

    网络框架的选择 C++语言里面有asio和libuv等网络库, 可以方便的进行各种高效编程. 但是C#里面, 情况不太一样, C#自带的网络API有多种. 例如: Socket TcpStream(同 ...

  4. Leetcode 1577 数的平方等于两数乘积的方法数

    Leetcode 1577 数的平方等于两数乘积的方法数 题目 给你两个整数数组 nums1 和 nums2 ,请你返回根据以下规则形成的三元组的数目(类型 1 和类型 2 ): 类型 1:三元组 ( ...

  5. 在Nginx里指定ip_hash的方式解决Tomcat集群session的问题

    据称,Tomcat集群session同步方案有以下几种方式: 1)使用tomcat自带的cluster方式,多个tomcat间自动实时复制session信息,配置起来很简单.但这个方案的效率比较低,在 ...

  6. .NET性能排查

    概述 1,性能参数 2,性能排查方式 3,.NET的性能分析工具 1,性能指标 一个系统的性能排查或者性能设计的前提就是要有明确的性能指标:常见的性能参数 1.响应时间(处理任务时的延迟,简称 RT, ...

  7. Redis必须会的知识点

    Nosql:非关系型数据库 分表分库 + 水平拆分 + mysql集群: 在Memcached的高速缓存,Mysql主从复制.读写分离的基础上,由于MyISAM使用表锁,高并发Mysql应用开始使用I ...

  8. 认证授权:IdentityServer4 - 单点登录

    前言 上一篇文章介绍了IdentityServer4的各种授权模式,本篇继续介绍使用IdentityServer4实现单点登录效果. 单点登录(SSO) SSO( Single Sign-On ),中 ...

  9. tomact在windows系统下安装

    一.下载 下载地址: https://tomcat.apache.org/download-90.cgi 7,8,9的版本都可以下,这里下载最新版本 注意:Binary是编译好的,可以直接使用的版本, ...

  10. 【征文活动】为自己发“声” —— 声网RTC征文大赛在园子里征稿

    2020年8月20日,声网Agora入驻园子的新楼盘--博客园品牌专区.9月,我们与声网Agora再度合作,「为自己发"声"- RTC 征文大赛」在园子里征稿. RTC(Real- ...